Code review for DOMAIN patch.
authorTom Lane
Wed, 20 Mar 2002 19:45:13 +0000 (19:45 +0000)
committerTom Lane
Wed, 20 Mar 2002 19:45:13 +0000 (19:45 +0000)
37 files changed:
doc/src/sgml/catalogs.sgml
doc/src/sgml/ref/create_domain.sgml
doc/src/sgml/ref/drop_domain.sgml
doc/src/sgml/ref/psql-ref.sgml
src/backend/catalog/heap.c
src/backend/catalog/pg_aggregate.c
src/backend/catalog/pg_proc.c
src/backend/catalog/pg_type.c
src/backend/commands/creatinh.c
src/backend/commands/define.c
src/backend/commands/indexcmds.c
src/backend/commands/remove.c
src/backend/executor/nodeAgg.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/nodes/makefuncs.c
src/backend/optimizer/path/indxpath.c
src/backend/optimizer/prep/preptlist.c
src/backend/parser/gram.y
src/backend/parser/parse_coerce.c
src/backend/parser/parse_expr.c
src/backend/parser/parse_func.c
src/backend/parser/parse_oper.c
src/backend/tcop/utility.c
src/backend/utils/adt/format_type.c
src/backend/utils/cache/lsyscache.c
src/bin/psql/describe.c
src/include/catalog/catversion.h
src/include/catalog/heap.h
src/include/catalog/pg_attribute.h
src/include/catalog/pg_type.h
src/include/nodes/makefuncs.h
src/include/nodes/parsenodes.h
src/include/parser/parse_coerce.h
src/include/utils/lsyscache.h
src/test/regress/expected/domain.out
src/test/regress/sql/domain.sql

index 451c9dcaa8af08510434568ad8b36256b670ed76..5db408f6d0f1f529716ed04ea6152a76ac551aed 100644 (file)
@@ -1,6 +1,6 @@
 
 
 
    This catalog stores information about datatypes.  Scalar types
    (base types) are created with CREATE TYPE.
    A complex type is also created for each table in the database, to
-   represent the row structure of the table.
+   represent the row structure of the table.  It is also possible to create
+   derived types with CREATE DOMAIN.
   
 
   
       
       
        typtype is b for
-       a base type and c for a complex type (i.e.,
-       a table's row type).  If typtype is
-       ctyprelid is
-       the OID of the type's entry in
-       pg_class.
+       a base type, c for a complex type (i.e.,
+       a table's row type), or d for a derived type (i.e.,
+       a domain).  See also typrelid 
+       and typbasetype.
       
      
 
        the pg_class entry that defines the
        corresponding table. A table could theoretically be used as a
        composite data type, but this is not fully functional.
+       Zero for non-complex types.
       
      
 
      
 
      
-      typbasetype
-      oid
+      typnotnull
+      bool
       
       
-       typbasetype is the type that this one is based
-       on.  Normally references the domains parent type, and is 0 otherwise.
+       typnotnull represents a NOT NULL
+       constraint on a type.  Presently used for domains only.
       
      
 
-    
-     typnotnull
-     boolean
-     
-     
-      typnotnull represents a NOT NULL
-      constraint on a type.  Used for domains only.
-     
-    
+     
+      typbasetype
+      oid
+      pg_type.oid
+      
+       If this is a derived type (see typtype),
+       then typbasetype identifies
+       the type that this one is based on.  Zero if not a derived type.
+      
+     
 
      
-      typmod
-      integer
+      typtypmod
+      int4
       
       
-       typmod records type-specific data
+       typtypmod records type-specific data
        supplied at table creation time (for example, the maximum
        length of a varchar column).  It is passed to
        type-specific input and output functions as the third
        argument. The value will generally be -1 for types that do not
-       need typmod.  This data is copied to
-       pg_attribute.atttypmod on creation
-       of a table using a domain as it's field type.
+       need typmod.  This value is copied to
+       pg_attribute.atttypmod when
+       creating a column of a domain type.
+       
+     
+
+     
+      typndims
+      int4
+      
+      
+       typndims is the number of array dimensions
+       for a domain that is an array.  (The array element type is
+       typbasetype.)  Zero for non-domains and non-array domains.
+       This value is copied to
+       pg_attribute.attndims when
+       creating a column of a domain type.
        
      
 
       text
       
       
-       typdefaultbin is NULL for types without a
-       default value.  If it's not NULL, it contains the internal string
-       representation of the default expression node.
+       If typdefaultbin is not NULL, it is the nodeToString
+       representation of a default expression for the type.  Currently this is
+       only used for domains.
       
      
 
       text
       
       
-       typdefault 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.
+       typdefault is NULL if the type has no associated
+       default value. If typdefaultbin is not NULL,
+       typdefault must contain a human-readable version of the
+       default expression represented by typdefaultbin.  If
+       typdefaultbin is NULL and typdefault is
+       not, then typdefault is the external representation of
+       the type's default value, which may be fed to the type's input
+       converter to produce a constant.
       
      
     
index 5f79dc63b539e13df2a61f45a1fb293006e91a03..222d49da5d10bafdc3da1702c73f6e04a8d9c5d7 100644 (file)
@@ -1,5 +1,5 @@
 
 
@@ -23,13 +23,14 @@ PostgreSQL documentation
    2002-02-24
   
   
-CREATE DOMAIN domainname data_type  [ DEFAULT default_expr ] [ column_constraint [, ... ] ]
+CREATE DOMAIN domainname [AS] data_type
+    [ DEFAULT default_expr ]
+    [ constraint [, ... ] ]
+
+where constraint is:
+
 [ CONSTRAINT constraint_name ]
-{ NOT NULL | NULL  }
-
+{ NOT NULL | NULL }
   
 
   
@@ -67,23 +68,26 @@ CREATE DOMAIN domainname 
       default_expr
       
        
-        The DEFAULT clause assigns a default data value for
-        the column whose column definition it appears within.  The value
-        is any variable-free expression (subselects and cross-references
-        to other columns in the current table are not allowed).  The
+        The DEFAULT clause specifies a default value for
+   columns of the domain data type.  The value
+        is any variable-free expression (but subselects are not allowed).
+   The
         data type of the default expression must match the data type of the
         domain.
        
 
        
         The default expression will be used in any insert operation that
-        does not specify a value for the domain.  If there is no default
+        does not specify a value for the column.  If there is no default
         for a domain, then the default is NULL.
        
 
        
         
-         The default of a column will be tested before that of the domain.
+         If a default value is specified for a particular column, it
+    overrides any default associated with the domain.  In turn,
+    the domain default overrides any default value associated with
+    the underlying data type.
         
        
       
@@ -93,7 +97,7 @@ CREATE DOMAIN domainname 
       CONSTRAINT constraint_name
       
        
-        An optional name for a domain.  If not specified,
+        An optional name for a constraint.  If not specified,
         the system generates a name.
        
       
@@ -103,7 +107,7 @@ CREATE DOMAIN domainname 
       NOT NULL
       
        
-        The column is not allowed to contain NULL values.  This is
+        Values of this domain are not allowed to be NULL.  This is
         equivalent to the column constraint CHECK (
         class="PARAMETER">column NOT NULL).
        
@@ -114,7 +118,7 @@ CREATE DOMAIN domainname 
       NULL
       
        
-        The column is allowed to contain NULL values. This is the default.
+        Values of this domain are allowed to be NULL.  This is the default.
        
 
        
@@ -175,7 +179,7 @@ CREATE DOMAIN
    Domains are useful for abstracting common fields between tables into
    a single location for maintenance.  An email address column may be used
    in several tables, all with the same properties.  Define a domain and
-   use that rather than setting up each tables constraints individually.
+   use that rather than setting up each table's constraints individually.
   
  
 
@@ -195,9 +199,9 @@ CREATE TABLE countrylist (id INT4, country country_code);
   Compatibility
 
   
-   This CREATE DOMAIN command is a
-   PostgreSQL extension.  CHECK and FOREIGN KEY
-   constraints are currently unsupported.
+   SQL99 defines CREATE DOMAIN, but says that the only allowed constraint
+   type is CHECK constraints.  CHECK constraints for domains are not yet
+   supported by PostgreSQL.
   
  
 
index e9bc38ad28cb9a94628f8ec5a5f7432e116777d7..63eb0dc057ee30cf8ee1ea0b6be726b74c5ac69c 100644 (file)
@@ -1,5 +1,5 @@
 
 
@@ -23,7 +23,7 @@ PostgreSQL documentation
    1999-07-20
   
   
-DROP DOMAIN domainname [, ...]
+DROP DOMAIN domainname [, ...]  [ CASCADE | RESTRICT ]
   
 
   
@@ -43,6 +43,25 @@ DROP DOMAIN domainname [, ...]
        
       
      
+
+     
+      CASCADE
+      
+       
+        Automatically drop objects that depend on the domain.  This
+   behavior is not currently supported.
+       
+      
+     
+
+     
+      RESTRICT
+      
+       
+        Do not drop dependent objects.  This is the default.
+       
+      
+     
     
    
   
@@ -117,7 +136,7 @@ ERROR:  RemoveDomain: type 'domainname
    To remove the box domain:
 
 
-DROP DOMAIN box RESTRICT;
+DROP DOMAIN box;
 
   
  
@@ -134,9 +153,8 @@ DROP DOMAIN box RESTRICT;
 
 DROP DOMAIN name { CASCADE | RESTRICT }
 
-   PostgreSQL enforces the existance of
-   RESTRICT or CASCADE but ignores their enforcement against the
-   system tables.
+   PostgreSQL accepts only the RESTRICT
+   option, and currently does not check for existence of dependent objects.
   
  
 
index 350128fa7244041d76ca06421785fd3c69eff6bc..40ba18716c222bd13fdc587f481fdb44c00d451d 100644 (file)
@@ -1,5 +1,5 @@
 
 
@@ -419,21 +419,10 @@ testdb=>
         \dD [ pattern ]
         
         
-        Lists all database domains.
-        
-
-        
-        Descriptions for objects can be generated with the COMMENT ON
-        SQL command.
-   
-
-        
-        
-        PostgreSQL stores the object descriptions in the
-        pg_description system table.
+        Lists all available domains (derived types).
+   If pattern
+   (a regular expression) is specified, only matching domains are shown.
         
-        
-
         
       
 
index b2359e4725c7f3b6ab5635bb753a6f0e0f3bafd1..e7bb12807688fa0e1f407f889c05a4d777d59df5 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.188 2002/03/19 02:58:19 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.189 2002/03/20 19:43:34 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -705,7 +705,7 @@ AddNewRelationType(char *typeName, Oid new_rel_oid, Oid new_type_oid)
               true,            /* passed by value */
               'i',             /* default alignment - same as for OID */
               'p',             /* Not TOASTable */
-              -1,              /* Type mod length */
+              -1,              /* typmod */
               0,               /* array dimensions for typBaseType */
               false);          /* Type NOT NULL */
 }
@@ -1589,10 +1589,7 @@ AddRelationRawConstraints(Relation rel,
    RangeTblEntry *rte;
    int         numchecks;
    List       *listptr;
-
-   /* Probably shouldn't be null by default */
-   Node       *expr = NULL;
-
+   Node       *expr;
 
    /*
     * Get info about existing constraints.
@@ -1624,17 +1621,11 @@ AddRelationRawConstraints(Relation rel,
    foreach(listptr, rawColDefaults)
    {
        RawColumnDefault *colDef = (RawColumnDefault *) lfirst(listptr);
-
-
        Form_pg_attribute atp = rel->rd_att->attrs[colDef->attnum - 1];
 
-       expr = cookDefault(pstate, colDef->raw_default
-                       , atp->atttypid, atp->atttypmod
-                       , NameStr(atp->attname));
-
-       /*
-        * OK, store it.
-        */
+       expr = cookDefault(pstate, colDef->raw_default,
+                          atp->atttypid, atp->atttypmod,
+                          NameStr(atp->attname));
        StoreAttrDefault(rel, colDef->attnum, nodeToString(expr));
    }
 
