]> granicus.if.org Git - postgresql/commitdiff
Code review for DOMAIN patch.
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 20 Mar 2002 19:45:13 +0000 (19:45 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
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 @@
 <!--
  Documentation of the system catalogs, directed toward PostgreSQL developers
- $Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.34 2002/03/19 02:18:10 momjian Exp $
+ $Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.35 2002/03/20 19:43:24 tgl Exp $
  -->
 
 <chapter id="catalogs">
    This catalog stores information about datatypes.  Scalar types
    (<quote>base types</>) are created with <command>CREATE TYPE</command>.
    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 <command>CREATE DOMAIN</command>.
   </para>
 
   <table>
       <entry></entry>
       <entry>
        <structfield>typtype</structfield> is <literal>b</literal> for
-       a base type and <literal>c</literal> for a complex type (i.e.,
-       a table's row type).  If <structfield>typtype</structfield> is
-       <literal>c</literal>, <structfield>typrelid</structfield> is
-       the OID of the type's entry in
-       <structname>pg_class</structname>.
+       a base type, <literal>c</literal> for a complex type (i.e.,
+       a table's row type), or <literal>d</literal> for a derived type (i.e.,
+       a domain).  See also <structfield>typrelid</structfield> 
+       and <structfield>typbasetype</structfield>.
       </entry>
      </row>
 
        the <structfield>pg_class</structfield> 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.
       </entry>
      </row>
 
      </row>
 
      <row>
-      <entry>typbasetype</entry>
-      <entry><type>oid</type></entry>
+      <entry>typnotnull</entry>
+      <entry><type>bool</type></entry>
       <entry></entry>
       <entry><para>
-       <structfield>typbasetype</structfield> is the type that this one is based
-       on.  Normally references the domains parent type, and is 0 otherwise.
+       <structfield>typnotnull</structfield> represents a NOT NULL
+       constraint on a type.  Presently used for domains only.
       </para></entry>
      </row>
 
-        <row>
-         <entry>typnotnull</entry>
-         <entry><type>boolean</type></entry>
-         <entry></entry>
-         <entry><para>
-          <structfield>typnotnull</structfield> represents a NOT NULL
-          constraint on a type.  Used for domains only.
-         </para></entry>
-        </row>
+     <row>
+      <entry>typbasetype</entry>
+      <entry><type>oid</type></entry>
+      <entry>pg_type.oid</entry>
+      <entry><para>
+       If this is a derived type (see <structfield>typtype</structfield>),
+       then <structfield>typbasetype</structfield> identifies
+       the type that this one is based on.  Zero if not a derived type.
+      </para></entry>
+     </row>
 
      <row>
-      <entry>typmod</entry>
-      <entry><type>integer</type></entry>
+      <entry>typtypmod</entry>
+      <entry><type>int4</type></entry>
       <entry></entry>
       <entry><para>
-       <structfield>typmod</structfield> records type-specific data
+       <structfield>typtypmod</structfield> records type-specific data
        supplied at table creation time (for example, the maximum
        length of a <type>varchar</type> 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
-       <structfield>pg_attribute.atttypmod</structfield> on creation
-       of a table using a domain as it's field type.
+       need typmod.  This value is copied to
+       <structfield>pg_attribute.atttypmod</structfield> when
+       creating a column of a domain type.
+       </para></entry>
+     </row>
+
+     <row>
+      <entry>typndims</entry>
+      <entry><type>int4</type></entry>
+      <entry></entry>
+      <entry><para>
+       <structfield>typndims</structfield> 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
+       <structfield>pg_attribute.attndims</structfield> when
+       creating a column of a domain type.
        </para></entry>
      </row>
 
       <entry><type>text</type></entry>
       <entry></entry>
       <entry><para>
-       <structfield>typdefaultbin</structfield> 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 <structfield>typdefaultbin</> is not NULL, it is the nodeToString
+       representation of a default expression for the type.  Currently this is
+       only used for domains.
       </para></entry>
      </row>
 
       <entry><type>text</type></entry>
       <entry></entry>
       <entry><para>
-       <structfield>typdefault</structfield> is NULL for types without a
-       default value.  If it's not NULL, it contains the external string
-       representation of the type's default value.
+       <structfield>typdefault</> is NULL if the type has no associated
+       default value. If <structfield>typdefaultbin</> is not NULL,
+       <structfield>typdefault</> must contain a human-readable version of the
+       default expression represented by <structfield>typdefaultbin</>.  If
+       <structfield>typdefaultbin</> is NULL and <structfield>typdefault</> is
+       not, then <structfield>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.
       </para></entry>
      </row>
     </tbody>
index 5f79dc63b539e13df2a61f45a1fb293006e91a03..222d49da5d10bafdc3da1702c73f6e04a8d9c5d7 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_domain.sgml,v 1.3 2002/03/19 02:18:13 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_domain.sgml,v 1.4 2002/03/20 19:43:28 tgl Exp $
 PostgreSQL documentation
 -->
 
@@ -23,13 +23,14 @@ PostgreSQL documentation
    <date>2002-02-24</date>
   </refsynopsisdivinfo>
   <synopsis>
-CREATE DOMAIN <replaceable class="parameter">domainname</replaceable> <replaceable class="parameter">data_type</replaceable>  [ DEFAULT <replaceable>default_expr</> ] [ <replaceable class="PARAMETER">column_constraint</replaceable> [, ... ] ]
+CREATE DOMAIN <replaceable class="parameter">domainname</replaceable> [AS] <replaceable class="parameter">data_type</replaceable>
+    [ DEFAULT <replaceable>default_expr</> ]
+    [ <replaceable class="PARAMETER">constraint</replaceable> [, ... ] ]
+
+where <replaceable class="PARAMETER">constraint</replaceable> is:
+
 [ CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> ]
-{ NOT NULL | NULL <!-- |  UNIQUE | PRIMARY KEY |
-  CHECK (<replaceable class="PARAMETER">expression</replaceable>) |
-  REFERENCES <replaceable class="PARAMETER">reftable</replaceable> [ ( <replaceable class="PARAMETER">refcolumn</replaceable> ) ] [ MATCH FULL | MATCH PARTIAL ]
-    [ ON DELETE <replaceable class="parameter">action</replaceable> ] [ ON UPDATE <replaceable class="parameter">action</replaceable> ] --> }
-<!-- [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] -->
+{ NOT NULL | NULL }
   </synopsis>
 
   <refsect2 id="R2-SQL-CREATEDOMAIN-1">
@@ -67,23 +68,26 @@ CREATE DOMAIN <replaceable class="parameter">domainname</replaceable> <replaceab
       <replaceable>default_expr</replaceable></literal></term>
       <listitem>
        <para>
-        The <literal>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 <literal>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.
        </para>
 
        <para>
         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.
        </para>
 
        <note>
         <para>
-         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.
         </para>
        </note>
       </listitem>
@@ -93,7 +97,7 @@ CREATE DOMAIN <replaceable class="parameter">domainname</replaceable> <replaceab
       <term><literal>CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable></literal></term>
       <listitem>
        <para>
-        An optional name for a domain.  If not specified,
+        An optional name for a constraint.  If not specified,
         the system generates a name.
        </para>
       </listitem>
@@ -103,7 +107,7 @@ CREATE DOMAIN <replaceable class="parameter">domainname</replaceable> <replaceab
       <term><literal>NOT NULL</></term>
       <listitem>
        <para>
-        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 <literal>CHECK (<replaceable
         class="PARAMETER">column</replaceable> NOT NULL)</literal>.
        </para>
@@ -114,7 +118,7 @@ CREATE DOMAIN <replaceable class="parameter">domainname</replaceable> <replaceab
       <term><literal>NULL</></term>
       <listitem>
        <para>
-        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.
        </para>
 
        <para>
@@ -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.
   </para>
  </refsect1>
 
@@ -195,9 +199,9 @@ CREATE TABLE countrylist (id INT4, country country_code);
   <title>Compatibility</title>
 
   <para>
-   This <command>CREATE DOMAIN</command> command is a
-   <productname>PostgreSQL</productname> 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 <productname>PostgreSQL</productname>.
   </para>
  </refsect1>
 
index e9bc38ad28cb9a94628f8ec5a5f7432e116777d7..63eb0dc057ee30cf8ee1ea0b6be726b74c5ac69c 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_domain.sgml,v 1.3 2002/03/19 02:18:13 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_domain.sgml,v 1.4 2002/03/20 19:43:28 tgl Exp $
 PostgreSQL documentation
 -->
 
@@ -23,7 +23,7 @@ PostgreSQL documentation
    <date>1999-07-20</date>
   </refsynopsisdivinfo>
   <synopsis>
-DROP DOMAIN <replaceable class="PARAMETER">domainname</replaceable> [, ...]
+DROP DOMAIN <replaceable class="PARAMETER">domainname</replaceable> [, ...]  [ CASCADE | RESTRICT ]
   </synopsis>
 
   <refsect2 id="R2-SQL-DROPDOMAIN-1">
@@ -43,6 +43,25 @@ DROP DOMAIN <replaceable class="PARAMETER">domainname</replaceable> [, ...]
        </para>
       </listitem>
      </varlistentry>
+
+     <varlistentry>
+      <term><literal>CASCADE</></term>
+      <listitem>
+       <para>
+        Automatically drop objects that depend on the domain.  This
+       behavior is not currently supported.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
+      <term><literal>RESTRICT</></term>
+      <listitem>
+       <para>
+        Do not drop dependent objects.  This is the default.
+       </para>
+      </listitem>
+     </varlistentry>
     </variablelist>
    </para>
   </refsect2>
@@ -117,7 +136,7 @@ ERROR:  RemoveDomain: type '<replaceable class="parameter">domainname</replaceab
    To remove the <type>box</type> domain:
 
 <programlisting>
-DROP DOMAIN box RESTRICT;
+DROP DOMAIN box;
 </programlisting>
   </para>
  </refsect1>
@@ -134,9 +153,8 @@ DROP DOMAIN box RESTRICT;
 <synopsis>
 DROP DOMAIN <replaceable>name</replaceable> { CASCADE | RESTRICT }
 </synopsis>
-   <productname>PostgreSQL</productname> enforces the existance of
-   RESTRICT or CASCADE but ignores their enforcement against the
-   system tables.
+   <productname>PostgreSQL</productname> accepts only the RESTRICT
+   option, and currently does not check for existence of dependent objects.
   </para>
  </refsect1>
 
index 350128fa7244041d76ca06421785fd3c69eff6bc..40ba18716c222bd13fdc587f481fdb44c00d451d 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/psql-ref.sgml,v 1.64 2002/03/19 02:32:19 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/psql-ref.sgml,v 1.65 2002/03/20 19:43:30 tgl Exp $
 PostgreSQL documentation
 -->
 
@@ -419,21 +419,10 @@ testdb=>
         <term><literal>\dD</literal> [ <replaceable class="parameter">pattern</replaceable> ]</term>
         <listitem>
         <para>
-        Lists all database domains.
-        </para>
-
-        <para>
-        Descriptions for objects can be generated with the <command>COMMENT ON</command>
-        <acronym>SQL</acronym> command.
-       </para>
-
-        <note>
-        <para>
-        <productname>PostgreSQL</productname> stores the object descriptions in the
-        pg_description system table.
+        Lists all available domains (derived types).
+       If <replaceable class="parameter">pattern</replaceable>
+       (a regular expression) is specified, only matching domains are shown.
         </para>
-        </note>
-
         </listitem>
       </varlistentry>
 
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 <expr> 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 <node>    alter_column_default
-%type <ival>    drop_behavior
+%type <ival>    drop_behavior, opt_drop_behavior
 
 %type <list>   createdb_opt_list, createdb_opt_item
 %type <boolean>        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("@ <number> <units>, 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;