Fix handling of pg_type.typdefault per bug report from Dave Blasby.
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 6 Sep 2001 02:07:42 +0000 (02:07 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 6 Sep 2001 02:07:42 +0000 (02:07 +0000)
If there's anyone out there who's actually using datatype-defined
default values, this will be an incompatible change in behavior ...
but the old behavior was so broken that I doubt anyone was using it.

doc/src/sgml/catalogs.sgml
src/backend/catalog/heap.c
src/backend/catalog/pg_type.c
src/backend/commands/define.c
src/backend/optimizer/prep/preptlist.c
src/backend/utils/cache/lsyscache.c
src/bin/pg_dump/pg_dump.c
src/include/catalog/pg_type.h
src/include/utils/lsyscache.h
src/test/regress/expected/create_type.out
src/test/regress/sql/create_type.sql

index 39c05e24bd8193056af42341e3b4646d0412cb69..0b1ab7e287414999f4ba524f32176ee8ef3f7c57 100644 (file)
@@ -1,6 +1,6 @@
 <!--
  Documentation of the system catalogs, directed toward PostgreSQL developers
- $Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.22 2001/08/26 16:55:58 tgl Exp $
+ $Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.23 2001/09/06 02:07:41 tgl Exp $
  -->
 
 <chapter id="catalogs">
       <entry></entry>
       <entry>
        The initial value of the transition state.  This is a text
-       field which will be cast to the type of aggtranstype.
+       field containing the initial value in its external string
+       representation.  If the field is NULL, the transition state
+       value starts out NULL.
       </entry>
      </row>
     </tbody>
       <entry>typdefault</entry>
       <entry><type>text</type></entry>
       <entry></entry>
-      <entry>???</entry>
+      <entry><para>
+       <structfield>typdefault</structfield> is NULL for types without a
+       default value.  If it's not NULL, it contains the external string
+       representation of the type's default value.
+      </para></entry>
      </row>
     </tbody>
    </tgroup>
index 4f7b04a36a05e44386ee80955635e68ca0b598a8..b68488ae0073c69adbff99636cb8bf706e279959 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.175 2001/08/25 18:52:41 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.176 2001/09/06 02:07:42 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -657,7 +657,6 @@ AddNewRelationTuple(Relation pg_class_desc,
 static void
 AddNewRelationType(char *typeName, Oid new_rel_oid, Oid new_type_oid)
 {
-
        /*
         * The sizes are set to oid size because it makes implementing sets
         * MUCH easier, and no one (we hope) uses these fields to figure out
@@ -666,24 +665,22 @@ AddNewRelationType(char *typeName, Oid new_rel_oid, Oid new_type_oid)
         * actually get is the oid of a tuple in the pg_proc catalog, so the
         * size of the "set" is the size of an oid. Similarly, byval being
         * true makes sets much easier, and it isn't used by anything else.
-        *
-        * XXX Note the assumption that OIDs are the same size as int4s.
         */
        TypeCreate(typeName,            /* type name */
                           new_type_oid,        /* preassigned oid for type */
                           new_rel_oid,         /* relation oid */
                           sizeof(Oid),         /* internal size */
-                          sizeof(Oid),         /* external size */
+                          -1,                          /* external size */
                           'c',                         /* type-type (catalog) */
                           ',',                         /* default array delimiter */
-                          "int4in",            /* input procedure */
-                          "int4out",           /* output procedure */
-                          "int4in",            /* receive procedure */
-                          "int4out",           /* send procedure */
+                          "oidin",                     /* input procedure */
+                          "oidout",            /* output procedure */
+                          "oidin",                     /* receive procedure */
+                          "oidout",            /* send procedure */
                           NULL,                        /* array element type - irrelevant */
-                          "-",                         /* default type value */
+                          NULL,                        /* default type value - none */
                           true,                        /* passed by value */
-                          'i',                         /* default alignment */
+                          'i',                         /* default alignment - same as for OID */
                           'p');                        /* Not TOASTable */
 }
 
index 5429c537a6e56ce4b4093089af5ec10dbc24c293..b31892860a298c84c675258e513028673f1d56f0 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.62 2001/08/10 15:49:39 petere Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.63 2001/09/06 02:07:42 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -51,7 +51,7 @@ TypeGetWithOpenRelation(Relation pg_type_desc,
        /*
         * initialize the scan key and begin a scan of pg_type
         */
-       ScanKeyEntryInitialize(typeKey,
+       ScanKeyEntryInitialize(&typeKey[0],
                                                   0,
                                                   Anum_pg_type_typname,
                                                   F_NAMEEQ,
@@ -318,10 +318,18 @@ TypeCreate(char *typeName,
        }
 
        /*
-        * XXX comment me
+        * validate size specifications: either positive (fixed-length) or
+        * -1 (variable-length).
         */
-       if (externalSize == 0)
-               externalSize = -1;              /* variable length */
+       if (! (internalSize > 0 || internalSize == -1))
+               elog(ERROR, "TypeCreate: invalid type internal size %d",
+                        internalSize);
+       if (! (externalSize > 0 || externalSize == -1))
+               elog(ERROR, "TypeCreate: invalid type external size %d",
+                        externalSize);
+
+       if (internalSize != -1 && storage != 'p')
+               elog(ERROR, "TypeCreate: fixed size types must have storage PLAIN");
 
        /*
         * initialize arrays needed by FormHeapTuple
@@ -330,20 +338,9 @@ TypeCreate(char *typeName,
        {
                nulls[i] = ' ';
                replaces[i] = 'r';
-               values[i] = (Datum) NULL;               /* redundant, but nice */
+               values[i] = (Datum) 0;
        }
 
-       /*
-        * XXX
-        *
-        * Do this so that user-defined types have size -1 instead of zero if
-        * they are variable-length - this is so that everything else in the
-        * backend works.
-        */
-
-       if (internalSize == 0)
-               internalSize = -1;
-
        /*
         * initialize the *values information
         */
@@ -435,15 +432,19 @@ TypeCreate(char *typeName,
        /*
         * initialize the default value for this type.
         */
-       values[i] = DirectFunctionCall1(textin,         /* 17 */
-                        CStringGetDatum(defaultTypeValue ? defaultTypeValue : "-"));
+       if (defaultTypeValue)
+               values[i] = DirectFunctionCall1(textin,
+                                                                               CStringGetDatum(defaultTypeValue));
+       else
+               nulls[i] = 'n';
+       i++;                                            /* 17 */
 
        /*
         * open pg_type and begin a scan for the type name.
         */
        pg_type_desc = heap_openr(TypeRelationName, RowExclusiveLock);
 
-       ScanKeyEntryInitialize(typeKey,
+       ScanKeyEntryInitialize(&typeKey[0],
                                                   0,
                                                   Anum_pg_type_typname,
                                                   F_NAMEEQ,
index f88343fa91e8655e18c9066fab87562a578eda4f..947257b5e18fea2d114fa68119517b7796566488 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.58 2001/08/03 20:47:40 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.59 2001/09/06 02:07:42 tgl Exp $
  *
  * DESCRIPTION
  *       The "DefineFoo" routines take the parse tree and pick out the
@@ -535,20 +535,20 @@ DefineAggregate(char *aggName, List *parameters)
 void
 DefineType(char *typeName, List *parameters)
 {
-       int16           internalLength = 0;             /* int2 */
-       int16           externalLength = 0;             /* int2 */
+       int16           internalLength = -1;            /* int2 */
+       int16           externalLength = -1;            /* int2 */
        char       *elemName = NULL;
        char       *inputName = NULL;
        char       *outputName = NULL;
        char       *sendName = NULL;
        char       *receiveName = NULL;
-       char       *defaultValue = NULL;        /* Datum */
+       char       *defaultValue = NULL;
        bool            byValue = false;
        char            delimiter = DEFAULT_TYPDELIM;
        char       *shadow_type;
        List       *pl;
        char            alignment = 'i'; /* default alignment */
-       char            storage = 'p';  /* default storage in TOAST */
+       char            storage = 'p';  /* default TOAST storage method */
 
        /*
         * Type names must be one character shorter than other names, allowing
@@ -556,10 +556,8 @@ DefineType(char *typeName, List *parameters)
         * "_".
         */
        if (strlen(typeName) > (NAMEDATALEN - 2))
-       {
                elog(ERROR, "DefineType: type names must be %d characters or less",
                         NAMEDATALEN - 2);
-       }
 
        foreach(pl, parameters)
        {
@@ -645,9 +643,6 @@ DefineType(char *typeName, List *parameters)
        if (outputName == NULL)
                elog(ERROR, "Define: \"output\" unspecified");
 
-       if (internalLength != -1 && storage != 'p')
-               elog(ERROR, "Define: fixed size types must have storage PLAIN");
-
        /*
         * now have TypeCreate do all the real work.
         */
@@ -674,6 +669,9 @@ DefineType(char *typeName, List *parameters)
         */
        shadow_type = makeArrayTypeName(typeName);
 
+       /* alignment must be 'i' or 'd' for arrays */
+       alignment = (alignment == 'd') ? 'd' : 'i';
+
        TypeCreate(shadow_type,         /* type name */
                           InvalidOid,          /* preassigned type oid (not done here) */
                           InvalidOid,          /* relation oid (n/a here) */
@@ -688,7 +686,7 @@ DefineType(char *typeName, List *parameters)
                           typeName,            /* element type name */
                           NULL,                        /* never a default type value */
                           false,                       /* never passed by value */
-                          alignment,           /* NB: must be 'i' or 'd' for arrays... */
+                          alignment,           /* see above */
                           'x');                        /* ARRAY is always toastable */
 
        pfree(shadow_type);
index da51a76d3f3ac8ef6c52f01de2e727ad3fe530e5..737f624b5aaaa883131d53ee4b72c290aefc63b6 100644 (file)
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.42 2001/03/22 03:59:38 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.43 2001/09/06 02:07:42 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -192,45 +192,54 @@ expand_targetlist(List *tlist, int command_type,
                        {
                                case CMD_INSERT:
                                        {
-                                               Datum           typedefault = get_typdefault(atttype);
-                                               int                     typlen;
-                                               Const      *temp_const;
+                                               bool            hasdefault;
+                                               Datum           typedefault;
+                                               int16           typlen;
+                                               bool            typbyval;
+                                               Const      *def_const;
 
-#ifdef _DROP_COLUMN_HACK__
-                                               if (COLUMN_IS_DROPPED(att_tup))
-                                                       typedefault = PointerGetDatum(NULL);
-#endif  /* _DROP_COLUMN_HACK__ */
-
-                                               if (typedefault == PointerGetDatum(NULL))
-                                                       typlen = 0;
-                                               else
+                                               if (att_tup->attisset)
                                                {
-
                                                        /*
-                                                        * Since this is an append or replace, the
-                                                        * size of any set attribute is the size of
-                                                        * the OID used to represent it.
+                                                        * Set attributes are represented as OIDs no
+                                                        * matter what the set element type is, and
+                                                        * the element type's default is irrelevant too.
                                                         */
-                                                       if (att_tup->attisset)
-                                                               typlen = get_typlen(OIDOID);
+                                                       hasdefault = false;
+                                                       typedefault = (Datum) 0;
+                                                       typlen = sizeof(Oid);
+                                                       typbyval = true;
+                                               }
+                                               else
+                                               {
+#ifdef _DROP_COLUMN_HACK__
+                                                       if (COLUMN_IS_DROPPED(att_tup))
+                                                       {
+                                                               hasdefault = false;
+                                                               typedefault = (Datum) 0;
+                                                       }
                                                        else
-                                                               typlen = get_typlen(atttype);
+#endif  /* _DROP_COLUMN_HACK__ */
+                                                               hasdefault = get_typdefault(atttype,
+                                                                                                                       &typedefault);
+
+                                                       get_typlenbyval(atttype, &typlen, &typbyval);
                                                }
 
-                                               temp_const = makeConst(atttype,
-                                                                                          typlen,
-                                                                                          typedefault,
-                                                                 (typedefault == PointerGetDatum(NULL)),
-                                                                                          false,
-                                                                                          false,       /* not a set */
-                                                                                          false);
+                                               def_const = makeConst(atttype,
+                                                                                         typlen,
+                                                                                         typedefault,
+                                                                                         !hasdefault,
+                                                                                         typbyval,
+                                                                                         false,        /* not a set */
+                                                                                         false);
 
                                                new_tle = makeTargetEntry(makeResdom(attrno,
                                                                                                                         atttype,
                                                                                                                         -1,
                                                                                                           pstrdup(attrname),
                                                                                                                         false),
-                                                                                                 (Node *) temp_const);
+                                                                                                 (Node *) def_const);
                                                break;
                                        }
                                case CMD_UPDATE:
index 1637abe999aa9c7c5c27c440f44edd3093601f4b..b788383ba50f4511cf269336148afce42cd6c8ee 100644 (file)
@@ -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.57 2001/08/21 16:36:05 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.58 2001/09/06 02:07:42 tgl Exp $
  *
  * NOTES
  *       Eventually, the index information should go through here, too.
@@ -750,23 +750,20 @@ get_typstorage(Oid typid)
 /*
  * get_typdefault
  *
- *       Given a type OID, return the typdefault field associated with that
- *       type, or Datum(NULL) if there is no typdefault.  (This implies
- *       that pass-by-value types can't have a default value that has
- *       a representation of zero.  Not worth fixing now.)
- *       The result points to palloc'd storage for non-pass-by-value types.
+ *       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.
  */
-Datum
-get_typdefault(Oid typid)
+bool
+get_typdefault(Oid typid, Datum *defaultValue)
 {
        HeapTuple       typeTuple;
        Form_pg_type type;
-       struct varlena *typDefault;
+       Oid                     typinput,
+                               typelem;
+       Datum           textDefaultVal;
        bool            isNull;
-       int32           dataSize;
-       int32           typLen;
-       bool            typByVal;
-       Datum           returnValue;
+       char       *strDefaultVal;
 
        typeTuple = SearchSysCache(TYPEOID,
                                                           ObjectIdGetDatum(typid),
@@ -777,66 +774,39 @@ get_typdefault(Oid typid)
 
        type = (Form_pg_type) GETSTRUCT(typeTuple);
 
+       typinput = type->typinput;
+       typelem = type->typelem;
+
        /*
-        * First, see if there is a non-null typdefault field (usually there
-        * isn't)
+        * typdefault is potentially null, so don't try to access it as a struct
+        * field. Must do it the hard way with SysCacheGetAttr.
         */
-       typDefault = (struct varlena *)
-               DatumGetPointer(SysCacheGetAttr(TYPEOID,
-                                                                               typeTuple,
-                                                                               Anum_pg_type_typdefault,
-                                                                               &isNull));
+       textDefaultVal = SysCacheGetAttr(TYPEOID,
+                                                                        typeTuple,
+                                                                        Anum_pg_type_typdefault,
+                                                                        &isNull);
 
        if (isNull)
        {
                ReleaseSysCache(typeTuple);
-               return PointerGetDatum(NULL);
+               *defaultValue = (Datum) 0;
+               return false;
        }
 
-       /*
-        * Otherwise, extract/copy the value.
-        */
-       dataSize = VARSIZE(typDefault) - VARHDRSZ;
-       typLen = type->typlen;
-       typByVal = type->typbyval;
+       /* Convert text datum to C string */
+       strDefaultVal = DatumGetCString(DirectFunctionCall1(textout,
+                                                                                                               textDefaultVal));
 
-       if (typByVal)
-       {
-               if (dataSize == typLen)
-                       returnValue = fetch_att(VARDATA(typDefault), typByVal, typLen);
-               else
-                       returnValue = PointerGetDatum(NULL);
-       }
-       else if (typLen < 0)
-       {
-               /* variable-size type */
-               if (dataSize < 0)
-                       returnValue = PointerGetDatum(NULL);
-               else
-               {
-                       returnValue = PointerGetDatum(palloc(VARSIZE(typDefault)));
-                       memcpy((char *) DatumGetPointer(returnValue),
-                                  (char *) typDefault,
-                                  (int) VARSIZE(typDefault));
-               }
-       }
-       else
-       {
-               /* fixed-size pass-by-ref type */
-               if (dataSize != typLen)
-                       returnValue = PointerGetDatum(NULL);
-               else
-               {
-                       returnValue = PointerGetDatum(palloc(dataSize));
-                       memcpy((char *) DatumGetPointer(returnValue),
-                                  VARDATA(typDefault),
-                                  (int) dataSize);
-               }
-       }
+       /* Convert C string to a value of the given type */
+       *defaultValue = OidFunctionCall3(typinput,
+                                                                        CStringGetDatum(strDefaultVal),
+                                                                        ObjectIdGetDatum(typelem),
+                                                                        Int32GetDatum(-1));
 
+       pfree(strDefaultVal);
        ReleaseSysCache(typeTuple);
 
-       return returnValue;
+       return true;
 }
 
 /*
index abed81cf825add76ce71a0de521299ef314c7dc0..3395026354341b11884272acf931dca50abb6512 100644 (file)
@@ -22,7 +22,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.227 2001/08/27 20:33:07 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.228 2001/09/06 02:07:42 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1400,7 +1400,10 @@ getTypes(int *numTypes)
                tinfo[i].typsend = strdup(PQgetvalue(res, i, i_typsend));
                tinfo[i].typelem = strdup(PQgetvalue(res, i, i_typelem));
                tinfo[i].typdelim = strdup(PQgetvalue(res, i, i_typdelim));
-               tinfo[i].typdefault = strdup(PQgetvalue(res, i, i_typdefault));
+               if (PQgetisnull(res, i, i_typdefault))
+                       tinfo[i].typdefault = NULL;
+               else
+                       tinfo[i].typdefault = strdup(PQgetvalue(res, i, i_typdefault));
                tinfo[i].typrelid = strdup(PQgetvalue(res, i, i_typrelid));
                tinfo[i].typalign = strdup(PQgetvalue(res, i, i_typalign));
                tinfo[i].typstorage = strdup(PQgetvalue(res, i, i_typstorage));
@@ -3167,8 +3170,10 @@ dumpTypes(Archive *fout, FuncInfo *finfo, int numFuncs,
                                                  "CREATE TYPE %s "
                                                  "( internallength = %s, externallength = %s,",
                                                  fmtId(tinfo[i].typname, force_quotes),
-                                                 tinfo[i].typlen,
-                                                 tinfo[i].typprtlen);
+                                                 (strcmp(tinfo[i].typlen, "-1") == 0) ?
+                                                 "variable" : tinfo[i].typlen,
+                                                 (strcmp(tinfo[i].typprtlen, "-1") == 0) ?
+                                                 "variable" : tinfo[i].typprtlen);
                /* cannot combine these because fmtId uses static result area */
                appendPQExpBuffer(q, " input = %s,",
                                                  fmtId(tinfo[i].typinput, force_quotes));
@@ -3176,9 +3181,14 @@ dumpTypes(Archive *fout, FuncInfo *finfo, int numFuncs,
                                                  fmtId(tinfo[i].typoutput, force_quotes));
                appendPQExpBuffer(q, " send = %s,",
                                                  fmtId(tinfo[i].typsend, force_quotes));
-               appendPQExpBuffer(q, " receive = %s, default = ",
+               appendPQExpBuffer(q, " receive = %s",
                                                  fmtId(tinfo[i].typreceive, force_quotes));
-               formatStringLiteral(q, tinfo[i].typdefault, CONV_ALL);
+
+               if (tinfo[i].typdefault != NULL)
+               {
+                       appendPQExpBuffer(q, ", default = ");
+                       formatStringLiteral(q, tinfo[i].typdefault, CONV_ALL);
+               }
 
                if (tinfo[i].isArray)
                {
index d5e020202917ca8a6d4a8f7eabc27603490b1565..912a47a96c94f279bc21e008d0fec46a920c326f 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_type.h,v 1.110 2001/08/25 18:52:43 tgl Exp $
+ * $Id: pg_type.h,v 1.111 2001/09/06 02:07:42 tgl Exp $
  *
  * NOTES
  *       the genbki.sh script reads this file and generates .bki
@@ -42,11 +42,16 @@ CATALOG(pg_type) BOOTSTRAP
        int4            typowner;
 
        /*
-        * typlen is the number of bytes we use to represent a value of this
-        * type, e.g. 4 for an int4.  But for a variable length type, typlen
-        * is -1.
+        * For a fixed-size type, typlen is the number of bytes we use to
+        * represent a value of this type, e.g. 4 for an int4.  But for a
+        * variable-length type, typlen is -1.
         */
        int2            typlen;
+       /*
+        * typprtlen was once intended to be the length of the external
+        * representation of a datatype, with the same interpretation as for
+        * typlen.  But it's currently unused.
+        */
        int2            typprtlen;
 
        /*
@@ -66,8 +71,14 @@ CATALOG(pg_type) BOOTSTRAP
         * anyway?)
         */
        char            typtype;
+
+       /*
+        * If typisdefined is false, the entry is only a placeholder (forward
+        * reference).  We know the type name, but not yet anything else about it.
+        */
        bool            typisdefined;
-       char            typdelim;
+
+       char            typdelim;               /* delimiter for arrays of this type */
        Oid                     typrelid;               /* 0 if not a class type */
 
        /*
@@ -82,6 +93,10 @@ CATALOG(pg_type) BOOTSTRAP
         *      typelem != 0 and typlen < 0.
         */
        Oid                     typelem;
+
+       /*
+        * I/O conversion procedures for the datatype.
+        */
        regproc         typinput;
        regproc         typoutput;
        regproc         typreceive;
@@ -123,6 +138,12 @@ CATALOG(pg_type) BOOTSTRAP
         */
        char            typstorage;
 
+       /*
+        * typdefault is NULL if the type has no associated default value.
+        * If it's not NULL, it contains the external representation of the
+        * type's default value --- this default is used whenever no per-column
+        * default is specified for a column of the datatype.
+        */
        text            typdefault;             /* VARIABLE LENGTH FIELD */
 } FormData_pg_type;
 
index ac7d9ba100baccda128263a705e43db12e42c645..6b3f8a52eaae03f0d7adc5a1fbb8916ae9971e7f 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: lsyscache.h,v 1.35 2001/08/21 16:36:06 tgl Exp $
+ * $Id: lsyscache.h,v 1.36 2001/09/06 02:07:42 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -42,7 +42,7 @@ extern int16 get_typlen(Oid typid);
 extern bool get_typbyval(Oid typid);
 extern void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval);
 extern char get_typstorage(Oid typid);
-extern Datum get_typdefault(Oid typid);
+extern bool get_typdefault(Oid typid, Datum *defaultValue);
 extern int32 get_typavgwidth(Oid typid, int32 typmod);
 extern int32 get_attavgwidth(Oid relid, AttrNumber attnum);
 extern bool get_attstatsslot(HeapTuple statstuple,
index 985c8f75698b155f3e9ff54223c1ab3a33a4f1ff..06b992280b110c8638334589adf1ed59895b268d 100644 (file)
@@ -13,3 +13,28 @@ CREATE TYPE city_budget (
    output = int44out, 
    element = int4
 );
+-- Test type-related default values (broken in releases before PG 7.2)
+CREATE TYPE int42 (
+   internallength = 4,
+   input = int4in,
+   output = int4out,
+   alignment = int4,
+   default = 42,
+   passedbyvalue
+);
+CREATE TYPE text_w_default (
+   internallength = variable,
+   input = textin,
+   output = textout,
+   alignment = int4,
+   default = 'zippo'
+);
+CREATE TABLE default_test (f1 text_w_default, f2 int42);
+INSERT INTO default_test DEFAULT VALUES;
+SELECT * FROM default_test;
+  f1   | f2 
+-------+----
+ zippo | 42
+(1 row)
+
+DROP TABLE default_test;
index 96655eed631c06da806e68099a3d7d218e929887..a728bbd8b9db796a8a6825553b3ba63334c38bce 100644 (file)
@@ -16,3 +16,29 @@ CREATE TYPE city_budget (
    element = int4
 );
 
+-- Test type-related default values (broken in releases before PG 7.2)
+
+CREATE TYPE int42 (
+   internallength = 4,
+   input = int4in,
+   output = int4out,
+   alignment = int4,
+   default = 42,
+   passedbyvalue
+);
+
+CREATE TYPE text_w_default (
+   internallength = variable,
+   input = textin,
+   output = textout,
+   alignment = int4,
+   default = 'zippo'
+);
+
+CREATE TABLE default_test (f1 text_w_default, f2 int42);
+
+INSERT INTO default_test DEFAULT VALUES;
+
+SELECT * FROM default_test;
+
+DROP TABLE default_test;