@@ -1646,7 +1637,6 @@ AddRelationRawConstraints(Relation rel,
    {
        Constraint *cdef = (Constraint *) lfirst(listptr);
        char       *ccname;
-       Node       *expr;
 
        if (cdef->contype != CONSTR_CHECK || cdef->raw_expr == NULL)
            continue;
@@ -1851,17 +1841,21 @@ SetRelationNumChecks(Relation rel, int numchecks)
  * Take a raw default and convert it to a cooked format ready for
  * storage.
  *
- * Parse state, attypid, attypmod and attname are required for
- * CoerceTargetExpr() and more importantly transformExpr().
+ * Parse state should be set up to recognize any vars that might appear
+ * in the expression.  (Even though we plan to reject vars, it's more
+ * user-friendly to give the correct error message than "unknown var".)
+ *
+ * If atttypid is not InvalidOid, check that the expression is coercible
+ * to the specified type.  atttypmod is needed in this case, and attname
+ * is used in the error message if any.
  */
 Node *
 cookDefault(ParseState *pstate,
            Node *raw_default,
            Oid atttypid,
            int32 atttypmod,
-           char *attname) {
-
-   Oid         type_id;
+           char *attname)
+{
    Node        *expr;
 
    Assert(raw_default != NULL);
@@ -1896,22 +1890,20 @@ cookDefault(ParseState *pstate,
     * will actually do the coercion, to ensure we don't accept an
     * unusable default expression.
     */
-   type_id = exprType(expr);
-   if (type_id != InvalidOid && atttypid != InvalidOid) {
-       if (type_id != atttypid) {
+   if (OidIsValid(atttypid))
+   {
+       Oid     type_id = exprType(expr);
 
-           /* Try coercing to the base type of the domain if available */
+       if (type_id != atttypid)
+       {
            if (CoerceTargetExpr(pstate, expr, type_id,
-                                getBaseType(atttypid),
-                                atttypmod) == NULL) {
-
+                                atttypid, atttypmod) == NULL)
                elog(ERROR, "Column \"%s\" is of type %s"
-                   " but default expression is of type %s"
-                   "\n\tYou will need to rewrite or cast the expression",
+                    " but default expression is of type %s"
+                    "\n\tYou will need to rewrite or cast the expression",
                     attname,
                     format_type_be(atttypid),
                     format_type_be(type_id));
-           }
        }
    }
 
index f037852bb57b9886240c61dba2b4ea3267b1ead6..8de1a52c3fa515a3fdbc8b6b6c3c3c5cc7ada26d 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.40 2001/10/25 05:49:23 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.41 2002/03/20 19:43:35 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -135,14 +135,13 @@ AggregateCreate(char *aggName,
 
    /*
     * If the transfn is strict and the initval is NULL, make sure input
-    * type and transtype are the same (or at least binary- compatible),
+    * type and transtype are the same (or at least binary-compatible),
     * so that it's OK to use the first input value as the initial
     * transValue.
     */
    if (proc->proisstrict && agginitval == NULL)
    {
-       if (basetype != transtype &&
-           !IS_BINARY_COMPATIBLE(basetype, transtype))
+       if (!IsBinaryCompatible(basetype, transtype))
            elog(ERROR, "must not omit initval when transfn is strict and transtype is not compatible with input type");
    }
    ReleaseSysCache(tup);
index 2c398bc0369c9c59d08f0feec1129dabc3449aba..78041ac585ab807694a31273a67d661e0ab8e103 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.65 2002/03/06 06:09:26 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.66 2002/03/20 19:43:36 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -423,7 +423,7 @@ checkretval(Oid rettype, List *queryTreeList)
                 format_type_be(rettype));
 
        restype = ((TargetEntry *) lfirst(tlist))->resdom->restype;
-       if (restype != rettype && !IS_BINARY_COMPATIBLE(restype, rettype))
+       if (!IsBinaryCompatible(restype, rettype))
            elog(ERROR, "return type mismatch in function: declared to return %s, returns %s",
                 format_type_be(rettype), format_type_be(restype));
 
@@ -440,7 +440,7 @@ checkretval(Oid rettype, List *queryTreeList)
    if (tlistlen == 1)
    {
        restype = ((TargetEntry *) lfirst(tlist))->resdom->restype;
-       if (restype == rettype || IS_BINARY_COMPATIBLE(restype, rettype))
+       if (IsBinaryCompatible(restype, rettype))
            return;
    }
 
@@ -470,7 +470,7 @@ checkretval(Oid rettype, List *queryTreeList)
            continue;
        tletype = exprType(tle->expr);
        atttype = reln->rd_att->attrs[i]->atttypid;
-       if (tletype != atttype && !IS_BINARY_COMPATIBLE(tletype, atttype))
+       if (!IsBinaryCompatible(tletype, atttype))
            elog(ERROR, "function declared to return %s returns %s instead of %s at column %d",
                 format_type_be(rettype),
                 format_type_be(tletype),
index 351646691906a25aa37f9c98967a81b1570a5819..6878691241d10ef9327e35389e7e62e00afa4540 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.68 2002/03/19 02:18:14 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.69 2002/03/20 19:43:38 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -179,13 +179,11 @@ TypeShellMakeWithOpenRelation(Relation pg_type_desc, char *typeName)
    values[i++] = CharGetDatum('i');            /* 15 */
    values[i++] = CharGetDatum('p');            /* 16 */
    values[i++] = BoolGetDatum(false);          /* 17 */
-   values[i++] = Int32GetDatum(-1);            /* 18 */
-   values[i++] = ObjectIdGetDatum(InvalidOid); /* 19 */
+   values[i++] = ObjectIdGetDatum(InvalidOid); /* 18 */
+   values[i++] = Int32GetDatum(-1);            /* 19 */
    values[i++] = Int32GetDatum(0);             /* 20 */
-   values[i++] = DirectFunctionCall1(textin,
-                                     CStringGetDatum(typeName));       /* 21 */
-   values[i++] = DirectFunctionCall1(textin,
-                                     CStringGetDatum(typeName));       /* 22 */
+   nulls[i++] = 'n';           /* 21 */
+   nulls[i++] = 'n';           /* 22 */
 
    /*
     * create a new type tuple with FormHeapTuple
@@ -288,7 +286,7 @@ TypeCreate(char *typeName,
           char storage,
           int32 typeMod,
           int32 typNDims,          /* Array dimensions for baseTypeName */
-          bool typeNotNull)        /* binary default representation (cooked) */
+          bool typeNotNull)
 {
    int         i,
                j;
@@ -452,21 +450,10 @@ TypeCreate(char *typeName,
     */
    values[i++] = CharGetDatum(storage);        /* 16 */
 
-   /*
-    * set the typenotnull value
-    */
-   values[i++] = BoolGetDatum(typeNotNull);    /* 17 */
-
-   /*
-    * set the typemod value
-    */
-   values[i++] = Int32GetDatum(typeMod);           /* 18 */
-
-   values[i++] = ObjectIdGetDatum(baseObjectId);   /* 19 */
-
-   /*
-    * Dimension number for an array base type
-    */
+   /* set typnotnull, typbasetype, typtypmod, typndims */
+   values[i++] = BoolGetDatum(typeNotNull);        /* 17 */
+   values[i++] = ObjectIdGetDatum(baseObjectId);   /* 18 */
+   values[i++] = Int32GetDatum(typeMod);           /* 19 */
    values[i++] = Int32GetDatum(typNDims);          /* 20 */
 
    /*
@@ -475,17 +462,17 @@ TypeCreate(char *typeName,
     */
    if (defaultTypeBin)
        values[i] = DirectFunctionCall1(textin,
-                                     CStringGetDatum(defaultTypeBin));
+                                       CStringGetDatum(defaultTypeBin));
    else
        nulls[i] = 'n';
-   i++;                                        /* 21 */
+   i++;                        /* 21 */
 
    /*
     * initialize the default value for this type.
     */
    if (defaultTypeValue)
        values[i] = DirectFunctionCall1(textin,
-                                     CStringGetDatum(defaultTypeValue));
+                                       CStringGetDatum(defaultTypeValue));
    else
        nulls[i] = 'n';
    i++;                        /* 22 */
index d6af805715c43bd2ec53415096e0160cbc1cedf9..c9dee0cbbedb870708208f61e603d5cb5147d33d 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.87 2002/03/19 02:58:19 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.88 2002/03/20 19:43:42 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -42,6 +42,7 @@ static int    findAttrByName(const char *attributeName, List *schema);
 static void setRelhassubclassInRelation(Oid relationId, bool relhassubclass);
 static List *MergeDomainAttributes(List *schema);
 
+
 /* ----------------------------------------------------------------
  *     DefineRelation
  *             Creates a new relation.
@@ -71,9 +72,9 @@ DefineRelation(CreateStmt *stmt, char relkind)
    StrNCpy(relname, stmt->relname, NAMEDATALEN);
 
    /*
-    * Inherit domain attributes into the known columns before table inheritance
-    * applies it's changes otherwise we risk adding double constraints
-    * to a domain thats inherited.
+    * Merge domain attributes into the known columns before processing table
+    * inheritance.  Otherwise we risk adding double constraints to a
+    * domain-type column that's inherited.
     */
    schema = MergeDomainAttributes(schema);
 
@@ -273,11 +274,8 @@ TruncateRelation(const char *relname)
 /*
  * MergeDomainAttributes
  *      Returns a new table schema with the constraints, types, and other
- *      attributes of the domain resolved for fields using the domain as
- *     their type.
- *
- * Defaults are pulled out by the table attribute as required, similar to
- * how all types defaults are processed.
+ *      attributes of domains resolved for fields using a domain as
+ *      their type.
  */
 static List *
 MergeDomainAttributes(List *schema)
@@ -295,34 +293,25 @@ MergeDomainAttributes(List *schema)
        HeapTuple  tuple;
        Form_pg_type typeTup;
 
-
        tuple = SearchSysCache(TYPENAME,
                               CStringGetDatum(coldef->typename->name),
                               0,0,0);
-
        if (!HeapTupleIsValid(tuple))
            elog(ERROR, "MergeDomainAttributes: Type %s does not exist",
                 coldef->typename->name);
-
        typeTup = (Form_pg_type) GETSTRUCT(tuple);
-       if (typeTup->typtype == 'd') {
-           /*
-            * This is a domain, lets force the properties of the domain on to
-            * the new column.
-            */
-
-           /* Enforce the typmod value */
-           coldef->typename->typmod = typeTup->typmod;
 
-           /* Enforce type NOT NULL || column definition NOT NULL -> NOT NULL */
-           coldef->is_not_null |= typeTup->typnotnull;
+       if (typeTup->typtype == 'd')
+       {
+           /* Force the column to have the correct typmod. */
+           coldef->typename->typmod = typeTup->typtypmod;
+           /* XXX more to do here? */
+       }
 
-           /* Enforce the element type in the event the domain is an array
-            *
-            * BUG: How do we fill out arrayBounds and attrname from typelem and typNDimms?
-            */
+       /* Enforce type NOT NULL || column definition NOT NULL -> NOT NULL */
+       /* Currently only used for domains, but could be valid for all */
+       coldef->is_not_null |= typeTup->typnotnull;
 
-       }
        ReleaseSysCache(tuple);
    }
 
index 72aa7a3a15f092ce098a34f0a3a5edea57e3a0ae..2441e49bcaae3bfba5af5999703baf090f63bd72 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.70 2002/03/19 02:18:15 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.71 2002/03/20 19:43:44 tgl Exp $
  *
  * DESCRIPTION
  *   The "DefineFoo" routines take the parse tree and pick out the
@@ -483,38 +483,29 @@ DefineAggregate(char *aggName, List *parameters)
 void
 DefineDomain(CreateDomainStmt *stmt)
 {
-   int16       internalLength = -1;    /* int2 */
-   int16       externalLength = -1;    /* int2 */
-   char       *inputName = NULL;
-   char       *outputName = NULL;
-   char       *sendName = NULL;
-   char       *receiveName = NULL;
-
-   /*
-    * Domains store the external representation in defaultValue
-    * and the interal Node representation in defaultValueBin
-    */
-   char       *defaultValue = NULL;
-   char       *defaultValueBin = NULL;
-
-   bool        byValue = false;
-   char        delimiter = DEFAULT_TYPDELIM;
-   char        alignment = 'i';    /* default alignment */
-   char        storage = 'p';  /* default TOAST storage method */
+   int16       internalLength;
+   int16       externalLength;
+   char       *inputName;
+   char       *outputName;
+   char       *sendName;
+   char       *receiveName;
+   bool        byValue;
+   char        delimiter;
+   char        alignment;
+   char        storage;
    char        typtype;
    Datum       datum;
+   bool        isnull;
+   char       *defaultValue = NULL;
+   char       *defaultValueBin = NULL;
    bool        typNotNull = false;
+   Oid         basetypelem;
    char        *elemName = NULL;
    int32       typNDims = 0;   /* No array dimensions by default */
-
-   bool        isnull;
-   Relation    pg_type_rel;
-   TupleDesc   pg_type_dsc;
    HeapTuple   typeTup;
    char       *typeName = stmt->typename->name;
-
-   List       *listptr;
    List       *schema = stmt->constraints;
+   List       *listptr;
 
    /*
     * Domainnames, unlike typenames don't need to account for the '_'
@@ -524,25 +515,13 @@ DefineDomain(CreateDomainStmt *stmt)
        elog(ERROR, "CREATE DOMAIN: domain names must be %d characters or less",
             NAMEDATALEN - 1);
 
-
    /* Test for existing Domain (or type) of that name */
-   typeTup = SearchSysCache( TYPENAME
-                           , PointerGetDatum(stmt->domainname)
-                           , 0, 0, 0
-                           );
-
+   typeTup = SearchSysCache(TYPENAME,
+                            PointerGetDatum(stmt->domainname),
+                            0, 0, 0);
    if (HeapTupleIsValid(typeTup))
-   {
-       elog(ERROR, "CREATE DOMAIN: domain or type  %s already exists",
+       elog(ERROR, "CREATE DOMAIN: domain or type %s already exists",
             stmt->domainname);
-   }
-
-   /*
-    * Get the information about old types
-    */
-   pg_type_rel = heap_openr(TypeRelationName, RowExclusiveLock);
-   pg_type_dsc = RelationGetDescr(pg_type_rel);
-
 
    /*
     * When the type is an array for some reason we don't actually receive
@@ -555,22 +534,12 @@ DefineDomain(CreateDomainStmt *stmt)
        typNDims = length(stmt->typename->arrayBounds);
    }
 
-
-   typeTup = SearchSysCache( TYPENAME
-                           , PointerGetDatum(typeName)
-                           , 0, 0, 0
-                           );
-
+   typeTup = SearchSysCache(TYPENAME,
+                            PointerGetDatum(typeName),
+                            0, 0, 0);
    if (!HeapTupleIsValid(typeTup))
-   {
        elog(ERROR, "CREATE DOMAIN: type %s does not exist",
             stmt->typename->name);
-   }
-
-
-   /* Check that this is a basetype */
-   typtype = DatumGetChar(heap_getattr(typeTup, Anum_pg_type_typtype, pg_type_dsc, &isnull));
-   Assert(!isnull);
 
    /*
     * What we really don't want is domains of domains.  This could cause all sorts
@@ -578,9 +547,10 @@ DefineDomain(CreateDomainStmt *stmt)
     *
     * With testing, we may determine complex types should be allowed
     */
-   if (typtype != 'b') {
-       elog(ERROR, "DefineDomain: %s is not a basetype", stmt->typename->name);
-   }
+   typtype = ((Form_pg_type) GETSTRUCT(typeTup))->typtype;
+   if (typtype != 'b')
+       elog(ERROR, "DefineDomain: %s is not a basetype",
+            stmt->typename->name);
 
    /* passed by value */
    byValue = ((Form_pg_type) GETSTRUCT(typeTup))->typbyval;
@@ -588,6 +558,9 @@ DefineDomain(CreateDomainStmt *stmt)
    /* Required Alignment */
    alignment = ((Form_pg_type) GETSTRUCT(typeTup))->typalign;
 
+   /* TOAST Strategy */
+   storage = ((Form_pg_type) GETSTRUCT(typeTup))->typstorage;
+
    /* Storage Length */
    internalLength = ((Form_pg_type) GETSTRUCT(typeTup))->typlen;
 
@@ -597,70 +570,66 @@ DefineDomain(CreateDomainStmt *stmt)
    /* Array element Delimiter */
    delimiter = ((Form_pg_type) GETSTRUCT(typeTup))->typdelim;
 
+   /*
+    * XXX this is pretty bogus: should be passing function OIDs to
+    * TypeCreate, not names which aren't unique.
+    */
+
    /* Input Function Name */
-   datum = heap_getattr(typeTup, Anum_pg_type_typinput, pg_type_dsc, &isnull);
+   datum = SysCacheGetAttr(TYPENAME, typeTup, Anum_pg_type_typinput, &isnull);
    Assert(!isnull);
 
    inputName = DatumGetCString(DirectFunctionCall1(regprocout, datum));
 
    /* Output Function Name */
-   datum = heap_getattr(typeTup, Anum_pg_type_typoutput, pg_type_dsc, &isnull);
+   datum = SysCacheGetAttr(TYPENAME, typeTup, Anum_pg_type_typoutput, &isnull);
    Assert(!isnull);
 
    outputName = DatumGetCString(DirectFunctionCall1(regprocout, datum));
 
    /* ReceiveName */
-   datum = heap_getattr(typeTup, Anum_pg_type_typreceive, pg_type_dsc, &isnull);
+   datum = SysCacheGetAttr(TYPENAME, typeTup, Anum_pg_type_typreceive, &isnull);
    Assert(!isnull);
 
    receiveName = DatumGetCString(DirectFunctionCall1(regprocout, datum));
 
    /* SendName */
-   datum = heap_getattr(typeTup, Anum_pg_type_typsend, pg_type_dsc, &isnull);
+   datum = SysCacheGetAttr(TYPENAME, typeTup, Anum_pg_type_typsend, &isnull);
    Assert(!isnull);
 
    sendName = DatumGetCString(DirectFunctionCall1(regprocout, datum));
 
-   /* TOAST Strategy */
-   storage =  ((Form_pg_type) GETSTRUCT(typeTup))->typstorage;
-   Assert(!isnull);
-
    /* Inherited default value */
-   datum =             heap_getattr(typeTup, Anum_pg_type_typdefault, pg_type_dsc, &isnull);
-   if (!isnull) {
-       defaultValue =  DatumGetCString(DirectFunctionCall1(textout, datum));
-   }
+   datum = SysCacheGetAttr(TYPENAME, typeTup,
+                           Anum_pg_type_typdefault, &isnull);
+   if (!isnull)
+       defaultValue = DatumGetCString(DirectFunctionCall1(textout, datum));
 
    /* Inherited default binary value */
-   datum =             heap_getattr(typeTup, Anum_pg_type_typdefaultbin, pg_type_dsc, &isnull);
-   if (!isnull) {
-       defaultValueBin =   DatumGetCString(DirectFunctionCall1(textout, datum));
-   }
+   datum = SysCacheGetAttr(TYPENAME, typeTup,
+                           Anum_pg_type_typdefaultbin, &isnull);
+   if (!isnull)
+       defaultValueBin = DatumGetCString(DirectFunctionCall1(textout, datum));
 
    /*
     * Pull out the typelem name of the parent OID.
     *
     * This is what enables us to make a domain of an array
     */
-   datum =             heap_getattr(typeTup, Anum_pg_type_typelem, pg_type_dsc, &isnull);
-   Assert(!isnull);
-
-   if (DatumGetObjectId(datum) != InvalidOid) {
+   basetypelem = ((Form_pg_type) GETSTRUCT(typeTup))->typelem;
+   if (basetypelem != InvalidOid)
+   {
        HeapTuple tup;
 
-       tup = SearchSysCache( TYPEOID
-                           , datum
-                           , 0, 0, 0
-                           );
-
-       elemName = NameStr(((Form_pg_type) GETSTRUCT(tup))->typname);
-
+       tup = SearchSysCache(TYPEOID,
+                            ObjectIdGetDatum(basetypelem),
+                            0, 0, 0);
+       elemName = pstrdup(NameStr(((Form_pg_type) GETSTRUCT(tup))->typname));
        ReleaseSysCache(tup);
    }
 
-
    /*
-    * Run through constraints manually avoids the additional
+    * Run through constraints manually to avoid the additional
     * processing conducted by DefineRelation() and friends.
     *
     * Besides, we don't want any constraints to be cooked.  We'll
@@ -668,20 +637,13 @@ DefineDomain(CreateDomainStmt *stmt)
     */
    foreach(listptr, schema)
    {
+       Constraint *colDef = lfirst(listptr);
        bool nullDefined = false;
        Node       *expr;
-       Constraint *colDef = lfirst(listptr);
-
-       /* Used for the statement transformation */
        ParseState *pstate;
 
-       /*
-        * Create a dummy ParseState and insert the target relation as its
-        * sole rangetable entry.  We need a ParseState for transformExpr.
-        */
-       pstate = make_parsestate(NULL);
-
-       switch(colDef->contype) {
+       switch (colDef->contype)
+       {
            /*
             * The inherited default value may be overridden by the user
             * with the DEFAULT  statement.
@@ -690,27 +652,26 @@ DefineDomain(CreateDomainStmt *stmt)
             * don't want to cook or fiddle too much.
             */
            case CONSTR_DEFAULT:
-
+               /* Create a dummy ParseState for transformExpr */
+               pstate = make_parsestate(NULL);
                /*
-                * Cook the colDef->raw_expr into an expression to ensure
-                * that it can be done.  We store the text version of the
-                * raw value.
-                *
+                * Cook the colDef->raw_expr into an expression.
                 * Note: Name is strictly for error message
                 */
-               expr = cookDefault(pstate, colDef->raw_expr
-                               , typeTup->t_data->t_oid
-                               , stmt->typename->typmod
-                               , stmt->typename->name);
-
-               /* Binary default required */
+               expr = cookDefault(pstate, colDef->raw_expr,
+                                  typeTup->t_data->t_oid,
+                                  stmt->typename->typmod,
+                                  stmt->typename->name);
+               /*
+                * Expression must be stored as a nodeToString result,
+                * but we also require a valid textual representation
+                * (mainly to make life easier for pg_dump).
+                */
                defaultValue = deparse_expression(expr,
                                deparse_context_for(stmt->domainname,
                                                    InvalidOid),
                                                   false);
-
                defaultValueBin = nodeToString(expr);
-
                break;
 
            /*
@@ -723,7 +684,6 @@ DefineDomain(CreateDomainStmt *stmt)
                    typNotNull = true;
                    nullDefined = true;
                }
-
                break;
 
            case CONSTR_NULL:
@@ -733,31 +693,31 @@ DefineDomain(CreateDomainStmt *stmt)
                    typNotNull = false;
                    nullDefined = true;
                }
-
                break;
 
            case CONSTR_UNIQUE:
-               elog(ERROR, "CREATE DOMAIN / UNIQUE indecies not supported");
+               elog(ERROR, "CREATE DOMAIN / UNIQUE indexes not supported");
                break;
 
            case CONSTR_PRIMARY:
-               elog(ERROR, "CREATE DOMAIN / PRIMARY KEY indecies not supported");
+               elog(ERROR, "CREATE DOMAIN / PRIMARY KEY indexes not supported");
                break;
 
-
            case CONSTR_CHECK:
-
-               elog(ERROR, "defineDomain: CHECK Constraints not supported");
+               elog(ERROR, "DefineDomain: CHECK Constraints not supported");
                break;
 
            case CONSTR_ATTR_DEFERRABLE:
            case CONSTR_ATTR_NOT_DEFERRABLE:
            case CONSTR_ATTR_DEFERRED:
            case CONSTR_ATTR_IMMEDIATE:
-               elog(ERROR, "defineDomain: DEFERRABLE, NON DEFERRABLE, DEFERRED and IMMEDIATE not supported");
+               elog(ERROR, "DefineDomain: DEFERRABLE, NON DEFERRABLE, DEFERRED and IMMEDIATE not supported");
                break;
-       }
 
+           default:
+               elog(ERROR, "DefineDomain: unrecognized constraint node type");
+               break;
+       }
    }
 
    /*
@@ -776,8 +736,8 @@ DefineDomain(CreateDomainStmt *stmt)
               sendName,            /* send procedure */
               elemName,            /* element type name */
               typeName,            /* base type name */
-              defaultValue,        /* default type value */
-              defaultValueBin,     /* default type value */
+              defaultValue,        /* default type value (text) */
+              defaultValueBin,     /* default type value (binary) */
               byValue,             /* passed by value */
               alignment,           /* required alignment */
               storage,             /* TOAST strategy */
@@ -789,10 +749,8 @@ DefineDomain(CreateDomainStmt *stmt)
     * Now we can clean up.
     */
    ReleaseSysCache(typeTup);
-   heap_close(pg_type_rel, NoLock);
 }
 
-
 /*
  * DefineType
  *     Registers a new type.
@@ -808,8 +766,6 @@ DefineType(char *typeName, List *parameters)
    char       *sendName = NULL;
    char       *receiveName = NULL;
    char       *defaultValue = NULL;
-   char       *defaultValueBin = NULL;
-   Node       *defaultRaw = (Node *) NULL;
    bool        byValue = false;
    char        delimiter = DEFAULT_TYPDELIM;
    char       *shadow_type;
@@ -851,7 +807,7 @@ DefineType(char *typeName, List *parameters)
        else if (strcasecmp(defel->defname, "element") == 0)
            elemName = defGetString(defel);
        else if (strcasecmp(defel->defname, "default") == 0)
-           defaultRaw = defel->arg;
+           defaultValue = defGetString(defel);
        else if (strcasecmp(defel->defname, "passedbyvalue") == 0)
            byValue = true;
        else if (strcasecmp(defel->defname, "alignment") == 0)
@@ -911,32 +867,6 @@ DefineType(char *typeName, List *parameters)
    if (outputName == NULL)
        elog(ERROR, "Define: \"output\" unspecified");
 
-
-   if (defaultRaw) {
-       Node   *expr;
-       ParseState *pstate;
-
-       /*
-        * Create a dummy ParseState and insert the target relation as its
-        * sole rangetable entry.  We need a ParseState for transformExpr.
-        */
-       pstate = make_parsestate(NULL);
-
-       expr = cookDefault(pstate, defaultRaw,
-                          InvalidOid,
-                          -1,
-                          typeName);
-
-       /* Binary default required */
-       defaultValue = deparse_expression(expr,
-                       deparse_context_for(typeName,
-                                           InvalidOid),
-                                          false);
-
-       defaultValueBin = nodeToString(expr);
-   }
-
-
    /*
     * now have TypeCreate do all the real work.
     */
@@ -952,9 +882,9 @@ DefineType(char *typeName, List *parameters)
               receiveName,     /* receive procedure */
               sendName,        /* send procedure */
               elemName,        /* element type name */
-              NULL,            /* base type name (Non-zero for domains) */
+              NULL,            /* base type name (only for domains) */
               defaultValue,    /* default type value */
-              defaultValueBin, /* default type value (Binary form) */
+              NULL,            /* no binary form available */
               byValue,         /* passed by value */
               alignment,       /* required alignment */
               storage,         /* TOAST strategy */
index b04ec8a9b4118d68fcc6b6ab59f76581ce13dd07..677f1306376ebdfc827c6870b66958d7d63adde5 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.63 2002/03/06 06:09:33 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.64 2002/03/20 19:43:47 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -314,8 +314,7 @@ FuncIndexArgs(IndexInfo *indexInfo,
 
    for (i = 0; i < nargs; i++)
    {
-       if (argTypes[i] != true_typeids[i] &&
-           !IS_BINARY_COMPATIBLE(argTypes[i], true_typeids[i]))
+       if (!IsBinaryCompatible(argTypes[i], true_typeids[i]))
            func_error("DefineIndex", funcIndex->name, nargs, argTypes,
                       "Index function must be binary-compatible with table datatype");
    }
@@ -418,8 +417,7 @@ GetAttrOpClass(IndexElem *attribute, Oid attrType,
    opInputType = ((Form_pg_opclass) GETSTRUCT(tuple))->opcintype;
    ReleaseSysCache(tuple);
 
-   if (attrType != opInputType &&
-       !IS_BINARY_COMPATIBLE(attrType, opInputType))
+   if (!IsBinaryCompatible(attrType, opInputType))
        elog(ERROR, "operator class \"%s\" does not accept data type %s",
             attribute->class, format_type_be(attrType));
 
@@ -470,7 +468,7 @@ GetDefaultOpClass(Oid attrType, Oid accessMethodId)
                nexact++;
                exactOid = tuple->t_data->t_oid;
            }
-           else if (IS_BINARY_COMPATIBLE(opclass->opcintype, attrType))
+           else if (IsBinaryCompatible(opclass->opcintype, attrType))
            {
                ncompatible++;
                compatibleOid = tuple->t_data->t_oid;
index 297b351df834a3ba945409770aff5835e5ab6f23..99b243ed4fdf9f2cfe8266ff5fd6f73c5d72f095 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.69 2002/03/19 02:18:16 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.70 2002/03/20 19:43:49 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -282,23 +282,18 @@ RemoveType(char *typeName)        /* type name to be removed */
  *     use it.
  */
 void
-RemoveDomain(char *domainName, int behavior)       /* domain name to be removed */
+RemoveDomain(char *domainName, int behavior)
 {
    Relation    relation;
    HeapTuple   tup;
-   TupleDesc   description;
    char        typtype;
-   bool        isnull;
-
 
    /* Domains are stored as types.  Check for permissions on the type */
    if (!pg_ownercheck(GetUserId(), domainName, TYPENAME))
        elog(ERROR, "RemoveDomain: type '%s': permission denied",
             domainName);
 
-
    relation = heap_openr(TypeRelationName, RowExclusiveLock);
-   description = RelationGetDescr(relation);
 
    tup = SearchSysCache(TYPENAME,
                         PointerGetDatum(domainName),
@@ -306,14 +301,11 @@ RemoveDomain(char *domainName, int behavior)      /* domain name to be removed */
    if (!HeapTupleIsValid(tup))
        elog(ERROR, "RemoveType: type '%s' does not exist", domainName);
 
-
    /* Check that this is actually a domain */
-   typtype = DatumGetChar(heap_getattr(tup, Anum_pg_type_typtype, description, &isnull));
-   Assert(!isnull);
+   typtype = ((Form_pg_type) GETSTRUCT(tup))->typtype;
 
-   if (typtype != 'd') {
+   if (typtype != 'd')
        elog(ERROR, "%s is not a domain", domainName);
-   }
 
    /* CASCADE unsupported */
    if (behavior == CASCADE) {
index 7331cfe796b0f13654435e87cb68faaab86ba07b..e7da9e5af5702fe991921244009010e362af3c0c 100644 (file)
@@ -46,7 +46,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.79 2002/03/02 21:39:25 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.80 2002/03/20 19:43:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -896,8 +896,7 @@ ExecInitAgg(Agg *node, EState *estate, Plan *parent)
             */
            Oid         inputType = exprType(aggref->target);
 
-           if (inputType != aggform->aggtranstype &&
-               !IS_BINARY_COMPATIBLE(inputType, aggform->aggtranstype))
+           if (!IsBinaryCompatible(inputType, aggform->aggtranstype))
                elog(ERROR, "Aggregate %s needs to have compatible input type and transition type",
                     aggname);
        }
index 070a6da5172a1b3f5f97dc5b1dbbc0cb42bdc0fe..ebdc7cf1165892dceef19391d751d470f0480302 100644 (file)
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.170 2002/03/19 02:18:16 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.171 2002/03/20 19:43:58 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2026,6 +2026,7 @@ _copyDropStmt(DropStmt *from)
 
    Node_Copy(from, newnode, names);
    newnode->removeType = from->removeType;
+   newnode->behavior = from->behavior;
 
    return newnode;
 }
@@ -2238,7 +2239,6 @@ _copyCreateDomainStmt(CreateDomainStmt *from)
 
    if (from->domainname)
        newnode->domainname = pstrdup(from->domainname);
-
    Node_Copy(from, newnode, typename);
    Node_Copy(from, newnode, constraints);
 
index f6f39f2f247eaf520221cfc2b2813e41ac41bba0..c7ed489e091dbd6e1bcd382657ac1c980e0578bd 100644 (file)
@@ -20,7 +20,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.118 2002/03/19 02:18:16 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.119 2002/03/20 19:44:01 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -878,6 +878,8 @@ _equalDropStmt(DropStmt *a, DropStmt *b)
        return false;
    if (a->removeType != b->removeType)
        return false;
+   if (a->behavior != b->behavior)
+       return false;
 
    return true;
 }
index d8f8310c5b7463dd0c83fc42b72bde8098af6973..36f8460b46c17c81d5123bb2c5609cc04e4de869 100644 (file)
@@ -8,16 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/nodes/makefuncs.c,v 1.26 2001/03/22 03:59:32 momjian Exp $
- *
- * NOTES
- *   Creator functions in POSTGRES 4.2 are generated automatically. Most of
- *   them are rarely used. Now we don't generate them any more. If you want
- *   one, you have to write it yourself.
- *
- * HISTORY
- *   AUTHOR            DATE            MAJOR EVENT
- *   Andrew Yu         Oct 20, 1994    file creation
+ *   $Header: /cvsroot/pgsql/src/backend/nodes/makefuncs.c,v 1.27 2002/03/20 19:44:04 tgl Exp $
  */
 #include "postgres.h"
 
@@ -184,3 +175,19 @@ makeAttr(char *relname, char *attname)
 
    return a;
 }
+
+/*
+ * makeRelabelType -
+ *   creates a RelabelType node
+ */
+RelabelType *
+makeRelabelType(Node *arg, Oid rtype, int32 rtypmod)
+{
+   RelabelType *r = makeNode(RelabelType);
+
+   r->arg = arg;
+   r->resulttype = rtype;
+   r->resulttypmod = rtypmod;
+
+   return r;
+}
index b07f0fb006669fa42919464f8067b7ebdc816ff9..3458c69f1b59a9bdef9c34ac701dacee311a5be0 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.113 2002/03/02 21:39:26 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.114 2002/03/20 19:44:09 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -900,9 +900,9 @@ indexable_operator(Expr *clause, Oid opclass, bool indexkey_on_left)
     */
    if (ltype == indexkeytype && rtype == indexkeytype)
        return InvalidOid;      /* no chance for a different operator */
-   if (ltype != indexkeytype && !IS_BINARY_COMPATIBLE(ltype, indexkeytype))
+   if (!IsBinaryCompatible(ltype, indexkeytype))
        return InvalidOid;
-   if (rtype != indexkeytype && !IS_BINARY_COMPATIBLE(rtype, indexkeytype))
+   if (!IsBinaryCompatible(rtype, indexkeytype))
        return InvalidOid;
 
    /*
index cc992c7f3a8f92a0030621c18333975fb1453423..8fb1426748fcf98143e92f2df29823f7c397c530 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.49 2002/03/19 02:18:17 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.50 2002/03/20 19:44:15 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -355,9 +355,9 @@ build_column_default(Relation rel, int attrno)
    Form_pg_attribute att_tup = rd_att->attrs[attrno - 1];
    Oid         atttype = att_tup->atttypid;
    int32       atttypmod = att_tup->atttypmod;
-   int16       typlen;
-   bool        typbyval;
-   Node       *expr;
+   int16       typlen = att_tup->attlen;
+   bool        typbyval = att_tup->attbyval;
+   Node       *expr = NULL;
 
    /*
     * Scan to see if relation has a default for this column.
@@ -371,110 +371,86 @@ build_column_default(Relation rel, int attrno)
        {
            if (attrno == defval[ndef].adnum)
            {
-               Oid         type_id;
-
                /*
                 * Found it, convert string representation to node tree.
                 */
                expr = stringToNode(defval[ndef].adbin);
-
-               /*
-                * Make sure the value is coerced to the target column
-                * type (might not be right type yet if it's not a
-                * constant!) This should match the parser's processing of
-                * non-defaulted expressions --- see
-                * updateTargetListEntry().
-                */
-               type_id = exprType(expr);
-
-               if (type_id != atttype)
-               {
-                   expr = CoerceTargetExpr(NULL, expr, type_id,
-                                           getBaseType(atttype), atttypmod);
-
-                   /*
-                    * This really shouldn't fail; should have checked the
-                    * default's type when it was created ...
-                    */
-                   if (expr == NULL)
-                       elog(ERROR, "Column \"%s\" is of type %s"
-                            " but default expression is of type %s"
-                            "\n\tYou will need to rewrite or cast the expression",
-                            NameStr(att_tup->attname),
-                            format_type_be(atttype),
-                            format_type_be(type_id));
-               }
-
-               /*
-                * If the column is a fixed-length type, it may need a
-                * length coercion as well as a type coercion.
-                */
-               expr = coerce_type_typmod(NULL, expr,
-                                         atttype, atttypmod);
-               return expr;
+               break;
            }
        }
    }
 
-   /*
-    * No per-column default, so look for a default for the type itself.
-    * If there isn't one, we generate a NULL constant of the correct
-    * type.
-    */
-   if (att_tup->attisset)
+   if (expr == NULL)
    {
        /*
-        * Set attributes are represented as OIDs no matter what the set
-        * element type is, and the element type's default is irrelevant
-        * too.
+        * No per-column default, so look for a default for the type itself.
         */
-       typlen = sizeof(Oid);
-       typbyval = true;
+       if (att_tup->attisset)
+       {
+           /*
+            * Set attributes are represented as OIDs no matter what the set
+            * element type is, and the element type's default is irrelevant
+            * too.
+            */
+           typlen = sizeof(Oid);
+           typbyval = true;
+       }
+       else
+       {
+           expr = get_typdefault(atttype);
+       }
+   }
 
+   if (expr == NULL)
+   {
+       /*
+        * No default anywhere, so generate a NULL constant.
+        */
        expr = (Node *) makeConst(atttype,
                                  typlen,
                                  (Datum) 0,
-                                 true,
+                                 true,         /* isnull */
                                  typbyval,
-                                 false,           /* not a set */
+                                 false,        /* not a set */
                                  false);
    }
    else
    {
-#ifdef _DROP_COLUMN_HACK__
-       if (COLUMN_IS_DROPPED(att_tup))
+       Oid         exprtype;
+
+       /*
+        * Make sure the value is coerced to the target column
+        * type (might not be right type yet if it's not a
+        * constant!)  This should match the parser's processing of
+        * non-defaulted expressions --- see
+        * updateTargetListEntry().
+        */
+       exprtype = exprType(expr);
+
+       if (exprtype != atttype)
        {
+           expr = CoerceTargetExpr(NULL, expr, exprtype,
+                                   atttype, atttypmod);
 
-           expr = (Node *) makeConst(atttype,
-                                     typlen,
-                                     (Datum) 0,
-                                     true,
-                                     typbyval,
-                                     false,           /* not a set */
-                                     false);
-       }
-       else
-#endif   /* _DROP_COLUMN_HACK__ */
-           expr = get_typdefault(atttype, atttypmod);
-
-       if (expr == NULL) {
-               expr = (Node *) makeConst(atttype,
-                                         typlen,
-                                         (Datum) 0,
-                                         true,
-                                         typbyval,
-                                         false,        /* not a set */
-                                         false);
+           /*
+            * This really shouldn't fail; should have checked the
+            * default's type when it was created ...
+            */
+           if (expr == NULL)
+               elog(ERROR, "Column \"%s\" is of type %s"
+                    " but default expression is of type %s"
+                    "\n\tYou will need to rewrite or cast the expression",
+                    NameStr(att_tup->attname),
+                    format_type_be(atttype),
+                    format_type_be(exprtype));
        }
-       get_typlenbyval(atttype, &typlen, &typbyval);
-   }
 
-   /*
-    * If the column is a fixed-length type, it may need a length coercion
-    * as well as a type coercion, as well as direction to the final type.
-    */
-   expr = coerce_type_typmod(NULL, expr,
-                             atttype, atttypmod);
+       /*
+        * If the column is a fixed-length type, it may need a
+        * length coercion as well as a type coercion.
+        */
+       expr = coerce_type_typmod(NULL, expr, atttype, atttypmod);
+   }
 
    return expr;
 }
index 1994875bd1c8a54f0c8b71426a834cacd7340e60..6951653ce8a352d7a98525ef1648d5fd55273353 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.293 2002/03/19 12:52:20 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.294 2002/03/20 19:44:21 tgl Exp $
  *
  * HISTORY
  *   AUTHOR            DATE            MAJOR EVENT
@@ -135,8 +135,7 @@ static void doNegateFloat(Value *v);
        ClosePortalStmt, ClusterStmt, CommentStmt, ConstraintsSetStmt,
        CopyStmt, CreateAsStmt, CreateDomainStmt, CreateGroupStmt, CreatePLangStmt,
        CreateSchemaStmt, CreateSeqStmt, CreateStmt, CreateTrigStmt,
-       CreateUserStmt, CreatedbStmt, CursorStmt,
-       DefineStmt, DeleteStmt,
+       CreateUserStmt, CreatedbStmt, CursorStmt, DefineStmt, DeleteStmt,
        DropGroupStmt, DropPLangStmt, DropSchemaStmt, DropStmt, DropTrigStmt,
        DropUserStmt, DropdbStmt, ExplainStmt, FetchStmt,
        GrantStmt, IndexStmt, InsertStmt, ListenStmt, LoadStmt, LockStmt,
@@ -151,7 +150,7 @@ static void doNegateFloat(Value *v);
                simple_select
 
 %type     alter_column_default
-%type     drop_behavior
+%type     drop_behavior, opt_drop_behavior
 
 %type    createdb_opt_list, createdb_opt_item
 %type     opt_equal
@@ -1181,6 +1180,10 @@ drop_behavior: CASCADE                   { $$ = CASCADE; }
        | RESTRICT                      { $$ = RESTRICT; }
         ;
 
+opt_drop_behavior: CASCADE             { $$ = CASCADE; }
+       | RESTRICT                      { $$ = RESTRICT; }
+       | /* EMPTY */                   { $$ = RESTRICT; /* default */ }
+        ;
 
 
 /*****************************************************************************
@@ -2030,22 +2033,13 @@ def_list:  def_elem                         { $$ = makeList1($1); }
        | def_list ',' def_elem             { $$ = lappend($1, $3); }
        ;
 
-def_elem:  DEFAULT '=' b_expr
-               {
-                   $$ = makeNode(DefElem);
-                   $$->defname = "default";
-                   if (exprIsNullConstant($3))
-                       $$->arg = (Node *)NULL;
-                   else
-                       $$->arg = $3;
-               }
-       | ColId '=' def_arg
+def_elem:  ColLabel '=' def_arg
                {
                    $$ = makeNode(DefElem);
                    $$->defname = $1;
                    $$->arg = (Node *)$3;
                }
-       | ColId
+       | ColLabel
                {
                    $$ = makeNode(DefElem);
                    $$->defname = $1;
@@ -2069,19 +2063,11 @@ def_arg:  func_return                   {  $$ = (Node *)$1; }
  *
  *****************************************************************************/
 
-DropStmt:  DROP drop_type name_list
+DropStmt:  DROP drop_type name_list opt_drop_behavior
                {
                    DropStmt *n = makeNode(DropStmt);
                    n->removeType = $2;
                    n->names = $3;
-                   n->behavior = RESTRICT;     /* Restricted by default */
-                   $$ = (Node *)n;
-               }
-       | DROP DOMAIN_P name_list drop_behavior
-               {   
-                   DropStmt *n = makeNode(DropStmt);
-                   n->removeType = DROP_DOMAIN_P;
-                   n->names = $3;
                    n->behavior = $4;
                    $$ = (Node *)n;
                }
@@ -2092,7 +2078,8 @@ drop_type: TABLE                              { $$ = DROP_TABLE; }
        | VIEW                                  { $$ = DROP_VIEW; }
        | INDEX                                 { $$ = DROP_INDEX; }
        | RULE                                  { $$ = DROP_RULE; }
-       | TYPE_P                                { $$ = DROP_TYPE_P; }
+       | TYPE_P                                { $$ = DROP_TYPE; }
+       | DOMAIN_P                              { $$ = DROP_DOMAIN; }
        ;
 
 /*****************************************************************************
@@ -3194,12 +3181,19 @@ createdb_opt_item:  LOCATION opt_equal Sconst
                }
        ;
 
+/*
+ * Though the equals sign doesn't match other WITH options, pg_dump uses
+ *  equals for backward compability, and it doesn't seem worth remove it.
+ */
+opt_equal: '='                             { $$ = TRUE; }
+       | /*EMPTY*/                         { $$ = FALSE; }
+       ;
+
 
 /*****************************************************************************
  *
  *     DROP DATABASE
  *
- *
  *****************************************************************************/
 
 DropdbStmt:    DROP DATABASE database_name
@@ -3210,20 +3204,11 @@ DropdbStmt: DROP DATABASE database_name
                }
        ;
 
-/*
- * Though the equals sign doesn't match other WITH options, pg_dump uses
- *  equals for backward compability, and it doesn't seem worth remove it.
- */
-opt_equal: '='                             { $$ = TRUE; }
-       | /*EMPTY*/                         { $$ = FALSE; }
-       ;
-
 
 /*****************************************************************************
  *
  *     ALTER DATABASE
  *
- *
  *****************************************************************************/
 
 AlterDatabaseSetStmt: ALTER DATABASE database_name VariableSetStmt
index 7aaaa65c61bfa0068818d128ef3f744495299b47..690a047915ac202cfb32e4aabe6fe99cd1c288a5 100644 (file)
@@ -8,25 +8,31 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.67 2002/03/19 02:18:20 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.68 2002/03/20 19:44:22 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "postgres.h"
 
 #include "catalog/pg_proc.h"
+#include "nodes/makefuncs.h"
 #include "optimizer/clauses.h"
 #include "parser/parse_coerce.h"
 #include "parser/parse_expr.h"
 #include "parser/parse_func.h"
 #include "parser/parse_type.h"
 #include "utils/builtins.h"
+#include "utils/lsyscache.h"
 #include "utils/syscache.h"
 
+
 Oid            DemoteType(Oid inType);
 Oid            PromoteTypeToNext(Oid inType);
 
 static Oid PreferredType(CATEGORY category, Oid type);
+static Node *build_func_call(Oid funcid, Oid rettype, List *args);
+static Oid find_coercion_function(Oid targetTypeId, Oid inputTypeId,
+                                  Oid secondArgType);
 
 
 /* coerce_type()
@@ -87,32 +93,28 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId,
 
        result = (Node *) newcon;
    }
-   else if (IS_BINARY_COMPATIBLE(inputTypeId, targetTypeId))
+   else if (IsBinaryCompatible(inputTypeId, targetTypeId))
    {
        /*
         * We don't really need to do a conversion, but we do need to
         * attach a RelabelType node so that the expression will be seen
         * to have the intended type when inspected by higher-level code.
-        */
-       RelabelType *relabel = makeNode(RelabelType);
-
-       relabel->arg = node;
-       relabel->resulttype = targetTypeId;
-
-       /*
+        *
         * XXX could we label result with exprTypmod(node) instead of
         * default -1 typmod, to save a possible length-coercion later?
         * Would work if both types have same interpretation of typmod,
         * which is likely but not certain.
         */
-       relabel->resulttypmod = -1;
-
-       result = (Node *) relabel;
+       result = (Node *) makeRelabelType(node, targetTypeId, -1);
    }
    else if (typeInheritsFrom(inputTypeId, targetTypeId))
    {
-       /* Input class type is a subclass of target, so nothing to do */
-       result = node;
+       /*
+        * Input class type is a subclass of target, so nothing to do
+        * --- except relabel the type.  This is binary compatibility
+        * for complex types.
+        */
+       result = (Node *) makeRelabelType(node, targetTypeId, -1);
    }
    else
    {
@@ -121,21 +123,24 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId,
         * (caller should have determined that there is one), and generate
         * an expression tree representing run-time application of the
         * conversion function.
+        *
+        * For domains, we use the coercion function for the base type.
         */
-       FuncCall   *n = makeNode(FuncCall);
+       Oid         baseTypeId = getBaseType(targetTypeId);
+       Oid         funcId;
 
-       n->funcname = typeidTypeName(targetTypeId);
-       n->args = makeList1(node);
-       n->agg_star = false;
-       n->agg_distinct = false;
+       funcId = find_coercion_function(baseTypeId,
+                                       getBaseType(inputTypeId),
+                                       InvalidOid);
+       if (!OidIsValid(funcId))
+           elog(ERROR, "coerce_type: no conversion function from %s to %s",
+                format_type_be(inputTypeId), format_type_be(targetTypeId));
 
-       result = transformExpr(pstate, (Node *) n, EXPR_COLUMN_FIRST);
+       result = build_func_call(funcId, baseTypeId, makeList1(node));
 
-       /* safety check that we got the right thing */
-       if (exprType(result) != targetTypeId)
-           elog(ERROR, "coerce_type: conversion function %s produced %s",
-                typeidTypeName(targetTypeId),
-                typeidTypeName(exprType(result)));
+       /* if domain, relabel with domain type ID */
+       if (targetTypeId != baseTypeId)
+           result = (Node *) makeRelabelType(result, targetTypeId, -1);
 
        /*
         * If the input is a constant, apply the type conversion function
@@ -152,7 +157,8 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId,
         * nodes that mustn't be collapsed.  (It'd be a lot cleaner to
         * make a separate node type for that purpose...)
         */
-       if (IsA(node, Const) &&!((Const *) node)->constisnull)
+       if (IsA(node, Const) &&
+           !((Const *) node)->constisnull)
            result = eval_const_expressions(result);
    }
 
