diff options
Diffstat (limited to 'src/backend/utils')
-rw-r--r-- | src/backend/utils/adt/format_type.c | 34 | ||||
-rw-r--r-- | src/backend/utils/cache/lsyscache.c | 120 |
2 files changed, 95 insertions, 59 deletions
diff --git a/src/backend/utils/adt/format_type.c b/src/backend/utils/adt/format_type.c index fc8733e960c..c85d7ea0884 100644 --- a/src/backend/utils/adt/format_type.c +++ b/src/backend/utils/adt/format_type.c @@ -8,7 +8,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/format_type.c,v 1.27 2002/03/19 02:18:21 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/format_type.c,v 1.28 2002/03/20 19:44:40 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -123,10 +123,10 @@ format_type_internal(Oid type_oid, int32 typemod, HeapTuple tuple; Oid array_base_type; int16 typlen; + char typtype; bool is_array; char *name; char *buf; - char typtype; if (type_oid == InvalidOid && allow_invalid) return pstrdup("-"); @@ -143,34 +143,16 @@ format_type_internal(Oid type_oid, int32 typemod, type_oid); } + /* + * Check if it's an array (and not a domain --- we don't want to show + * the substructure of a domain type). Fixed-length array types such + * as "name" shouldn't get deconstructed either. + */ array_base_type = ((Form_pg_type) GETSTRUCT(tuple))->typelem; typlen = ((Form_pg_type) GETSTRUCT(tuple))->typlen; typtype = ((Form_pg_type) GETSTRUCT(tuple))->typtype; - /* - * Domains look alot like arrays, so lets process them first, and return - * back to avoid the array and 'standard' formatting procedures that are - * use for base types. - */ - if (typtype == 'd') { - name = NameStr(((Form_pg_type) GETSTRUCT(tuple))->typname); - - /* - * Double-quote the name if it's not a standard identifier. - * Note this is *necessary* for ruleutils.c's use. - */ - if (strspn(name, "abcdefghijklmnopqrstuvwxyz0123456789_") != strlen(name) - || isdigit((unsigned char) name[0])) - buf = psnprintf(strlen(name) + 3, "\"%s\"", name); - else - buf = pstrdup(name); - - ReleaseSysCache(tuple); - - return buf; - } - - if (array_base_type != InvalidOid && typlen < 0) + if (array_base_type != InvalidOid && typlen < 0 && typtype != 'd') { /* Switch our attention to the array element type */ ReleaseSysCache(tuple); diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c index 760e07ce5e6..f4ebb6261c2 100644 --- a/src/backend/utils/cache/lsyscache.c +++ b/src/backend/utils/cache/lsyscache.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.63 2002/03/19 02:18:21 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.64 2002/03/20 19:44:42 tgl Exp $ * * NOTES * Eventually, the index information should go through here, too. @@ -23,7 +23,7 @@ #include "catalog/pg_shadow.h" #include "catalog/pg_statistic.h" #include "catalog/pg_type.h" -#include "parser/parse_coerce.h" +#include "nodes/makefuncs.h" #include "utils/array.h" #include "utils/builtins.h" #include "utils/lsyscache.h" @@ -818,19 +818,19 @@ get_typstorage(Oid typid) /* * get_typdefault - * * Given a type OID, return the type's default value, if any. - * Returns FALSE if there is no default (effectively, default is NULL). - * The result points to palloc'd storage for pass-by-reference types. + * + * The result is a palloc'd expression node tree, or NULL if there + * is no defined default for the datatype. + * + * NB: caller should be prepared to coerce result to correct datatype; + * the returned expression tree might produce something of the wrong type. */ Node * -get_typdefault(Oid typid, int32 atttypmod) +get_typdefault(Oid typid) { HeapTuple typeTuple; Form_pg_type type; - Oid typinput; - Oid typbasetype; - char typtype; Datum datum; bool isNull; Node *expr; @@ -838,48 +838,102 @@ get_typdefault(Oid typid, int32 atttypmod) typeTuple = SearchSysCache(TYPEOID, ObjectIdGetDatum(typid), 0, 0, 0); - if (!HeapTupleIsValid(typeTuple)) elog(ERROR, "get_typdefault: failed to lookup type %u", typid); - type = (Form_pg_type) GETSTRUCT(typeTuple); - typinput = type->typinput; - typbasetype = type->typbasetype; - typtype = type->typtype; - /* - * typdefaultbin is potentially null, so don't try to access it as a - * struct field. Must do it the hard way with SysCacheGetAttr. + * typdefault and typdefaultbin are potentially null, so don't try to + * access 'em as struct fields. Must do it the hard way with + * SysCacheGetAttr. */ datum = SysCacheGetAttr(TYPEOID, typeTuple, Anum_pg_type_typdefaultbin, &isNull); - ReleaseSysCache(typeTuple); - if (isNull) - return (Node *) NULL; + if (!isNull) + { + /* We have an expression default */ + expr = stringToNode(DatumGetCString(DirectFunctionCall1(textout, + datum))); + } + else + { + /* Perhaps we have a plain literal default */ + datum = SysCacheGetAttr(TYPEOID, + typeTuple, + Anum_pg_type_typdefault, + &isNull); - /* Convert Datum to a Node */ - expr = stringToNode(DatumGetCString( - DirectFunctionCall1(textout, datum))); + if (!isNull) + { + char *strDefaultVal; + + /* Convert text datum to C string */ + strDefaultVal = DatumGetCString(DirectFunctionCall1(textout, + datum)); + /* Convert C string to a value of the given type */ + datum = OidFunctionCall3(type->typinput, + CStringGetDatum(strDefaultVal), + ObjectIdGetDatum(type->typelem), + Int32GetDatum(-1)); + /* Build a Const node containing the value */ + expr = (Node *) makeConst(typid, + type->typlen, + datum, + false, + type->typbyval, + false, /* not a set */ + false); + pfree(strDefaultVal); + } + else + { + /* No default */ + expr = NULL; + } + } + ReleaseSysCache(typeTuple); + return expr; +} + +/* + * getBaseType + * If the given type is a domain, return its base type; + * otherwise return the type's own OID. + */ +Oid +getBaseType(Oid typid) +{ /* - * Ensure we goto the basetype before the domain type. - * - * Prevents scenarios like the below from failing: - * CREATE DOMAIN dom text DEFAULT random(); - * + * We loop to find the bottom base type in a stack of domains. */ - if (typbasetype != InvalidOid) { - expr = coerce_type(NULL, expr, typid, - typbasetype, atttypmod); - } + for (;;) + { + HeapTuple tup; + Form_pg_type typTup; + + tup = SearchSysCache(TYPEOID, + ObjectIdGetDatum(typid), + 0, 0, 0); + if (!HeapTupleIsValid(tup)) + elog(ERROR, "getBaseType: failed to lookup type %u", typid); + typTup = (Form_pg_type) GETSTRUCT(tup); + if (typTup->typtype != 'd') + { + /* Not a domain, so done */ + ReleaseSysCache(tup); + break; + } + typid = typTup->typbasetype; + ReleaseSysCache(tup); + } - return expr; + return typid; } /* |