diff options
Diffstat (limited to 'src/backend/utils/adt/misc.c')
-rw-r--r-- | src/backend/utils/adt/misc.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c index d4a92d0b3fa..0e6c45807a1 100644 --- a/src/backend/utils/adt/misc.c +++ b/src/backend/utils/adt/misc.c @@ -44,6 +44,7 @@ #include "utils/fmgroids.h" #include "utils/lsyscache.h" #include "utils/ruleutils.h" +#include "utils/syscache.h" #include "utils/timestamp.h" @@ -567,6 +568,50 @@ pg_typeof(PG_FUNCTION_ARGS) /* + * Return the base type of the argument. + * If the given type is a domain, return its base type; + * otherwise return the type's own OID. + * Return NULL if the type OID doesn't exist or points to a + * non-existent base type. + * + * This is a SQL-callable version of getBaseType(). Unlike that function, + * we don't want to fail for a bogus type OID; this is helpful to keep race + * conditions from turning into query failures when scanning the catalogs. + * Hence we need our own implementation. + */ +Datum +pg_basetype(PG_FUNCTION_ARGS) +{ + Oid typid = PG_GETARG_OID(0); + + /* + * We loop to find the bottom base type in a stack of domains. + */ + for (;;) + { + HeapTuple tup; + Form_pg_type typTup; + + tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid)); + if (!HeapTupleIsValid(tup)) + PG_RETURN_NULL(); /* return NULL for bogus OID */ + typTup = (Form_pg_type) GETSTRUCT(tup); + if (typTup->typtype != TYPTYPE_DOMAIN) + { + /* Not a domain, so done */ + ReleaseSysCache(tup); + break; + } + + typid = typTup->typbasetype; + ReleaseSysCache(tup); + } + + PG_RETURN_OID(typid); +} + + +/* * Implementation of the COLLATE FOR expression; returns the collation * of the argument. */ |