@@ -169,23 +175,18 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId,
  *
  * Notes:
  * This uses the same mechanism as the CAST() SQL construct in gram.y.
- * We should also check the function return type on candidate conversion
- * routines just to be safe but we do not do that yet...
- * - thomas 1998-03-31
  */
 bool
 can_coerce_type(int nargs, Oid *input_typeids, Oid *func_typeids)
 {
    int         i;
-   HeapTuple   ftup;
-   Form_pg_proc pform;
-   Oid         oid_array[FUNC_MAX_ARGS];
 
    /* run through argument list... */
    for (i = 0; i < nargs; i++)
    {
        Oid         inputTypeId = input_typeids[i];
        Oid         targetTypeId = func_typeids[i];
+       Oid         funcId;
 
        /* no problem if same type */
        if (inputTypeId == targetTypeId)
@@ -195,7 +196,7 @@ can_coerce_type(int nargs, Oid *input_typeids, Oid *func_typeids)
         * one of the known-good transparent conversions? then drop
         * through...
         */
-       if (IS_BINARY_COMPATIBLE(inputTypeId, targetTypeId))
+       if (IsBinaryCompatible(inputTypeId, targetTypeId))
            continue;
 
        /* don't know what to do for the output type? then quit... */
@@ -232,25 +233,14 @@ can_coerce_type(int nargs, Oid *input_typeids, Oid *func_typeids)
         * Else, try for explicit conversion using functions: look for a
         * single-argument function named with the target type name and
         * accepting the source type.
+        *
+        * If either type is a domain, use its base type instead.
         */
-       MemSet(oid_array, 0, FUNC_MAX_ARGS * sizeof(Oid));
-       oid_array[0] = inputTypeId;
-
-       ftup = SearchSysCache(PROCNAME,
-                          PointerGetDatum(typeidTypeName(targetTypeId)),
-                             Int32GetDatum(1),
-                             PointerGetDatum(oid_array),
-                             0);
-       if (!HeapTupleIsValid(ftup))
-           return false;
-       /* Make sure the function's result type is as expected, too */
-       pform = (Form_pg_proc) GETSTRUCT(ftup);
-       if (pform->prorettype != targetTypeId)
-       {
-           ReleaseSysCache(ftup);
+       funcId = find_coercion_function(getBaseType(targetTypeId),
+                                       getBaseType(inputTypeId),
+                                       InvalidOid);
+       if (!OidIsValid(funcId))
            return false;
-       }
-       ReleaseSysCache(ftup);
    }
 
    return true;
@@ -277,8 +267,8 @@ Node *
 coerce_type_typmod(ParseState *pstate, Node *node,
                   Oid targetTypeId, int32 atttypmod)
 {
-   char       *funcname;
-   Oid         oid_array[FUNC_MAX_ARGS];
+   Oid         baseTypeId;
+   Oid         funcId;
 
    /*
     * A negative typmod is assumed to mean that no coercion is wanted.
@@ -286,30 +276,28 @@ coerce_type_typmod(ParseState *pstate, Node *node,
    if (atttypmod < 0 || atttypmod == exprTypmod(node))
        return node;
 
-   funcname = typeidTypeName(targetTypeId);
-   MemSet(oid_array, 0, FUNC_MAX_ARGS * sizeof(Oid));
-   oid_array[0] = targetTypeId;
-   oid_array[1] = INT4OID;
-
-   /* attempt to find with arguments exactly as specified... */
-   if (SearchSysCacheExists(PROCNAME,
-                            PointerGetDatum(funcname),
-                            Int32GetDatum(2),
-                            PointerGetDatum(oid_array),
-                            0))
+   /* If given type is a domain, use base type instead */
+   baseTypeId = getBaseType(targetTypeId);
+
+   funcId = find_coercion_function(baseTypeId, baseTypeId, INT4OID);
+
+   if (OidIsValid(funcId))
    {
-       A_Const    *cons = makeNode(A_Const);
-       FuncCall   *func = makeNode(FuncCall);
+       Const      *cons;
 
-       cons->val.type = T_Integer;
-       cons->val.val.ival = atttypmod;
+       cons = makeConst(INT4OID,
+                        sizeof(int32),
+                        Int32GetDatum(atttypmod),
+                        false,
+                        true,
+                        false,
+                        false);
 
-       func->funcname = funcname;
-       func->args = makeList2(node, cons);
-       func->agg_star = false;
-       func->agg_distinct = false;
+       node = build_func_call(funcId, baseTypeId, makeList2(node, cons));
 
-       node = transformExpr(pstate, (Node *) func, EXPR_COLUMN_FIRST);
+       /* relabel if it's domain case */
+       if (targetTypeId != baseTypeId)
+           node = (Node *) makeRelabelType(node, targetTypeId, atttypmod);
    }
 
    return node;
@@ -532,6 +520,64 @@ TypeCategory(Oid inType)
 }  /* TypeCategory() */
 
 
+/* IsBinaryCompatible()
+ *     Check if two types are binary-compatible.
+ *
+ * This notion allows us to cheat and directly exchange values without
+ * going through the trouble of calling a conversion function.
+ *
+ * XXX This should be moved to system catalog lookups
+ * to allow for better type extensibility.
+ */
+
+/*
+ * This macro describes hard-coded knowledge of binary compatibility
+ * for built-in types.
+ */
+#define IS_BINARY_COMPATIBLE(a,b) \
+         (((a) == BPCHAROID && (b) == TEXTOID) \
+       || ((a) == BPCHAROID && (b) == VARCHAROID) \
+       || ((a) == VARCHAROID && (b) == TEXTOID) \
+       || ((a) == VARCHAROID && (b) == BPCHAROID) \
+       || ((a) == TEXTOID && (b) == BPCHAROID) \
+       || ((a) == TEXTOID && (b) == VARCHAROID) \
+       || ((a) == OIDOID && (b) == INT4OID) \
+       || ((a) == OIDOID && (b) == REGPROCOID) \
+       || ((a) == INT4OID && (b) == OIDOID) \
+       || ((a) == INT4OID && (b) == REGPROCOID) \
+       || ((a) == REGPROCOID && (b) == OIDOID) \
+       || ((a) == REGPROCOID && (b) == INT4OID) \
+       || ((a) == ABSTIMEOID && (b) == INT4OID) \
+       || ((a) == INT4OID && (b) == ABSTIMEOID) \
+       || ((a) == RELTIMEOID && (b) == INT4OID) \
+       || ((a) == INT4OID && (b) == RELTIMEOID) \
+       || ((a) == INETOID && (b) == CIDROID) \
+       || ((a) == CIDROID && (b) == INETOID) \
+       || ((a) == BITOID && (b) == VARBITOID) \
+       || ((a) == VARBITOID && (b) == BITOID))
+
+bool
+IsBinaryCompatible(Oid type1, Oid type2)
+{
+   if (type1 == type2)
+       return true;
+   if (IS_BINARY_COMPATIBLE(type1, type2))
+       return true;
+   /*
+    * Perhaps the types are domains; if so, look at their base types
+    */
+   if (OidIsValid(type1))
+       type1 = getBaseType(type1);
+   if (OidIsValid(type2))
+       type2 = getBaseType(type2);
+   if (type1 == type2)
+       return true;
+   if (IS_BINARY_COMPATIBLE(type1, type2))
+       return true;
+   return false;
+}
+
+
 /* IsPreferredType()
  * Check if this type is a preferred type.
  * XXX This should be moved to system catalog lookups
@@ -606,31 +652,81 @@ PreferredType(CATEGORY category, Oid type)
    return result;
 }  /* PreferredType() */
 
-
 /*
- * If the targetTypeId is a domain, we really want to coerce
- * the tuple to the domain type -- not the domain itself
+ * find_coercion_function
+ *     Look for a coercion function between two types.
+ *
+ * A coercion function must be named after (the internal name of) its
+ * result type, and must accept exactly the specified input type.
+ *
+ * This routine is also used to look for length-coercion functions, which
+ * are similar but accept a second argument.  secondArgType is the type
+ * of the second argument (normally INT4OID), or InvalidOid if we are
+ * looking for a regular coercion function.
+ *
+ * If a function is found, return its pg_proc OID; else return InvalidOid.
  */
-Oid
-getBaseType(Oid inType)
+static Oid
+find_coercion_function(Oid targetTypeId, Oid inputTypeId, Oid secondArgType)
 {
-   HeapTuple   tup;
-   Form_pg_type typTup;
+   char       *funcname;
+   Oid         oid_array[FUNC_MAX_ARGS];
+   int         nargs;
+   HeapTuple   ftup;
+   Form_pg_proc pform;
+   Oid         funcid;
 
-   tup = SearchSysCache(TYPEOID,
-                        ObjectIdGetDatum(inType),
-                        0, 0, 0);
+   funcname = typeidTypeName(targetTypeId);
+   MemSet(oid_array, 0, FUNC_MAX_ARGS * sizeof(Oid));
+   oid_array[0] = inputTypeId;
+   if (OidIsValid(secondArgType))
+   {
+       oid_array[1] = secondArgType;
+       nargs = 2;
+   }
+   else
+       nargs = 1;
+
+   ftup = SearchSysCache(PROCNAME,
+                         PointerGetDatum(funcname),
+                         Int32GetDatum(nargs),
+                         PointerGetDatum(oid_array),
+                         0);
+   if (!HeapTupleIsValid(ftup))
+       return InvalidOid;
+   /* Make sure the function's result type is as expected, too */
+   pform = (Form_pg_proc) GETSTRUCT(ftup);
+   if (pform->prorettype != targetTypeId)
+   {
+       ReleaseSysCache(ftup);
+       return InvalidOid;
+   }
+   funcid = ftup->t_data->t_oid;
+   ReleaseSysCache(ftup);
+   return funcid;
+}
 
-   typTup = ((Form_pg_type) GETSTRUCT(tup));
+/*
+ * Build an expression tree representing a function call.
+ *
+ * The argument expressions must have been transformed already.
+ */
+static Node *
+build_func_call(Oid funcid, Oid rettype, List *args)
+{
+   Func       *funcnode;
+   Expr       *expr;
 
-   /*
-    * Assume that typbasetype exists and is a base type, where inType
-    * was a domain
-    */
-   if (typTup->typtype == 'd')
-       inType = typTup->typbasetype;
+   funcnode = makeNode(Func);
+   funcnode->funcid = funcid;
+   funcnode->functype = rettype;
+   funcnode->func_fcache = NULL;
 
-   ReleaseSysCache(tup);
+   expr = makeNode(Expr);
+   expr->typeOid = rettype;
+   expr->opType = FUNC_EXPR;
+   expr->oper = (Node *) funcnode;
+   expr->args = args;
 
-   return inType;
+   return (Node *) expr;
 }
index 5cbc26f5cbec3ab64cd93c7149559e97e57e85a8..6409ef3226a0f5725dad09cad950425d1f696cc4 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.109 2002/03/19 02:18:20 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.110 2002/03/20 19:44:25 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1027,8 +1027,7 @@ parser_typecast_expression(ParseState *pstate,
    if (inputType != targetType)
    {
        expr = CoerceTargetExpr(pstate, expr, inputType,
-                               getBaseType(targetType),
-                               typename->typmod);
+                               targetType, typename->typmod);
        if (expr == NULL)
            elog(ERROR, "Cannot cast type '%s' to '%s'",
                 format_type_be(inputType),
@@ -1040,7 +1039,7 @@ parser_typecast_expression(ParseState *pstate,
     * as well as a type coercion.
     */
    expr = coerce_type_typmod(pstate, expr,
-                             getBaseType(targetType), typename->typmod);
+                             targetType, typename->typmod);
 
    return expr;
 }
index ed39d6c1036c8e02034e81311994ba690779fd8d..6dc7b440fa87e9e488d59bc9b2b30e391d8b83a7 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.117 2002/03/12 00:51:55 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.118 2002/03/20 19:44:29 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -575,8 +575,7 @@ agg_select_candidate(Oid typeid, CandidateList candidates)
    {
        current_typeid = current_candidate->args[0];
 
-       if (current_typeid == typeid
-           || IS_BINARY_COMPATIBLE(current_typeid, typeid))
+       if (IsBinaryCompatible(current_typeid, typeid))
        {
            last_candidate = current_candidate;
            ncandidates++;
@@ -815,9 +814,7 @@ func_select_candidate(int nargs,
        {
            if (input_typeids[i] != UNKNOWNOID)
            {
-               if (current_typeids[i] == input_typeids[i] ||
-                   IS_BINARY_COMPATIBLE(current_typeids[i],
-                                        input_typeids[i]))
+               if (IsBinaryCompatible(current_typeids[i], input_typeids[i]))
                    nmatch++;
            }
        }
@@ -1115,8 +1112,7 @@ func_get_detail(char *funcname,
                Node       *arg1 = lfirst(fargs);
 
                if ((sourceType == UNKNOWNOID && IsA(arg1, Const)) ||
-                   sourceType == targetType ||
-                   IS_BINARY_COMPATIBLE(sourceType, targetType))
+                   IsBinaryCompatible(sourceType, targetType))
                {
                    /* Yup, it's a type coercion */
                    *funcid = InvalidOid;
index 318f1b9eb7e26f6bc2a23b01205437a6c7de6d0d..8495f9f9e65df053eccc72821e4c40e5fe88a207 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.52 2002/02/19 20:11:15 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.53 2002/03/20 19:44:31 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -354,9 +354,7 @@ oper_select_candidate(int nargs,
        {
            if (input_typeids[i] != UNKNOWNOID)
            {
-               if (current_typeids[i] == input_typeids[i] ||
-                   IS_BINARY_COMPATIBLE(current_typeids[i],
-                                        input_typeids[i]))
+               if (IsBinaryCompatible(current_typeids[i], input_typeids[i]))
                    nmatch++;
            }
        }
@@ -736,10 +734,8 @@ compatible_oper(char *op, Oid arg1, Oid arg2, bool noError)
 
    /* but is it good enough? */
    opform = (Form_pg_operator) GETSTRUCT(optup);
-   if ((opform->oprleft == arg1 ||
-        IS_BINARY_COMPATIBLE(opform->oprleft, arg1)) &&
-       (opform->oprright == arg2 ||
-        IS_BINARY_COMPATIBLE(opform->oprright, arg2)))
+   if (IsBinaryCompatible(opform->oprleft, arg1) &&
+       IsBinaryCompatible(opform->oprright, arg2))
        return optup;
 
    /* nope... */
index 0c1ead0331c78d100a10cd95a8a9287f2f4e1580..db8d440034f8d95a6d49e203b4960ec38f686101 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.134 2002/03/19 02:58:19 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.135 2002/03/20 19:44:35 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -276,12 +276,12 @@ ProcessUtility(Node *parsetree,
                            }
                            break;
 
-                       case DROP_TYPE_P:
+                       case DROP_TYPE:
                            /* RemoveType does its own permissions checks */
                            RemoveType(relname);
                            break;
 
-                       case DROP_DOMAIN_P:
+                       case DROP_DOMAIN:
                            /* RemoveDomain does its own permissions checks */
                            RemoveDomain(relname, stmt->behavior);
                            break;
index fc8733e960cf7a4d0b04957a18792685ea79cec3..c85d7ea08842cfab8c9a13d6133a43024eaf77b6 100644 (file)
@@ -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);
index 760e07ce5e6b7b03b36f128d61ef234b93b28ac6..f4ebb6261c28203ebe77ad9ce46bfdb95ebb95fa 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.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;
 }
 
 /*
index c45b81c7a8297612ff60ef4111b6b5b3ca5769b5..0c6f5441cad25bd02ff7f2755c646180d64c26e5 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright 2000 by PostgreSQL Global Development Group
  *
- * $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.46 2002/03/19 02:32:21 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.47 2002/03/20 19:44:45 tgl Exp $
  */
 #include "postgres_fe.h"
 #include "describe.h"
@@ -1053,7 +1053,7 @@ listDomains(const char *name)
 
    snprintf(buf, sizeof(buf),
         "SELECT t.typname as \"%s\",\n"
-        "       format_type( t.typbasetype, t.typmod) as \"%s\",\n"
+        "       format_type( t.typbasetype, t.typtypmod) as \"%s\",\n"
         "       CASE WHEN t.typnotnull AND t.typdefault IS NOT NULL THEN 'not null default '||t.typdefault\n"
         "            WHEN t.typnotnull AND t.typdefault IS NULL THEN 'not null'\n"
         "            WHEN NOT t.typnotnull AND t.typdefault IS NOT NULL THEN 'default '||t.typdefault\n"
index 882a29246fe45b207a3276b0d0f72c4b0cf7a828..a049a2393584e8d191fcec051b65bfebdaba8bff 100644 (file)
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: catversion.h,v 1.106 2002/03/12 00:51:59 tgl Exp $
+ * $Id: catversion.h,v 1.107 2002/03/20 19:44:48 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*                         yyyymmddN */
-#define CATALOG_VERSION_NO 200203111
+#define CATALOG_VERSION_NO 200203191
 
 #endif
index 4298f53bdc4a743db1658cd591273f3c10f65e6e..b2bcfb71bdcc463c8044e12d8c32871de9d48e50 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: heap.h,v 1.45 2002/03/19 02:58:19 momjian Exp $
+ * $Id: heap.h,v 1.46 2002/03/20 19:44:52 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -47,11 +47,11 @@ extern void AddRelationRawConstraints(Relation rel,
                          List *rawColDefaults,
                          List *rawConstraints);
 
-extern Node *cookDefault(ParseState *pstate
-                       , Node *raw_default
-                       , Oid atttypid
-                       , int32 atttypmod
-                       , char *attname);
+extern Node *cookDefault(ParseState *pstate,
+                        Node *raw_default,
+                        Oid atttypid,
+                        int32 atttypmod,
+                        char *attname);
 
 extern int RemoveCheckConstraint(Relation rel, const char *constrName, bool inh);
 
index 6efbe3223a36cf2cb68f31198f043541fc8429d8..df7cec839744fcd71cb7d51977fcaed9faad9f84 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_attribute.h,v 1.84 2002/03/19 02:18:22 momjian Exp $
+ * $Id: pg_attribute.h,v 1.85 2002/03/20 19:44:55 tgl Exp $
  *
  * NOTES
  *   the genbki.sh script reads this file and generates .bki
@@ -241,8 +241,8 @@ typedef FormData_pg_attribute *Form_pg_attribute;
 { 1247, {"typalign"},     18, 0,   1, 15, 0, -1, -1, true, 'p', false, 'c', false, false }, \
 { 1247, {"typstorage"},    18, 0,  1, 16, 0, -1, -1, true, 'p', false, 'c', false, false }, \
 { 1247, {"typnotnull"},    16, 0,   1, 17, 0, -1, -1, true, 'p', false, 'c', false, false }, \
-{ 1247, {"typmod"},        23, 0,  4, 18, 0, -1, -1, true, 'p', false, 'i', false, false }, \
-{ 1247, {"typbasetype"},   26, 0,  4, 19, 0, -1, -1, true, 'p', false, 'i', false, false }, \
+{ 1247, {"typbasetype"},   26, 0,  4, 18, 0, -1, -1, true, 'p', false, 'i', false, false }, \
+{ 1247, {"typtypmod"},     23, 0,  4, 19, 0, -1, -1, true, 'p', false, 'i', false, false }, \
 { 1247, {"typndims"},      23, 0,  4, 20, 0, -1, -1, true, 'p', false, 'i', false, false }, \
 { 1247, {"typdefaultbin"}, 25, 0,  -1, 21, 0, -1, -1, false, 'x', false, 'i', false, false }, \
 { 1247, {"typdefault"},    25, 0,  -1, 22, 0, -1, -1, false, 'x', false, 'i', false, false }
@@ -265,8 +265,8 @@ DATA(insert ( 1247 typsend          24 0  4  14 0 -1 -1 t p f i f f));
 DATA(insert ( 1247 typalign            18 0  1  15 0 -1 -1 t p f c f f));
 DATA(insert ( 1247 typstorage      18 0  1  16 0 -1 -1 t p f c f f));
 DATA(insert ( 1247 typnotnull      16 0  1  17 0 -1 -1 t p f c f f));
-DATA(insert ( 1247 typmod          23 0  4  18 0 -1 -1 t p f i f f));
-DATA(insert ( 1247 typbasetype     26 0  4  19 0 -1 -1 t p f i f f));
+DATA(insert ( 1247 typbasetype     26 0  4  18 0 -1 -1 t p f i f f));
+DATA(insert ( 1247 typtypmod       23 0  4  19 0 -1 -1 t p f i f f));
 DATA(insert ( 1247 typndims            23 0  4  20 0 -1 -1 t p f i f f));
 DATA(insert ( 1247 typdefaultbin   25 0 -1  21 0 -1 -1 f x f i f f));
 DATA(insert ( 1247 typdefault      25 0 -1  22 0 -1 -1 f x f i f f));
index 9aaea0cb3b1a9b0c3d351242a3f3afeb495fe805..d1d2c02f7819a922b6fc94bb0fb631c9d20a5f4c 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.117 2002/03/19 02:18:23 momjian Exp $
+ * $Id: pg_type.h,v 1.118 2002/03/20 19:44:57 tgl Exp $
  *
  * NOTES
  *   the genbki.sh script reads this file and generates .bki
@@ -151,36 +151,41 @@ CATALOG(pg_type) BOOTSTRAP
    bool        typnotnull;
 
    /*
-    * typmod records type-specific data supplied at domain creation
-    * time (for example, the max length of a varchar field).  It is
-    * passed to type-specific input and output functions as the third
-    * argument. The value will generally be -1 for types that do not need
-    * typmod.  This value is copied to pg_attribute.atttypmod.
+    * Domains use typbasetype to show the base (or complex) type that
+    * the domain is based on.  Zero if the type is not a domain.
     */
-   int4        typmod;
+   Oid         typbasetype;
 
    /*
-    * Domains use typbasetype to determine the base (or complex)type that
-    * the domain is based off.  It must be non-zero if the type is a
-    * domain.
+    * typtypmod records type-specific data supplied at domain creation
+    * time (for example, the max length of a varchar field).  It is
+    * passed to type-specific input and output functions as the third
+    * argument. The value will generally be -1 for types that do not need
+    * typmod.  This value is copied to pg_attribute.atttypmod when
+    * creating a column of a domain type.
     */
-   Oid         typbasetype;
+   int4        typtypmod;
 
    /*
-    * typndims is the declared number of dimensions, if an array typbasetype,
-    * otherwise zero.
+    * typndims is the declared number of dimensions for a domain type that
+    * is an array (with element type typbasetype).  Otherwise zero.
     */
    int4        typndims;
 
    /*
-    * typdefaultbin is the binary representation of typdefault
+    * If typdefaultbin is not NULL, it is the nodeToString representation
+    * of a default expression for the type.  Currently this is only used
+    * for domains.
     */
    text        typdefaultbin;  /* VARIABLE LENGTH FIELD */
 
    /*
     * 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
+    * typdefaultbin is not NULL, typdefault must contain a human-readable
+    * version of the default expression represented by typdefaultbin.
+    * If typdefaultbin is NULL and typdefault is not, then typdefault is
+    * the external representation of the type's default value, which may
+    * be fed to the type's input converter to produce a constant.
     */
    text        typdefault;     /* VARIABLE LENGTH FIELD */
 
@@ -215,8 +220,8 @@ typedef FormData_pg_type *Form_pg_type;
 #define Anum_pg_type_typalign          15
 #define Anum_pg_type_typstorage            16
 #define Anum_pg_type_typnotnull            17
-#define Anum_pg_type_typmod                18
-#define Anum_pg_type_typbasetype       19
+#define Anum_pg_type_typbasetype       18
+#define Anum_pg_type_typtypmod         19
 #define Anum_pg_type_typndims          20
 #define Anum_pg_type_typdefaultbin     21
 #define Anum_pg_type_typdefault            22
@@ -235,82 +240,82 @@ typedef FormData_pg_type *Form_pg_type;
 */
 
 /* OIDS 1 - 99 */
-DATA(insert OID = 16 ( bool       PGUID  1   1 t b t \054 0   0 boolin boolout boolin boolout c p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 16 ( bool       PGUID  1   1 t b t \054 0   0 boolin boolout boolin boolout c p f 0 -1 0 _null_ _null_ ));
 DESCR("boolean, 'true'/'false'");
 #define BOOLOID            16
 
-DATA(insert OID = 17 ( bytea      PGUID -1  -1 f b t \054 0  0 byteain byteaout byteain byteaout i x f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 17 ( bytea      PGUID -1  -1 f b t \054 0  0 byteain byteaout byteain byteaout i x f 0 -1 0 _null_ _null_ ));
 DESCR("variable-length string, binary values escaped");
 #define BYTEAOID       17
 
-DATA(insert OID = 18 ( char       PGUID  1   1 t b t \054 0   0 charin charout charin charout c p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 18 ( char       PGUID  1   1 t b t \054 0   0 charin charout charin charout c p f 0 -1 0 _null_ _null_ ));
 DESCR("single character");
 #define CHAROID            18
 
-DATA(insert OID = 19 ( name       PGUID NAMEDATALEN NAMEDATALEN  f b t \054 0  18 namein nameout namein nameout i p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 19 ( name       PGUID NAMEDATALEN NAMEDATALEN  f b t \054 0  18 namein nameout namein nameout i p f 0 -1 0 _null_ _null_ ));
 DESCR("31-character type for storing system identifiers");
 #define NAMEOID            19
 
-DATA(insert OID = 20 ( int8       PGUID  8  20 f b t \054 0   0 int8in int8out int8in int8out d p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 20 ( int8       PGUID  8  20 f b t \054 0   0 int8in int8out int8in int8out d p f 0 -1 0 _null_ _null_ ));
 DESCR("~18 digit integer, 8-byte storage");
 #define INT8OID            20
 
-DATA(insert OID = 21 ( int2       PGUID  2   5 t b t \054 0   0 int2in int2out int2in int2out s p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 21 ( int2       PGUID  2   5 t b t \054 0   0 int2in int2out int2in int2out s p f 0 -1 0 _null_ _null_ ));
 DESCR("-32 thousand to 32 thousand, 2-byte storage");
 #define INT2OID            21
 
-DATA(insert OID = 22 ( int2vector PGUID INDEX_MAX_KEYS*2 -1 f b t \054 0  21 int2vectorin int2vectorout int2vectorin int2vectorout i p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 22 ( int2vector PGUID INDEX_MAX_KEYS*2 -1 f b t \054 0  21 int2vectorin int2vectorout int2vectorin int2vectorout i p f 0 -1 0 _null_ _null_ ));
 DESCR("array of INDEX_MAX_KEYS int2 integers, used in system tables");
 #define INT2VECTOROID  22
 
-DATA(insert OID = 23 ( int4       PGUID  4  10 t b t \054 0   0 int4in int4out int4in int4out i p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 23 ( int4       PGUID  4  10 t b t \054 0   0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ ));
 DESCR("-2 billion to 2 billion integer, 4-byte storage");
 #define INT4OID            23
 
-DATA(insert OID = 24 ( regproc    PGUID  4  16 t b t \054 0   0 regprocin regprocout regprocin regprocout i p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 24 ( regproc    PGUID  4  16 t b t \054 0   0 regprocin regprocout regprocin regprocout i p f 0 -1 0 _null_ _null_ ));
 DESCR("registered procedure");
 #define REGPROCOID     24
 
-DATA(insert OID = 25 ( text       PGUID -1  -1 f b t \054 0  0 textin textout textin textout i x f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 25 ( text       PGUID -1  -1 f b t \054 0  0 textin textout textin textout i x f 0 -1 0 _null_ _null_ ));
 DESCR("variable-length string, no limit specified");
 #define TEXTOID            25
 
-DATA(insert OID = 26 ( oid        PGUID  4  10 t b t \054 0   0 oidin oidout oidin oidout i p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 26 ( oid        PGUID  4  10 t b t \054 0   0 oidin oidout oidin oidout i p f 0 -1 0 _null_ _null_ ));
 DESCR("object identifier(oid), maximum 4 billion");
 #define OIDOID         26
 
-DATA(insert OID = 27 ( tid        PGUID  6  19 f b t \054 0   0 tidin tidout tidin tidout i p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 27 ( tid        PGUID  6  19 f b t \054 0   0 tidin tidout tidin tidout i p f 0 -1 0 _null_ _null_ ));
 DESCR("(Block, offset), physical location of tuple");
 #define TIDOID     27
 
-DATA(insert OID = 28 ( xid        PGUID  4  12 t b t \054 0   0 xidin xidout xidin xidout i p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 28 ( xid        PGUID  4  12 t b t \054 0   0 xidin xidout xidin xidout i p f 0 -1 0 _null_ _null_ ));
 DESCR("transaction id");
 #define XIDOID 28
 
-DATA(insert OID = 29 ( cid        PGUID  4  10 t b t \054 0   0 cidin cidout cidin cidout i p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 29 ( cid        PGUID  4  10 t b t \054 0   0 cidin cidout cidin cidout i p f 0 -1 0 _null_ _null_ ));
 DESCR("command identifier type, sequence in transaction id");
 #define CIDOID 29
 
-DATA(insert OID = 30 ( oidvector  PGUID INDEX_MAX_KEYS*4 -1 f b t \054 0  26 oidvectorin oidvectorout oidvectorin oidvectorout i p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 30 ( oidvector  PGUID INDEX_MAX_KEYS*4 -1 f b t \054 0  26 oidvectorin oidvectorout oidvectorin oidvectorout i p f 0 -1 0 _null_ _null_ ));
 DESCR("array of INDEX_MAX_KEYS oids, used in system tables");
 #define OIDVECTOROID   30
 
-DATA(insert OID = 32 ( SET        PGUID -1  -1 f b t \054 0   0 textin textout textin textout i p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 32 ( SET        PGUID -1  -1 f b t \054 0   0 textin textout textin textout i p f 0 -1 0 _null_ _null_ ));
 DESCR("set of tuples");
 
-DATA(insert OID = 71 ( pg_type      PGUID 4 4 t c t \054 1247 0 int4in int4out int4in int4out i p f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 75 ( pg_attribute PGUID 4 4 t c t \054 1249 0 int4in int4out int4in int4out i p f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 81 ( pg_proc      PGUID 4 4 t c t \054 1255 0 int4in int4out int4in int4out i p f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 83 ( pg_class     PGUID 4 4 t c t \054 1259 0 int4in int4out int4in int4out i p f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 86 ( pg_shadow    PGUID 4 4 t c t \054 1260 0 int4in int4out int4in int4out i p f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 87 ( pg_group     PGUID 4 4 t c t \054 1261 0 int4in int4out int4in int4out i p f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 88 ( pg_database  PGUID 4 4 t c t \054 1262 0 int4in int4out int4in int4out i p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 71 ( pg_type      PGUID 4 4 t c t \054 1247 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 75 ( pg_attribute PGUID 4 4 t c t \054 1249 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 81 ( pg_proc      PGUID 4 4 t c t \054 1255 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 83 ( pg_class     PGUID 4 4 t c t \054 1259 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 86 ( pg_shadow    PGUID 4 4 t c t \054 1260 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 87 ( pg_group     PGUID 4 4 t c t \054 1261 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 88 ( pg_database  PGUID 4 4 t c t \054 1262 0 int4in int4out int4in int4out i p f 0 -1 0 _null_ _null_ ));
 
 /* OIDS 100 - 199 */
 
 /* OIDS 200 - 299 */
 
-DATA(insert OID = 210 (  smgr     PGUID 2  12 t b t \054 0 0 smgrin smgrout smgrin smgrout s p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 210 (  smgr     PGUID 2  12 t b t \054 0 0 smgrin smgrout smgrin smgrout s p f 0 -1 0 _null_ _null_ ));
 DESCR("storage manager");
 
 /* OIDS 300 - 399 */
@@ -320,167 +325,167 @@ DESCR("storage manager");
 /* OIDS 500 - 599 */
 
 /* OIDS 600 - 699 */
-DATA(insert OID = 600 (  point    PGUID 16  24 f b t \054 0 701 point_in point_out point_in point_out d p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 600 (  point    PGUID 16  24 f b t \054 0 701 point_in point_out point_in point_out d p f 0 -1 0 _null_ _null_ ));
 DESCR("geometric point '(x, y)'");
 #define POINTOID       600
-DATA(insert OID = 601 (  lseg     PGUID 32  48 f b t \054 0 600 lseg_in lseg_out lseg_in lseg_out d p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 601 (  lseg     PGUID 32  48 f b t \054 0 600 lseg_in lseg_out lseg_in lseg_out d p f 0 -1 0 _null_ _null_ ));
 DESCR("geometric line segment '(pt1,pt2)'");
 #define LSEGOID            601
-DATA(insert OID = 602 (  path     PGUID -1  -1 f b t \054 0 0 path_in path_out path_in path_out d x f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 602 (  path     PGUID -1  -1 f b t \054 0 0 path_in path_out path_in path_out d x f 0 -1 0 _null_ _null_ ));
 DESCR("geometric path '(pt1,...)'");
 #define PATHOID            602
-DATA(insert OID = 603 (  box      PGUID 32 100 f b t \073 0 600 box_in box_out box_in box_out d p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 603 (  box      PGUID 32 100 f b t \073 0 600 box_in box_out box_in box_out d p f 0 -1 0 _null_ _null_ ));
 DESCR("geometric box '(lower left,upper right)'");
 #define BOXOID         603
-DATA(insert OID = 604 (  polygon   PGUID -1  -1 f b t \054 0   0 poly_in poly_out poly_in poly_out d x f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 604 (  polygon   PGUID -1  -1 f b t \054 0   0 poly_in poly_out poly_in poly_out d x f 0 -1 0 _null_ _null_ ));
 DESCR("geometric polygon '(pt1,...)'");
 #define POLYGONOID     604
 
-DATA(insert OID = 628 (  line     PGUID 32  48 f b t \054 0 701 line_in line_out line_in line_out d p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 628 (  line     PGUID 32  48 f b t \054 0 701 line_in line_out line_in line_out d p f 0 -1 0 _null_ _null_ ));
 DESCR("geometric line '(pt1,pt2)'");
 #define LINEOID            628
-DATA(insert OID = 629 (  _line    PGUID  -1 -1 f b t \054 0 628 array_in array_out array_in array_out d x f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 629 (  _line    PGUID  -1 -1 f b t \054 0 628 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
 DESCR("");
 
 /* OIDS 700 - 799 */
 
-DATA(insert OID = 700 (  float4    PGUID  4  12 f b t \054 0   0 float4in float4out float4in float4out i p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 700 (  float4    PGUID  4  12 f b t \054 0   0 float4in float4out float4in float4out i p f 0 -1 0 _null_ _null_ ));
 DESCR("single-precision floating point number, 4-byte storage");
 #define FLOAT4OID 700
-DATA(insert OID = 701 (  float8    PGUID  8  24 f b t \054 0   0 float8in float8out float8in float8out d p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 701 (  float8    PGUID  8  24 f b t \054 0   0 float8in float8out float8in float8out d p f 0 -1 0 _null_ _null_ ));
 DESCR("double-precision floating point number, 8-byte storage");
 #define FLOAT8OID 701
-DATA(insert OID = 702 (  abstime   PGUID  4  20 t b t \054 0   0 nabstimein nabstimeout nabstimein nabstimeout i p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 702 (  abstime   PGUID  4  20 t b t \054 0   0 nabstimein nabstimeout nabstimein nabstimeout i p f 0 -1 0 _null_ _null_ ));
 DESCR("absolute, limited-range date and time (Unix system time)");
 #define ABSTIMEOID     702
-DATA(insert OID = 703 (  reltime   PGUID  4  20 t b t \054 0   0 reltimein reltimeout reltimein reltimeout i p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 703 (  reltime   PGUID  4  20 t b t \054 0   0 reltimein reltimeout reltimein reltimeout i p f 0 -1 0 _null_ _null_ ));
 DESCR("relative, limited-range time interval (Unix delta time)");
 #define RELTIMEOID     703
-DATA(insert OID = 704 (  tinterval PGUID 12  47 f b t \054 0   0 tintervalin tintervalout tintervalin tintervalout i p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 704 (  tinterval PGUID 12  47 f b t \054 0   0 tintervalin tintervalout tintervalin tintervalout i p f 0 -1 0 _null_ _null_ ));
 DESCR("(abstime,abstime), time interval");
 #define TINTERVALOID   704
-DATA(insert OID = 705 (  unknown   PGUID -1  -1 f b t \054 0   0 textin textout textin textout i p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 705 (  unknown   PGUID -1  -1 f b t \054 0   0 textin textout textin textout i p f 0 -1 0 _null_ _null_ ));
 DESCR("");
 #define UNKNOWNOID     705
 
-DATA(insert OID = 718 (  circle    PGUID  24 47 f b t \054 0   0 circle_in circle_out circle_in circle_out d p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 718 (  circle    PGUID  24 47 f b t \054 0   0 circle_in circle_out circle_in circle_out d p f 0 -1 0 _null_ _null_ ));
 DESCR("geometric circle '(center,radius)'");
 #define CIRCLEOID      718
-DATA(insert OID = 719 (  _circle   PGUID  -1 -1 f b t \054 0  718 array_in array_out array_in array_out d x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 790 (  money    PGUID   4 24 f b t \054 0    0 cash_in cash_out cash_in cash_out i p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 719 (  _circle   PGUID  -1 -1 f b t \054 0  718 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 790 (  money    PGUID   4 24 f b t \054 0    0 cash_in cash_out cash_in cash_out i p f 0 -1 0 _null_ _null_ ));
 DESCR("$d,ddd.cc, money");
 #define CASHOID 790
-DATA(insert OID = 791 (  _money    PGUID  -1 -1 f b t \054 0  790 array_in array_out array_in array_out i x f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 791 (  _money    PGUID  -1 -1 f b t \054 0  790 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
 
 /* OIDS 800 - 899 */
-DATA(insert OID = 829 ( macaddr    PGUID  6 -1 f b t \054 0 0 macaddr_in macaddr_out macaddr_in macaddr_out i p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 829 ( macaddr    PGUID  6 -1 f b t \054 0 0 macaddr_in macaddr_out macaddr_in macaddr_out i p f 0 -1 0 _null_ _null_ ));
 DESCR("XX:XX:XX:XX:XX:XX, MAC address");
 #define MACADDROID 829
-DATA(insert OID = 869 ( inet      PGUID  -1 -1 f b t \054 0 0 inet_in inet_out inet_in inet_out i p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 869 ( inet      PGUID  -1 -1 f b t \054 0 0 inet_in inet_out inet_in inet_out i p f 0 -1 0 _null_ _null_ ));
 DESCR("IP address/netmask, host address, netmask optional");
 #define INETOID 869
-DATA(insert OID = 650 ( cidr      PGUID  -1 -1 f b t \054 0 0 cidr_in cidr_out cidr_in cidr_out i p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 650 ( cidr      PGUID  -1 -1 f b t \054 0 0 cidr_in cidr_out cidr_in cidr_out i p f 0 -1 0 _null_ _null_ ));
 DESCR("network IP address/netmask, network address");
 #define CIDROID 650
 
 /* OIDS 900 - 999 */
 
 /* OIDS 1000 - 1099 */
-DATA(insert OID = 1000 (  _bool         PGUID -1  -1 f b t \054 0  16 array_in array_out array_in array_out i x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1001 (  _bytea    PGUID -1  -1 f b t \054 0  17 array_in array_out array_in array_out i x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1002 (  _char         PGUID -1  -1 f b t \054 0  18 array_in array_out array_in array_out i x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1003 (  _name         PGUID -1  -1 f b t \054 0  19 array_in array_out array_in array_out i x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1005 (  _int2         PGUID -1  -1 f b t \054 0  21 array_in array_out array_in array_out i x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1006 (  _int2vector PGUID -1 -1 f b t \054 0 22 array_in array_out array_in array_out i x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1007 (  _int4         PGUID -1  -1 f b t \054 0  23 array_in array_out array_in array_out i x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1008 (  _regproc  PGUID -1  -1 f b t \054 0  24 array_in array_out array_in array_out i x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1009 (  _text         PGUID -1  -1 f b t \054 0  25 array_in array_out array_in array_out i x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1028 (  _oid      PGUID -1  -1 f b t \054 0  26 array_in array_out array_in array_out i x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1010 (  _tid      PGUID -1  -1 f b t \054 0  27 array_in array_out array_in array_out i x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1011 (  _xid      PGUID -1  -1 f b t \054 0  28 array_in array_out array_in array_out i x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1012 (  _cid      PGUID -1  -1 f b t \054 0  29 array_in array_out array_in array_out i x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1013 (  _oidvector PGUID -1  -1 f b t \054 0 30 array_in array_out array_in array_out i x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1014 (  _bpchar   PGUID -1  -1 f b t \054 0 1042 array_in array_out array_in array_out i x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1015 (  _varchar  PGUID -1  -1 f b t \054 0 1043 array_in array_out array_in array_out i x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1016 (  _int8         PGUID -1  -1 f b t \054 0  20 array_in array_out array_in array_out d x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1017 (  _point    PGUID -1  -1 f b t \054 0 600 array_in array_out array_in array_out d x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1018 (  _lseg         PGUID -1  -1 f b t \054 0 601 array_in array_out array_in array_out d x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1019 (  _path         PGUID -1  -1 f b t \054 0 602 array_in array_out array_in array_out d x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1020 (  _box      PGUID -1  -1 f b t \073 0 603 array_in array_out array_in array_out d x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1021 (  _float4   PGUID -1  -1 f b t \054 0 700 array_in array_out array_in array_out i x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1022 (  _float8   PGUID -1  -1 f b t \054 0 701 array_in array_out array_in array_out d x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1023 (  _abstime  PGUID -1  -1 f b t \054 0 702 array_in array_out array_in array_out i x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1024 (  _reltime  PGUID -1  -1 f b t \054 0 703 array_in array_out array_in array_out i x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1025 (  _tinterval PGUID -1  -1 f b t \054 0 704 array_in array_out array_in array_out i x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1027 (  _polygon  PGUID -1  -1 f b t \054 0 604 array_in array_out array_in array_out d x f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 1000 (  _bool         PGUID -1  -1 f b t \054 0  16 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1001 (  _bytea    PGUID -1  -1 f b t \054 0  17 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1002 (  _char         PGUID -1  -1 f b t \054 0  18 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1003 (  _name         PGUID -1  -1 f b t \054 0  19 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1005 (  _int2         PGUID -1  -1 f b t \054 0  21 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1006 (  _int2vector PGUID -1 -1 f b t \054 0 22 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1007 (  _int4         PGUID -1  -1 f b t \054 0  23 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1008 (  _regproc  PGUID -1  -1 f b t \054 0  24 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1009 (  _text         PGUID -1  -1 f b t \054 0  25 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1028 (  _oid      PGUID -1  -1 f b t \054 0  26 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1010 (  _tid      PGUID -1  -1 f b t \054 0  27 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1011 (  _xid      PGUID -1  -1 f b t \054 0  28 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1012 (  _cid      PGUID -1  -1 f b t \054 0  29 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1013 (  _oidvector PGUID -1  -1 f b t \054 0 30 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1014 (  _bpchar   PGUID -1  -1 f b t \054 0 1042 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1015 (  _varchar  PGUID -1  -1 f b t \054 0 1043 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1016 (  _int8         PGUID -1  -1 f b t \054 0  20 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1017 (  _point    PGUID -1  -1 f b t \054 0 600 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1018 (  _lseg         PGUID -1  -1 f b t \054 0 601 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1019 (  _path         PGUID -1  -1 f b t \054 0 602 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1020 (  _box      PGUID -1  -1 f b t \073 0 603 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1021 (  _float4   PGUID -1  -1 f b t \054 0 700 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1022 (  _float8   PGUID -1  -1 f b t \054 0 701 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1023 (  _abstime  PGUID -1  -1 f b t \054 0 702 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1024 (  _reltime  PGUID -1  -1 f b t \054 0 703 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1025 (  _tinterval PGUID -1  -1 f b t \054 0 704 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1027 (  _polygon  PGUID -1  -1 f b t \054 0 604 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
 /*
  * Note: the size of aclitem needs to match sizeof(AclItem) in acl.h.
  * Thanks to some padding, this will be 8 on all platforms.
  * We also have an Assert to make sure.
  */
 #define ACLITEMSIZE 8
-DATA(insert OID = 1033 (  aclitem   PGUID 8   -1 f b t \054 0 0 aclitemin aclitemout aclitemin aclitemout i p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 1033 (  aclitem   PGUID 8   -1 f b t \054 0 0 aclitemin aclitemout aclitemin aclitemout i p f 0 -1 0 _null_ _null_ ));
 DESCR("access control list");
-DATA(insert OID = 1034 (  _aclitem  PGUID -1 -1 f b t \054 0 1033 array_in array_out array_in array_out i x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1040 (  _macaddr  PGUID -1 -1 f b t \054 0  829 array_in array_out array_in array_out i x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1041 (  _inet    PGUID -1 -1 f b t \054 0  869 array_in array_out array_in array_out i x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 651  (  _cidr    PGUID -1 -1 f b t \054 0  650 array_in array_out array_in array_out i x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1042 ( bpchar         PGUID -1  -1 f b t \054 0  0 bpcharin bpcharout bpcharin bpcharout i x f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 1034 (  _aclitem  PGUID -1 -1 f b t \054 0 1033 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1040 (  _macaddr  PGUID -1 -1 f b t \054 0  829 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1041 (  _inet    PGUID -1 -1 f b t \054 0  869 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 651  (  _cidr    PGUID -1 -1 f b t \054 0  650 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1042 ( bpchar         PGUID -1  -1 f b t \054 0  0 bpcharin bpcharout bpcharin bpcharout i x f 0 -1 0 _null_ _null_ ));
 DESCR("char(length), blank-padded string, fixed storage length");
 #define BPCHAROID      1042
-DATA(insert OID = 1043 ( varchar    PGUID -1  -1 f b t \054 0  0 varcharin varcharout varcharin varcharout i x f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 1043 ( varchar    PGUID -1  -1 f b t \054 0  0 varcharin varcharout varcharin varcharout i x f 0 -1 0 _null_ _null_ ));
 DESCR("varchar(length), non-blank-padded string, variable storage length");
 #define VARCHAROID     1043
 
-DATA(insert OID = 1082 ( date       PGUID  4  10 t b t \054 0  0 date_in date_out date_in date_out i p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 1082 ( date       PGUID  4  10 t b t \054 0  0 date_in date_out date_in date_out i p f 0 -1 0 _null_ _null_ ));
 DESCR("ANSI SQL date");
 #define DATEOID            1082
-DATA(insert OID = 1083 ( time       PGUID  8  16 f b t \054 0  0 time_in time_out time_in time_out d p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 1083 ( time       PGUID  8  16 f b t \054 0  0 time_in time_out time_in time_out d p f 0 -1 0 _null_ _null_ ));
 DESCR("hh:mm:ss, ANSI SQL time");
 #define TIMEOID            1083
 
 /* OIDS 1100 - 1199 */
-DATA(insert OID = 1114 ( timestamp  PGUID  8  47 f b t \054 0  0 timestamp_in timestamp_out timestamp_in timestamp_out d p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 1114 ( timestamp  PGUID  8  47 f b t \054 0  0 timestamp_in timestamp_out timestamp_in timestamp_out d p f 0 -1 0 _null_ _null_ ));
 DESCR("date and time");
 #define TIMESTAMPOID   1114
-DATA(insert OID = 1115 ( _timestamp  PGUID -1 -1 f b t \054 0  1184 array_in array_out array_in array_out d x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1182 ( _date      PGUID  -1 -1 f b t \054 0  1082 array_in array_out array_in array_out i x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1183 ( _time      PGUID  -1 -1 f b t \054 0  1083 array_in array_out array_in array_out d x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1184 ( timestamptz PGUID 8  47 f b t \054 0  0 timestamptz_in timestamptz_out timestamptz_in timestamptz_out d p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 1115 ( _timestamp  PGUID -1 -1 f b t \054 0  1184 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1182 ( _date      PGUID  -1 -1 f b t \054 0  1082 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1183 ( _time      PGUID  -1 -1 f b t \054 0  1083 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1184 ( timestamptz PGUID 8  47 f b t \054 0  0 timestamptz_in timestamptz_out timestamptz_in timestamptz_out d p f 0 -1 0 _null_ _null_ ));
 DESCR("date and time with time zone");
 #define TIMESTAMPTZOID 1184
-DATA(insert OID = 1185 ( _timestamptz PGUID -1 -1 f b t \054 0 1184 array_in array_out array_in array_out d x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1186 ( interval   PGUID 12  47 f b t \054 0  0 interval_in interval_out interval_in interval_out d p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 1185 ( _timestamptz PGUID -1 -1 f b t \054 0 1184 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1186 ( interval   PGUID 12  47 f b t \054 0  0 interval_in interval_out interval_in interval_out d p f 0 -1 0 _null_ _null_ ));
 DESCR("@  , time interval");
 #define INTERVALOID        1186
-DATA(insert OID = 1187 ( _interval  PGUID  -1 -1 f b t \054 0  1186 array_in array_out array_in array_out d x f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 1187 ( _interval  PGUID  -1 -1 f b t \054 0  1186 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
 
 /* OIDS 1200 - 1299 */
-DATA(insert OID = 1231 (  _numeric  PGUID -1  -1 f b t \054 0  1700 array_in array_out array_in array_out i x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1266 ( timetz         PGUID 12  22 f b t \054 0  0 timetz_in timetz_out timetz_in timetz_out d p f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 1231 (  _numeric  PGUID -1  -1 f b t \054 0  1700 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1266 ( timetz         PGUID 12  22 f b t \054 0  0 timetz_in timetz_out timetz_in timetz_out d p f 0 -1 0 _null_ _null_ ));
 DESCR("hh:mm:ss, ANSI SQL time");
 #define TIMETZOID      1266
-DATA(insert OID = 1270 ( _timetz    PGUID  -1 -1 f b t \054 0  1266 array_in array_out array_in array_out d x f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 1270 ( _timetz    PGUID  -1 -1 f b t \054 0  1266 array_in array_out array_in array_out d x f 0 -1 0 _null_ _null_ ));
 
 /* OIDS 1500 - 1599 */
-DATA(insert OID = 1560 ( bit        PGUID -1  -1 f b t \054 0  0 bit_in bit_out bit_in bit_out i x f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 1560 ( bit        PGUID -1  -1 f b t \054 0  0 bit_in bit_out bit_in bit_out i x f 0 -1 0 _null_ _null_ ));
 DESCR("fixed-length bit string");
 #define BITOID  1560
-DATA(insert OID = 1561 ( _bit       PGUID  -1 -1 f b t \054 0  1560 array_in array_out array_in array_out i x f -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1562 ( varbit         PGUID -1  -1 f b t \054 0  0 varbit_in varbit_out varbit_in varbit_out i x f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 1561 ( _bit       PGUID  -1 -1 f b t \054 0  1560 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 1562 ( varbit         PGUID -1  -1 f b t \054 0  0 varbit_in varbit_out varbit_in varbit_out i x f 0 -1 0 _null_ _null_ ));
 DESCR("variable-length bit string");
 #define VARBITOID    1562
-DATA(insert OID = 1563 ( _varbit    PGUID  -1 -1 f b t \054 0  1562 array_in array_out array_in array_out i x f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 1563 ( _varbit    PGUID  -1 -1 f b t \054 0  1562 array_in array_out array_in array_out i x f 0 -1 0 _null_ _null_ ));
 
 /* OIDS 1600 - 1699 */
 
 /* OIDS 1700 - 1799 */
-DATA(insert OID = 1700 ( numeric      PGUID -1  -1 f b t \054 0  0 numeric_in numeric_out numeric_in numeric_out i m f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 1700 ( numeric      PGUID -1  -1 f b t \054 0  0 numeric_in numeric_out numeric_in numeric_out i m f 0 -1 0 _null_ _null_ ));
 DESCR("numeric(precision, decimal), arbitrary precision number");
 #define NUMERICOID     1700
 
 /* OID 1790 */
-DATA(insert OID = 1790 ( refcursor    PGUID -1  -1 f b t \054 0  0 textin textout textin textout i x f -1 0 0 _null_ _null_ ));
+DATA(insert OID = 1790 ( refcursor    PGUID -1  -1 f b t \054 0  0 textin textout textin textout i x f 0 -1 0 _null_ _null_ ));
 DESCR("reference cursor (portal name)");
 #define REFCURSOROID   1790
 
index d8f7abc1d898da0153ffa52c405ebdbcd13a851d..384241990b5a98d40ef1e0e9cbe89711af340c1b 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: makefuncs.h,v 1.30 2001/11/05 17:46:34 momjian Exp $
+ * $Id: makefuncs.h,v 1.31 2002/03/20 19:45:01 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -46,4 +46,6 @@ extern Const *makeNullConst(Oid consttype);
 
 extern Attr *makeAttr(char *relname, char *attname);
 
+extern RelabelType *makeRelabelType(Node *arg, Oid rtype, int32 rtypmod);
+
 #endif   /* MAKEFUNC_H */
index 71552abbc7653400302c7e702053a4e64a54f70d..1b1f01bd28f7ae57732937135843d5287b086a99 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parsenodes.h,v 1.161 2002/03/19 02:18:24 momjian Exp $
+ * $Id: parsenodes.h,v 1.162 2002/03/20 19:45:02 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -407,23 +407,6 @@ typedef struct DefElem
 } DefElem;
 
 
-/****************************************************************************
- * Nodes for a Domain Creation tree
- ****************************************************************************/
-/* ----------------------
- *     CreateDomain Statement
- * ----------------------
- * Down here as it required TypeName to be defined first.
- */
-typedef struct CreateDomainStmt
-{
-   NodeTag     type;
-   char       *domainname;         /* name of domain to create */
-   TypeName   *typename;           /* the typecast */
-   List       *constraints;        /* constraints (list of Constraint nodes) */
-} CreateDomainStmt;
-
-
 /****************************************************************************
  * Nodes for a Query tree
  ****************************************************************************/
@@ -1056,11 +1039,23 @@ typedef struct VersionStmt
 typedef struct DefineStmt
 {
    NodeTag     type;
-   int         defType;        /* OPERATOR|P_TYPE|AGGREGATE */
+   int         defType;        /* OPERATOR|TYPE_P|AGGREGATE */
    char       *defname;
    List       *definition;     /* a list of DefElem */
 } DefineStmt;
 
+/* ----------------------
+ *     Create Domain Statement
+ * ----------------------
+ */
+typedef struct CreateDomainStmt
+{
+   NodeTag     type;
+   char       *domainname;         /* name of domain to create */
+   TypeName   *typename;           /* the base type */
+   List       *constraints;        /* constraints (list of Constraint nodes) */
+} CreateDomainStmt;
+
 /* ----------------------
  *     Drop Table|Sequence|View|Index|Rule|Type Statement
  * ----------------------
@@ -1071,8 +1066,8 @@ typedef struct DefineStmt
 #define DROP_VIEW    3
 #define DROP_INDEX   4
 #define DROP_RULE    5
-#define DROP_TYPE_P   6
-#define DROP_DOMAIN_P 7
+#define DROP_TYPE     6
+#define DROP_DOMAIN      7
 
 typedef struct DropStmt
 {
index d2c91ed25fa9adcc5beab17e0868d35900fe6f90..1c503aed6535d54d0c764f520ef722f92c38a0f8 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parse_coerce.h,v 1.40 2002/03/19 02:18:24 momjian Exp $
+ * $Id: parse_coerce.h,v 1.41 2002/03/20 19:45:07 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -34,38 +34,7 @@ typedef enum CATEGORY
 } CATEGORY;
 
 
-/* IS_BINARY_COMPATIBLE()
- * Check for types with the same underlying binary representation.
- * This allows us to cheat and directly exchange values without
- * going through the trouble of calling a conversion function.
- *
- * Remove equivalencing of FLOAT8 and TIMESTAMP. They really are not
- * close enough in behavior, with the TIMESTAMP reserved values
- * and special formatting. - thomas 1999-01-24
- */
-#define IS_BINARY_COMPATIBLE(a,b) \
-         (((a) == BPCHAROID && (b) == TEXTOID) \
-       || ((a) == BPCHAROID && (b) == VARCHAROID) \
-       || ((a) == VARCHAROID && (b) == TEXTOID) \
-       || ((a) == VARCHAROID && (b) == BPCHAROID) \
-       || ((a) == TEXTOID && (b) == BPCHAROID) \
-       || ((a) == TEXTOID && (b) == VARCHAROID) \
-       || ((a) == OIDOID && (b) == INT4OID) \
-       || ((a) == OIDOID && (b) == REGPROCOID) \
-       || ((a) == INT4OID && (b) == OIDOID) \
-       || ((a) == INT4OID && (b) == REGPROCOID) \
-       || ((a) == REGPROCOID && (b) == OIDOID) \
-       || ((a) == REGPROCOID && (b) == INT4OID) \
-       || ((a) == ABSTIMEOID && (b) == INT4OID) \
-       || ((a) == INT4OID && (b) == ABSTIMEOID) \
-       || ((a) == RELTIMEOID && (b) == INT4OID) \
-       || ((a) == INT4OID && (b) == RELTIMEOID) \
-       || ((a) == INETOID && (b) == CIDROID) \
-       || ((a) == CIDROID && (b) == INETOID) \
-       || ((a) == BITOID && (b) == VARBITOID) \
-       || ((a) == VARBITOID && (b) == BITOID))
-
-
+extern bool IsBinaryCompatible(Oid type1, Oid type2);
 extern bool IsPreferredType(CATEGORY category, Oid type);
 extern CATEGORY TypeCategory(Oid type);
 
@@ -81,6 +50,5 @@ extern Oid    select_common_type(List *typeids, const char *context);
 extern Node *coerce_to_common_type(ParseState *pstate, Node *node,
                      Oid targetTypeId,
                      const char *context);
-extern Oid getBaseType(Oid inType);
 
 #endif   /* PARSE_COERCE_H */
index 9b0ff8514d8904576210343b24b3ec9a53fcf65f..fbdb5f663460792e154a398582142af3ea8043eb 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.43 2002/03/19 02:18:24 momjian Exp $
+ * $Id: lsyscache.h,v 1.44 2002/03/20 19:45:09 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -44,7 +44,8 @@ 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 Node *get_typdefault(Oid typid, int32 atttypmod);
+extern Node *get_typdefault(Oid typid);
+extern Oid getBaseType(Oid typid);
 extern int32 get_typavgwidth(Oid typid, int32 typmod);
 extern int32 get_attavgwidth(Oid relid, AttrNumber attnum);
 extern bool get_attstatsslot(HeapTuple statstuple,
index 4d8d13ec2d753408dc6f197aa593af2e176fc5c7..7127215869a3c90bb2bb081ec15827035876c5a9 100644 (file)
@@ -3,9 +3,9 @@ create domain domaindroptest int4;
 comment on domain domaindroptest is 'About to drop this..';
 create domain basetypetest domaindroptest;
 ERROR:  DefineDomain: domaindroptest is not a basetype
+drop domain domaindroptest cascade;
+ERROR:  DROP DOMAIN does not support the CASCADE keyword
 drop domain domaindroptest;
-ERROR:  parser: parse error at or near ";"
-drop domain domaindroptest restrict;
 -- TEST Domains.
 create domain domainvarchar varchar(5);
 create domain domainnumeric numeric(8,2);
@@ -29,11 +29,21 @@ select * from basictest;
  88       | haha     | short       | 123.12
 (2 rows)
 
+-- check that domains inherit operations from base types
+-- XXX shouldn't have to quote the constant here
+select testtext || testvarchar as concat, testnumeric + '42' as sum
+from basictest;
+  concat   |  sum   
+-----------+--------
+ hahashort | 165.12
+ hahashort | 165.12
+(2 rows)
+
 drop table basictest;
 drop domain domainvarchar restrict;
 drop domain domainnumeric restrict;
 drop domain domainint4 restrict;
-drop domain domaintext restrict;
+drop domain domaintext;
 -- Array Test
 create domain domainint4arr int4[1];
 create domain domaintextarr text[2][3];
@@ -46,6 +56,26 @@ INSERT INTO domarrtest values ('{{2,2}{2,2}}', '{{"a","b"}}');
 INSERT INTO domarrtest values ('{2,2}', '{{"a","b"}{"c","d"}{"e"}}');
 INSERT INTO domarrtest values ('{2,2}', '{{"a"}{"c"}}');
 INSERT INTO domarrtest values (NULL, '{{"a","b"}{"c","d","e"}}');
+select * from domarrtest;
+  testint4arr  |     testtextarr     
+---------------+---------------------
+ {2,2}         | {{a,c},{"",d}}
+ {{2,2},{0,2}} | {{a,b}}
+ {2,2}         | {{a},{c},{e}}
+ {2,2}         | {{c},{""}}
+               | {{a,c,""},{"",d,e}}
+(5 rows)
+
+select testint4arr[1], testtextarr[2:2] from domarrtest;
+ testint4arr | testtextarr 
+-------------+-------------
+           2 | {{"",d}}
+             | 
+           2 | {{c}}
+           2 | {{""}}
+             | {{"",d,e}}
+(5 rows)
+
 drop table domarrtest;
 drop domain domainint4arr restrict;
 drop domain domaintextarr restrict;
index 1417fe318966eb39ba3c9a84243710aae84e4a82..cecb876c3863cd78cfe9432bcce14b924e31797d 100644 (file)
@@ -6,8 +6,8 @@ comment on domain domaindroptest is 'About to drop this..';
 
 create domain basetypetest domaindroptest;
 
+drop domain domaindroptest cascade;
 drop domain domaindroptest;
-drop domain domaindroptest restrict;
 
 
 -- TEST Domains.
@@ -31,11 +31,16 @@ INSERT INTO basictest values ('88', 'haha', 'short text', '123.12'); -- Bad varc
 INSERT INTO basictest values ('88', 'haha', 'short', '123.1212');    -- Truncate numeric
 select * from basictest;
 
+-- check that domains inherit operations from base types
+-- XXX shouldn't have to quote the constant here
+select testtext || testvarchar as concat, testnumeric + '42' as sum
+from basictest;
+
 drop table basictest;
 drop domain domainvarchar restrict;
 drop domain domainnumeric restrict;
 drop domain domainint4 restrict;
-drop domain domaintext restrict;
+drop domain domaintext;
 
 
 -- Array Test
@@ -51,6 +56,8 @@ INSERT INTO domarrtest values ('{{2,2}{2,2}}', '{{"a","b"}}');
 INSERT INTO domarrtest values ('{2,2}', '{{"a","b"}{"c","d"}{"e"}}');
 INSERT INTO domarrtest values ('{2,2}', '{{"a"}{"c"}}');
 INSERT INTO domarrtest values (NULL, '{{"a","b"}{"c","d","e"}}');
+select * from domarrtest;
+select testint4arr[1], testtextarr[2:2] from domarrtest;
 
 drop table domarrtest;
 drop domain domainint4arr restrict;