]> granicus.if.org Git - postgresql/commitdiff
Ok. Updated patch attached.
authorBruce Momjian <bruce@momjian.us>
Wed, 6 Mar 2002 20:35:02 +0000 (20:35 +0000)
committerBruce Momjian <bruce@momjian.us>
Wed, 6 Mar 2002 20:35:02 +0000 (20:35 +0000)
- domain.patch -> source patch against pgsql in cvs
- drop_domain.sgml and create_domain.sgml -> New doc/src/sgml/ref docs

- dominfo.txt -> basic domain related queries I used for testing
[ ADDED TO /doc]

Enables domains of array elements -> CREATE DOMAIN dom int4[3][2];

Uses a typbasetype column to describe the origin of the domain.

Copies data to attnotnull rather than processing in execMain().

Some documentation differences from earlier.

If this is approved, I'll start working on pg_dump, and a \dD <domain>
option in psql, and regression tests.  I don't really feel like doing
those until the system table structure settles for pg_type.

CHECKS when added, will also be copied to to the table attributes.  FK
Constraints (if I ever figure out how) will be done similarly.  Both
will lbe handled by MergeDomainAttributes() which is called shortly
before MergeAttributes().

Rod Taylor

32 files changed:
doc/dominfo.txt [new file with mode: 0644]
doc/src/sgml/catalogs.sgml
doc/src/sgml/ref/allfiles.sgml
doc/src/sgml/ref/comment.sgml
doc/src/sgml/ref/create_domain.sgml [new file with mode: 0644]
doc/src/sgml/ref/drop_domain.sgml [new file with mode: 0644]
doc/src/sgml/reference.sgml
src/backend/catalog/heap.c
src/backend/catalog/pg_type.c
src/backend/commands/creatinh.c
src/backend/commands/define.c
src/backend/commands/remove.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/optimizer/prep/preptlist.c
src/backend/parser/gram.y
src/backend/parser/keywords.c
src/backend/parser/parse_coerce.c
src/backend/parser/parse_expr.c
src/backend/tcop/utility.c
src/backend/utils/adt/format_type.c
src/backend/utils/cache/lsyscache.c
src/backend/utils/cache/relcache.c
src/include/catalog/heap.h
src/include/catalog/pg_attribute.h
src/include/catalog/pg_class.h
src/include/catalog/pg_type.h
src/include/commands/defrem.h
src/include/nodes/nodes.h
src/include/nodes/parsenodes.h
src/include/parser/parse_coerce.h
src/include/utils/lsyscache.h

diff --git a/doc/dominfo.txt b/doc/dominfo.txt
new file mode 100644 (file)
index 0000000..a439ff6
--- /dev/null
@@ -0,0 +1,87 @@
+
+
+-- Test Comment / Drop
+create domain domaindroptest int4;
+comment on domain domaindroptest is 'About to drop this..';
+
+select * from pg_type where typname = 'domaindroptest';
+
+drop domain domaindroptest restrict;
+
+select * from pg_type where typname = 'domaindroptest';
+
+-- TEST Domains.
+
+create domain domainvarchar varchar(5);
+create domain domainnumeric numeric(8,2);
+create domain domainint4 int4;
+create domain domaintext text;
+
+
+-- Test tables using domains
+create table basictest
+           ( testint4 domainint4
+           , testtext domaintext
+           , testvarchar domainvarchar
+           , testnumeric domainnumeric
+           );
+
+INSERT INTO basictest values ('88', 'haha', 'short', '123.12');      -- Good
+INSERT INTO basictest values ('88', 'haha', 'short text', '123.12'); -- Bad varchar
+INSERT INTO basictest values ('88', 'haha', 'short', '123.1212');    -- Truncate numeric
+select * from basictest;
+
+
+-- Array Test
+create domain domainint4arr int4[1];
+create domain domaintextarr text[2][3];
+
+create table arrtest
+           ( testint4arr domainint4arr
+           , testtextarr domaintextarr
+           );
+INSERT INTO arrtest values ('{2,2}', '{{"a","b"}{"c","d"}}');
+INSERT INTO arrtest values ('{{2,2}{2,2}}', '{{"a","b"}}');
+INSERT INTO arrtest values ('{2,2}', '{{"a","b"}{"c","d"}{"e"}}');
+INSERT INTO arrtest values ('{2,2}', '{{"a"}{"c"}}');
+INSERT INTO arrtest values (NULL, '{{"a","b"}{"c","d","e"}}');
+
+
+create domain dnotnull varchar(15) NOT NULL;
+create domain dnull    varchar(15) NULL;
+
+create table nulltest
+           ( col1 dnotnull
+           , col2 dnotnull NULL  -- NOT NULL in the domain cannot be overridden
+           , col3 dnull    NOT NULL
+           , col4 dnull
+           );
+INSERT INTO nulltest DEFAULT VALUES;
+INSERT INTO nulltest values ('a', 'b', 'c', 'd');  -- Good
+INSERT INTO nulltest values (NULL, 'b', 'c', 'd');
+INSERT INTO nulltest values ('a', NULL, 'c', 'd');
+INSERT INTO nulltest values ('a', 'b', NULL, 'd');
+INSERT INTO nulltest values ('a', 'b', 'c', NULL); -- Good
+select * from nulltest;
+
+
+create domain ddef1 int4 DEFAULT 3;
+create domain ddef2 numeric(8,6) DEFAULT '1234.123456789';
+-- Type mixing, function returns int8
+create domain ddef3 text DEFAULT 5;
+create sequence ddef4_seq;
+create domain ddef4 int4 DEFAULT nextval(cast('ddef4_seq' as text));
+
+create table defaulttest
+            ( col1 ddef1
+            , col2 ddef2
+            , col3 ddef3
+            , col4 ddef4
+            , col5 ddef1 NOT NULL DEFAULT NULL
+            , col6 ddef2 DEFAULT '88.1'
+            , col7 ddef4 DEFAULT 8000
+            );
+insert into defaulttest default values;
+insert into defaulttest default values;
+insert into defaulttest default values;
+select * from defaulttest;
index aab0a906d9b7a589c648e70e55dd4ab6b5e8adcb..357d17712b5b9ef9f64c7a7d0ccda1b0c3aae03d 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.31 2002/03/01 22:45:03 petere Exp $
+ $Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.32 2002/03/06 20:34:43 momjian Exp $
  -->
 
 <chapter id="catalogs">
       </para></entry>
      </row>
 
+     <row>
+      <entry>typbasetype</entry>
+      <entry><type>oid</type></entry>
+      <entry></entry>
+      <entry><para>
+       <structfield>typbasetype</structfield> is the type that this one is based
+       off of.  Normally references the domains parent type, and is 0 otherwise.
+      </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.  Normally used only for domains.
+         </para></entry>
+        </row>
+
+     <row>
+      <entry>typmod</entry>
+      <entry><type>integer</type></entry>
+      <entry></entry>
+      <entry><para>
+       <structfield>typmod</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.
+       </para></entry>
+     </row>
+
+     <row>
+      <entry>typdefaultbin</entry>
+      <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.
+      </para></entry>
+     </row>
+
      <row>
       <entry>typdefault</entry>
       <entry><type>text</type></entry>
index 94f1226c24f73997675812a41a2e4ab59afb9fe5..948e2cdac5ed13f110b147f88e44f8fbce1f652c 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/allfiles.sgml,v 1.33 2002/03/01 22:45:07 petere Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/allfiles.sgml,v 1.34 2002/03/06 20:34:44 momjian Exp $
 PostgreSQL documentation
 Complete list of usable sgml source files in this directory.
 -->
@@ -52,6 +52,7 @@ Complete list of usable sgml source files in this directory.
 <!entity createAggregate    system "create_aggregate.sgml">
 <!entity createConstraint   system "create_constraint.sgml">
 <!entity createDatabase     system "create_database.sgml">
+<!entity createDomain       system "create_domain.sgml">
 <!entity createFunction     system "create_function.sgml">
 <!entity createGroup        system "create_group.sgml">
 <!entity createIndex        system "create_index.sgml">
@@ -69,6 +70,7 @@ Complete list of usable sgml source files in this directory.
 <!entity delete             system "delete.sgml">
 <!entity dropAggregate      system "drop_aggregate.sgml">
 <!entity dropDatabase       system "drop_database.sgml">
+<!entity dropDomain         system "drop_domain.sgml">
 <!entity dropFunction       system "drop_function.sgml">
 <!entity dropGroup          system "drop_group.sgml">
 <!entity dropIndex          system "drop_index.sgml">
index 9a22b7589544beb96fac498e00b23218ca9728ad..2482a2d7e33fdde23ab5980bfcbe8bebed4c5a1f 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/comment.sgml,v 1.12 2001/12/27 21:36:57 tgl Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/comment.sgml,v 1.13 2002/03/06 20:34:44 momjian Exp $
 PostgreSQL documentation
 -->
 
@@ -25,7 +25,7 @@ PostgreSQL documentation
   <synopsis>
 COMMENT ON
 [
-  [ DATABASE | INDEX | RULE | SEQUENCE | TABLE | TYPE | VIEW ] <replaceable class="PARAMETER">object_name</replaceable> |
+  [ DATABASE | DOMAIN | INDEX | RULE | SEQUENCE | TABLE | TYPE | VIEW ] <replaceable class="PARAMETER">object_name</replaceable> |
   COLUMN <replaceable class="PARAMETER">table_name</replaceable>.<replaceable class="PARAMETER">column_name</replaceable> |
   AGGREGATE <replaceable class="PARAMETER">agg_name</replaceable> (<replaceable class="PARAMETER">agg_type</replaceable>) |
   FUNCTION <replaceable class="PARAMETER">func_name</replaceable> (<replaceable class="PARAMETER">arg1</replaceable>, <replaceable class="PARAMETER">arg2</replaceable>, ...) |
@@ -33,7 +33,7 @@ COMMENT ON
   TRIGGER <replaceable class="PARAMETER">trigger_name</replaceable> ON <replaceable class="PARAMETER">table_name</replaceable>
 ] IS <replaceable class="PARAMETER">'text'</replaceable>
   </synopsis>
-  
+
   <refsect2 id="R2-SQL-COMMENT-1">
    <refsect2info>
     <date>1999-10-25</date>
@@ -64,7 +64,7 @@ COMMENT ON
     </variablelist>
    </para>
   </refsect2>
-  
+
   <refsect2 id="R2-SQL-COMMENT-2">
    <refsect2info>
     <date>1998-09-08</date>
@@ -99,7 +99,7 @@ COMMENT
   </title>
   <para>
    <command>COMMENT</command> stores a comment about a database object.
-    Comments can be 
+    Comments can be
     easily retrieved with <command>psql</command>'s
     <command>\dd</command>, <command>\d+</command>, or <command>\l+</command>
     commands.  Other user interfaces to retrieve comments can be built atop
@@ -141,6 +141,7 @@ COMMENT ON mytable IS 'This is my table.';
 
    <programlisting>
 COMMENT ON DATABASE my_database IS 'Development Database';
+COMMENT ON DOMAIN my_domain IS 'Domains are like abstracted fields';
 COMMENT ON INDEX my_index IS 'Enforces uniqueness on employee id';
 COMMENT ON RULE my_rule IS 'Logs UPDATES of employee records';
 COMMENT ON SEQUENCE my_sequence IS 'Used to generate primary keys';
@@ -155,12 +156,12 @@ COMMENT ON TRIGGER my_trigger ON my_table IS 'Used for R.I.';
    </programlisting>
   </para>
  </refsect1>
+
  <refsect1 id="R1-SQL-COMMENT-3">
   <title>
    Compatibility
   </title>
-  
+
   <refsect2 id="R2-SQL-COMMENT-4">
    <refsect2info>
     <date>1998-09-08</date>
diff --git a/doc/src/sgml/ref/create_domain.sgml b/doc/src/sgml/ref/create_domain.sgml
new file mode 100644 (file)
index 0000000..f88069b
--- /dev/null
@@ -0,0 +1,231 @@
+<!--
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_domain.sgml,v 1.1 2002/03/06 20:34:44 momjian Exp $
+PostgreSQL documentation
+-->
+
+<refentry id="SQL-CREATEDOMAIN">
+ <refmeta>
+  <refentrytitle id="sql-createdomian-title">
+   CREATE DOMAIN
+  </refentrytitle>
+  <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+ <refnamediv>
+  <refname>
+   CREATE DOMAIN
+  </refname>
+  <refpurpose>
+   define a new domain
+  </refpurpose>
+ </refnamediv>
+ <refsynopsisdiv>
+  <refsynopsisdivinfo>
+   <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> [, ... ] ]
+[ 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 ] -->
+  </synopsis>
+
+  <refsect2 id="R2-SQL-CREATEDOMAIN-1">
+   <refsect2info>
+    <date>2002-02-24</date>
+   </refsect2info>
+   <title>
+    Parameters
+   </title>
+   <para>
+
+    <variablelist>
+     <varlistentry>
+      <term><replaceable class="parameter">domainname</replaceable></term>
+      <listitem>
+       <para>
+       The name of a domain to be created.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
+      <term><replaceable class="PARAMETER">data_type</replaceable></term>
+      <listitem>
+       <para>
+        The data type of the domain. This may include array specifiers.
+        Refer to the <citetitle>User's Guide</citetitle> for further
+        information about data types and arrays.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
+      <term><literal>DEFAULT
+      <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
+        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
+        for a domain, then the default is NULL.
+       </para>
+
+       <note>
+        <para>
+         The default of a column will be tested before that of the domain.
+        </para>
+       </note>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
+      <term><literal>CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable></literal></term>
+      <listitem>
+       <para>
+        An optional name for a domain.  If not specified,
+        the system generates a name.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
+      <term><literal>NOT NULL</></term>
+      <listitem>
+       <para>
+        The column is not allowed to contain NULL values.  This is
+        equivalent to the column constraint <literal>CHECK (<replaceable
+        class="PARAMETER">column</replaceable> NOT NULL)</literal>.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
+      <term><literal>NULL</></term>
+      <listitem>
+       <para>
+        The column is allowed to contain NULL values. This is the default.
+       </para>
+
+       <para>
+        This clause is only available for compatibility with
+        non-standard SQL databases.  Its use is discouraged in new
+        applications.
+       </para>
+      </listitem>
+     </varlistentry>
+
+    </variablelist>
+   </para>
+  </refsect2>
+
+  <refsect2 id="R2-SQL-CREATEDOMAIN-2">
+   <refsect2info>
+    <date>2002-02-24</date>
+   </refsect2info>
+   <title>
+    Outputs
+   </title>
+   <para>
+
+    <variablelist>
+     <varlistentry>
+      <term><computeroutput>
+CREATE DOMAIN
+       </computeroutput></term>
+      <listitem>
+       <para>
+       Message returned if the domain is successfully created.
+       </para>
+      </listitem>
+     </varlistentry>
+    </variablelist>
+   </para>
+  </refsect2>
+ </refsynopsisdiv>
+
+ <refsect1 id="R1-SQL-CREATEDOMAIN-1">
+  <refsect1info>
+   <date>2002-02-24</date>
+  </refsect1info>
+  <title>
+   Description
+  </title>
+
+  <para>
+   <command>CREATE DOMAIN</command>  allows  the user to register a new user data
+   domain with PostgreSQL for use in the current data base.   The
+   user  who  defines  a domain becomes its owner.
+   <replaceable class="parameter">domainname</replaceable> is
+   the name of the new type and must  be  unique  within  the
+   types and domains defined for this database.
+  </para>
+
+  <para>
+   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.
+  </para>
+ </refsect1>
+
+ <refsect1>
+  <title>Examples</title>
+  <para>
+   This example creates the <type>country_code</type> data type and then uses the
+   type in a table definition:
+<programlisting>
+CREATE DOMAIN country_code char(2) NOT NULL;
+CREATE TABLE countrylist (id INT4, country country_code);
+</programlisting>
+  </para>
+ </refsect1>
+
+ <refsect1 id="SQL-CREATEDOMAIN-compatibility">
+  <title>Compatibility</title>
+
+  <para>
+   This <command>CREATE DOMAIN</command> command is a
+   <productname>PostgreSQL</productname> extension.  CHECK and FOREIGN KEY
+   constraints are currently unsupported.
+  </para>
+ </refsect1>
+
+ <refsect1 id="SQL-CREATEDOMAIN-see-also">
+  <title>See Also</title>
+
+  <simplelist type="inline">
+   <member><xref linkend="sql-dropdomain"></member>
+   <member><citetitle>PostgreSQL Programmer's Guide</citetitle></member>
+  </simplelist>
+ </refsect1>
+
+</refentry>
+
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:"../reference.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:"/usr/lib/sgml/catalog"
+sgml-local-ecat-files:nil
+End:
+-->
diff --git a/doc/src/sgml/ref/drop_domain.sgml b/doc/src/sgml/ref/drop_domain.sgml
new file mode 100644 (file)
index 0000000..d508d6a
--- /dev/null
@@ -0,0 +1,167 @@
+<!--
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_domain.sgml,v 1.1 2002/03/06 20:34:44 momjian Exp $
+PostgreSQL documentation
+-->
+
+<refentry id="SQL-DROPDOMAIN">
+ <refmeta>
+  <refentrytitle id="SQL-DROPDOMAIN-TITLE">
+   DROP DOMAIN
+  </refentrytitle>
+  <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+ <refnamediv>
+  <refname>
+   DROP DOMAIN
+  </refname>
+  <refpurpose>
+   remove a user-defined domain
+  </refpurpose>
+ </refnamediv>
+ <refsynopsisdiv>
+  <refsynopsisdivinfo>
+   <date>1999-07-20</date>
+  </refsynopsisdivinfo>
+  <synopsis>
+DROP DOMAIN <replaceable class="PARAMETER">domainname</replaceable> [, ...]
+  </synopsis>
+
+  <refsect2 id="R2-SQL-DROPDOMAIN-1">
+   <refsect2info>
+    <date>2002-02-24</date>
+   </refsect2info>
+   <title>
+    Inputs
+   </title>
+   <para>
+    <variablelist>
+     <varlistentry>
+      <term><replaceable class="PARAMETER">domainname</replaceable></term>
+      <listitem>
+       <para>
+       The name of an existing domain.
+       </para>
+      </listitem>
+     </varlistentry>
+    </variablelist>
+   </para>
+  </refsect2>
+
+  <refsect2 id="R2-SQL-DROPDOMAIN-2">
+   <refsect2info>
+    <date>2002-02-24</date>
+   </refsect2info>
+   <title>
+    Outputs
+   </title>
+   <para>
+    <variablelist>
+     <varlistentry>
+      <term><computeroutput>
+DROP
+       </computeroutput></term>
+      <listitem>
+       <para>
+       The message returned if the command is successful.
+       </para>
+      </listitem>
+     </varlistentry>
+     <varlistentry>
+      <term><computeroutput>
+ERROR:  RemoveDomain: type '<replaceable class="parameter">domainname</replaceable>' does not exist
+       </computeroutput></term>
+      <listitem>
+       <para>
+       This message occurs if the specified domain (or type) is not found.
+       </para>
+      </listitem>
+     </varlistentry>
+    </variablelist>
+   </para>
+  </refsect2>
+ </refsynopsisdiv>
+
+ <refsect1 id="R1-SQL-DROPDOMAIN-1">
+  <refsect1info>
+   <date>2002-02-24</date>
+  </refsect1info>
+  <title>
+   Description
+  </title>
+  <para>
+   <command>DROP DOMAIN</command> will remove a user domain from the
+   system catalogs.
+  </para>
+  <para>
+   Only the owner of a domain can remove it.
+  </para>
+ </refsect1>
+
+ <refsect1 id="SQL-DROPDOMAIN-notes">
+  <title>Notes</title>
+
+  <itemizedlist>
+   <listitem>
+    <para>
+     It is the user's responsibility to remove any operators,
+     functions, aggregates, access methods, and tables that
+     use a deleted domain.
+    </para>
+   </listitem>
+  </itemizedlist>
+ </refsect1>
+
+ <refsect1 id="SQL-DROPDOMAIN-examples">
+  <title>Examples</title>
+  <para>
+   To remove the <type>box</type> domain:
+
+<programlisting>
+DROP DOMAIN box RESTRICT;
+</programlisting>
+  </para>
+ </refsect1>
+
+ <refsect1 id="SQL-DROPDOMAIN-compatibility">
+  <title>Compatibility</title>
+
+  <para>
+   A <command>DROP DOMAIN</command> statement exists in SQL99.  As with
+   most other <quote>drop</quote> commands, <command>DROP
+   DOMAIN</command> in SQL99 requires a <quote>drop behavior</quote>
+   clause to select between dropping all dependent objects or refusing
+   to drop if dependent objects exist:
+<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.
+  </para>
+ </refsect1>
+
+ <refsect1 id="SQL-DROPDOMAIN-see-also">
+  <title>See Also</title>
+
+  <simplelist type="inline">
+   <member><xref linkend="sql-createdomain"></member>
+  </simplelist>
+ </refsect1>
+</refentry>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:"../reference.ced"
+sgml-exposed-tags:nil
+sgml-local-catalogs:"/usr/lib/sgml/catalog"
+sgml-local-ecat-files:nil
+End:
+-->
index 27f218d33fb6d7e69e34b7e4f7b9618797a77baf..14fd89b0a4f6a795c423611d86c8c9779922ccc4 100644 (file)
@@ -1,5 +1,5 @@
 <!-- reference.sgml
-$Header: /cvsroot/pgsql/doc/src/sgml/reference.sgml,v 1.21 2002/03/01 22:45:04 petere Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/reference.sgml,v 1.22 2002/03/06 20:34:43 momjian Exp $
 
 PostgreSQL Reference Manual
 -->
@@ -61,6 +61,7 @@ PostgreSQL Reference Manual
    &createAggregate;
    &createConstraint;
    &createDatabase;
+   &createDomain;
    &createFunction;
    &createGroup;
    &createIndex;
@@ -78,6 +79,7 @@ PostgreSQL Reference Manual
    &delete;
    &dropAggregate;
    &dropDatabase;
+   &dropDomain;
    &dropFunction;
    &dropGroup;
    &dropIndex;
@@ -115,7 +117,7 @@ PostgreSQL Reference Manual
    &unlisten;
    &update;
    &vacuum;
-  
+
  </reference>
 
 <!--
index 61fc2a451b93f472011f0cac127260ef8d8101e7..2b55700f3ada09577fd3ec44a536443d10b85315 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.184 2002/03/06 06:09:25 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.185 2002/03/06 20:34:45 momjian Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -698,10 +698,15 @@ AddNewRelationType(char *typeName, Oid new_rel_oid, Oid new_type_oid)
                           "oidin",                     /* receive procedure */
                           "oidout",            /* send procedure */
                           NULL,                        /* array element type - irrelevant */
+                          NULL,                        /* baseType Name -- typically for domiains */
                           NULL,                        /* default type value - none */
+                          NULL,                        /* default type binary representation */
                           true,                        /* passed by value */
                           'i',                         /* default alignment - same as for OID */
-                          'p');                        /* Not TOASTable */
+                          'p',                         /* Not TOASTable */
+                          -1,                          /* Type mod length */
+                          0,                           /* array dimensions for typBaseType */
+                          false);                      /* Type NOT NULL */
 }
 
 /* --------------------------------
@@ -1584,6 +1589,10 @@ AddRelationRawConstraints(Relation rel,
        int                     numchecks;
        List       *listptr;
 
+       /* Probably shouldn't be null by default */
+       Node       *expr = NULL;
+
+
        /*
         * Get info about existing constraints.
         */
@@ -1614,68 +1623,13 @@ AddRelationRawConstraints(Relation rel,
        foreach(listptr, rawColDefaults)
        {
                RawColumnDefault *colDef = (RawColumnDefault *) lfirst(listptr);
-               Node       *expr;
-               Oid                     type_id;
-
-               Assert(colDef->raw_default != NULL);
-
-               /*
-                * Transform raw parsetree to executable expression.
-                */
-               expr = transformExpr(pstate, colDef->raw_default, EXPR_COLUMN_FIRST);
-
-               /*
-                * Make sure default expr does not refer to any vars.
-                */
-               if (contain_var_clause(expr))
-                       elog(ERROR, "cannot use column references in DEFAULT clause");
-
-               /*
-                * No subplans or aggregates, either...
-                */
-               if (contain_subplans(expr))
-                       elog(ERROR, "cannot use subselects in DEFAULT clause");
-               if (contain_agg_clause(expr))
-                       elog(ERROR, "cannot use aggregate functions in DEFAULT clause");
 
-               /*
-                * Check that it will be possible to coerce the expression to the
-                * column's type.  We store the expression without coercion,
-                * however, to avoid premature coercion in cases like
-                *
-                * CREATE TABLE tbl (fld datetime DEFAULT 'now'::text);
-                *
-                * NB: this should match the code in optimizer/prep/preptlist.c that
-                * will actually do the coercion, to ensure we don't accept an
-                * unusable default expression.
-                */
-               type_id = exprType(expr);
-               if (type_id != InvalidOid)
-               {
-                       Form_pg_attribute atp = rel->rd_att->attrs[colDef->attnum - 1];
 
-                       if (type_id != atp->atttypid)
-                       {
-                               if (CoerceTargetExpr(NULL, expr, type_id,
-                                                                 atp->atttypid, atp->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",
-                                                NameStr(atp->attname),
-                                                format_type_be(atp->atttypid),
-                                                format_type_be(type_id));
-                       }
-               }
+               Form_pg_attribute atp = rel->rd_att->attrs[colDef->attnum - 1];
 
-               /*
-                * Might as well try to reduce any constant expressions.
-                */
-               expr = eval_const_expressions(expr);
-
-               /*
-                * Must fix opids, in case any operators remain...
-                */
-               fix_opids(expr);
+               expr = cookDefault(pstate, colDef->raw_default
+                                               , atp->atttypid, atp->atttypmod
+                                               , NameStr(atp->attname));
 
                /*
                 * OK, store it.
@@ -1892,6 +1846,88 @@ SetRelationNumChecks(Relation rel, int numchecks)
        heap_close(relrel, RowExclusiveLock);
 }
 
+/*
+ * 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().
+ */
+Node *
+cookDefault(ParseState *pstate
+                       , Node *raw_default
+                       , Oid atttypid
+                       , int32 atttypmod
+                       , char *attname) {
+
+       Oid                     type_id;
+       Node            *expr;
+
+       Assert(raw_default != NULL);
+
+       /*
+        * Transform raw parsetree to executable expression.
+        */
+       expr = transformExpr(pstate, raw_default, EXPR_COLUMN_FIRST);
+
+       /*
+        * Make sure default expr does not refer to any vars.
+        */
+       if (contain_var_clause(expr))
+               elog(ERROR, "cannot use column references in DEFAULT clause");
+
+       /*
+        * No subplans or aggregates, either...
+        */
+       if (contain_subplans(expr))
+               elog(ERROR, "cannot use subselects in DEFAULT clause");
+       if (contain_agg_clause(expr))
+               elog(ERROR, "cannot use aggregate functions in DEFAULT clause");
+
+       /*
+        * Check that it will be possible to coerce the expression to the
+        * column's type.  We store the expression without coercion,
+        * however, to avoid premature coercion in cases like
+        *
+        * CREATE TABLE tbl (fld datetime DEFAULT 'now'::text);
+        *
+        * NB: this should match the code in optimizer/prep/preptlist.c that
+        * 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) {
+
+                       /* Try coercing to the base type of the domain if available */
+                       if (CoerceTargetExpr(pstate, expr, type_id,
+                                                                getBaseType(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",
+                                        attname,
+                                        format_type_be(atttypid),
+                                        format_type_be(type_id));
+                       }
+               }
+       }
+
+       /*
+        * Might as well try to reduce any constant expressions.
+        */
+       expr = eval_const_expressions(expr);
+
+       /*
+        * Must fix opids, in case any operators remain...
+        */
+       fix_opids(expr);
+
+       return(expr);
+}
+
+
 static void
 RemoveAttrDefaults(Relation rel)
 {
index f14d06e0e273addeaf7da64d88a21d66c1ec1b3a..9991465a619412cb2cb7fe8d7ab66fe34363a639 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.65 2001/10/25 05:49:23 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.66 2002/03/06 20:34:46 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -178,8 +178,13 @@ TypeShellMakeWithOpenRelation(Relation pg_type_desc, char *typeName)
        values[i++] = ObjectIdGetDatum(InvalidOid); /* 14 */
        values[i++] = CharGetDatum('i');        /* 15 */
        values[i++] = CharGetDatum('p');        /* 16 */
+               values[i++] = BoolGetDatum(false);      /* 17 */
+                       values[i++] = Int32GetDatum(-1);        /* 18 */
        values[i++] = DirectFunctionCall1(textin,
-                                                                         CStringGetDatum(typeName));           /* 17 */
+                                                                         CStringGetDatum(typeName));           /* 19 */
+       values[i++] = DirectFunctionCall1(textin,
+                                                                         CStringGetDatum(typeName));           /* 20 */
+
 
        /*
         * create a new type tuple with FormHeapTuple
@@ -264,7 +269,7 @@ TypeShellMake(char *typeName)
 Oid
 TypeCreate(char *typeName,
                   Oid assignedTypeOid,
-                  Oid relationOid,             /* only for 'c'atalog typeTypes */
+                  Oid relationOid,                     /* only for 'c'atalog typeTypes */
                   int16 internalSize,
                   int16 externalSize,
                   char typeType,
@@ -274,10 +279,15 @@ TypeCreate(char *typeName,
                   char *receiveProcedure,
                   char *sendProcedure,
                   char *elementTypeName,
-                  char *defaultTypeValue,              /* internal rep */
+                  char *baseTypeName,
+                  char *defaultTypeValue,      /* human readable rep */
+                  char *defaultTypeBin,        /* cooked rep */
                   bool passedByValue,
                   char alignment,
-                  char storage)
+                  char storage,
+                  int32 typeMod,
+                  int32 typNDims,                      /* Array dimensions for baseTypeName */
+                  bool typeNotNull)            /* binary default representation (cooked) */
 {
        int                     i,
                                j;
@@ -285,6 +295,7 @@ TypeCreate(char *typeName,
        HeapScanDesc pg_type_scan;
        Oid                     typeObjectId;
        Oid                     elementObjectId = InvalidOid;
+       Oid                     baseObjectId = InvalidOid;
        HeapTuple       tup;
        char            nulls[Natts_pg_type];
        char            replaces[Natts_pg_type];
@@ -317,6 +328,17 @@ TypeCreate(char *typeName,
                        elog(ERROR, "type %s does not exist", elementTypeName);
        }
 
+       /*
+        * if this type has an associated baseType, then we check that it
+        * is defined.
+        */
+       if (baseTypeName)
+       {
+               baseObjectId = TypeGet(baseTypeName, &defined);
+               if (!defined)
+                       elog(ERROR, "type %s does not exist", baseTypeName);
+       }
+
        /*
         * validate size specifications: either positive (fixed-length) or -1
         * (variable-length).
@@ -388,7 +410,7 @@ TypeCreate(char *typeName,
                         * signature is 0,OIDOID,INT4OID.  The output procedures may
                         * take 2 args (data value, element OID).
                         */
-                       if (OidIsValid(elementObjectId))
+                       if (OidIsValid(elementObjectId) || OidIsValid(baseObjectId))
                        {
                                int                     nargs;
 
@@ -411,6 +433,7 @@ TypeCreate(char *typeName,
                                                                                 PointerGetDatum(argList),
                                                                                 0);
                        }
+
                        if (!OidIsValid(procOid))
                                func_error("TypeCreate", procname, 1, argList, NULL);
                }
@@ -428,6 +451,34 @@ 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
+        */
+       values[i++] = Int32GetDatum(typNDims);                  /* 20 */
+
+       /*
+        * initialize the default binary value for this type.  Check for
+        * nulls of course.
+        */
+       if (defaultTypeBin)
+               values[i] = DirectFunctionCall1(textin,
+                                                                         CStringGetDatum(defaultTypeBin));
+       else
+               nulls[i] = 'n';
+       i++;                                                                            /* 21 */
+
        /*
         * initialize the default value for this type.
         */
@@ -436,7 +487,7 @@ TypeCreate(char *typeName,
                                                                          CStringGetDatum(defaultTypeValue));
        else
                nulls[i] = 'n';
-       i++;                                            /* 17 */
+       i++;                                            /* 22 */
 
        /*
         * open pg_type and begin a scan for the type name.
index 27535429c39499b04cc479a05df8fd285cf66072..586cee63cce5bb3adb5778089801de59f063b1bd 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.83 2002/03/06 06:09:31 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.84 2002/03/06 20:34:46 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -39,7 +39,7 @@ static bool change_varattnos_of_a_node(Node *node, const AttrNumber *newattno);
 static void StoreCatalogInheritance(Oid relationId, List *supers);
 static int     findAttrByName(const char *attributeName, List *schema);
 static void setRelhassubclassInRelation(Oid relationId, bool relhassubclass);
-
+static List *MergeDomainAttributes(List *schema);
 
 /* ----------------------------------------------------------------
  *             DefineRelation
@@ -69,6 +69,13 @@ DefineRelation(CreateStmt *stmt, char relkind)
         */
        StrNCpy(relname, stmt->relname, NAMEDATALEN);
 
+       /*
+        * Merge domain attributes into the known columns before inheritance
+        * applies it's changes otherwise we risk adding double constraints
+        * to a domain thats inherited.
+        */
+       schema = MergeDomainAttributes(schema);
+
        /*
         * Look up inheritance ancestors and generate relation schema,
         * including inherited attributes.
@@ -237,6 +244,88 @@ TruncateRelation(char *name)
        heap_truncate(name);
 }
 
+
+/*
+ * MergeDomainAttributes
+ *      Returns a new schema with the constraints, types, and other
+ *      attributes of the domain resolved.
+ *
+ * Defaults are processed at execution time by taking the default of
+ * the type (domain) if it is null.  This does not need to be merged
+ * here.
+ */
+static List *
+MergeDomainAttributes(List *schema)
+{
+       List       *entry;
+
+       /*
+        * Loop through the table elements supplied. These should
+        * never include inherited domains else they'll be
+        * double (or more) processed.
+        */
+       foreach(entry, schema)
+       {
+               ColumnDef  *coldef = lfirst(entry);
+               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;
+
+                       /* 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?
+                        */
+
+               }
+               ReleaseSysCache(tuple);
+
+//typedef struct TypeName
+//{
+       //NodeTag               type;
+       //char     *name;                       /* name of the type */
+       //bool          timezone;               /* timezone specified? */
+       //bool          setof;                  /* is a set? */
+       //int32         typmod;                 /* type modifier */
+       //List     *arrayBounds;        /* array bounds */
+       //char     *attrname;           /* field name when using %TYPE */
+//} TypeName;
+
+// ColumnDef
+//             NodeTag         type;
+//             char       *colname;            /* name of column */
+//             TypeName   *typename;           /* type of column */
+//             bool            is_not_null;    /* NOT NULL constraint specified? */
+//             Node       *raw_default;        /* default value (untransformed parse
+//                                                              * tree) */
+//             char       *cooked_default; /* nodeToString representation */
+//             List       *constraints;        /* other constraints on column */
+
+       }
+
+       return schema;
+}
+
 /*----------
  * MergeAttributes
  *             Returns new schema given initial schema and superclasses.
index 841fc73c30939c512722eb3e054b8a8933dc6e0f..cb71340eb2c61ccbf8b1125b100a949cf963ca7b 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.67 2002/03/06 06:09:32 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.68 2002/03/06 20:34:47 momjian Exp $
  *
  * DESCRIPTION
  *       The "DefineFoo" routines take the parse tree and pick out the
@@ -40,6 +40,7 @@
 
 #include "access/heapam.h"
 #include "catalog/catname.h"
+#include "catalog/heap.h"
 #include "catalog/pg_aggregate.h"
 #include "catalog/pg_language.h"
 #include "catalog/pg_operator.h"
@@ -475,6 +476,322 @@ DefineAggregate(char *aggName, List *parameters)
                                        initval);       /* initial condition */
 }
 
+/*
+ * DefineDomain
+ *             Registers a new domain.
+ */
+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 */
+       char            typtype;
+       Datum           datum;
+       bool            typNotNull = false;
+       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;
+
+       /*
+        * Domainnames, unlike typenames don't need to account for the '_'
+        * prefix.  So they can be one character longer.
+        */
+       if (strlen(stmt->domainname) > (NAMEDATALEN - 1))
+               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
+                                                       );
+
+       if (HeapTupleIsValid(typeTup))
+       {
+               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
+        * the name here.  We receive the base types name.  Lets set Dims while
+        * were at it.
+        */
+       if (stmt->typename->arrayBounds > 0) {
+               typeName = makeArrayTypeName(stmt->typename->name);
+
+               typNDims = length(stmt->typename->arrayBounds);
+       }
+
+
+       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
+        * of neat issues if we allow that.
+        *
+        * With testing, we may determine complex types should be allowed
+        */
+       if (typtype != 'b') {
+               elog(ERROR, "DefineDomain: %s is not a basetype", stmt->typename->name);
+       }
+
+       /* passed by value */
+       byValue =                       DatumGetBool(heap_getattr(typeTup, Anum_pg_type_typbyval, pg_type_dsc, &isnull));
+       Assert(!isnull);
+
+       /* Required Alignment */
+       alignment =             DatumGetChar(heap_getattr(typeTup, Anum_pg_type_typalign, pg_type_dsc, &isnull));
+       Assert(!isnull);
+
+       /* Storage Length */
+       internalLength =        DatumGetInt16(heap_getattr(typeTup, Anum_pg_type_typlen, pg_type_dsc, &isnull));
+       Assert(!isnull);
+
+       /* External Length (unused) */
+       externalLength =        DatumGetInt16(heap_getattr(typeTup, Anum_pg_type_typprtlen, pg_type_dsc, &isnull));
+       Assert(!isnull);
+
+       /* Array element Delimiter */
+       delimiter =             DatumGetChar(heap_getattr(typeTup, Anum_pg_type_typdelim, pg_type_dsc, &isnull));
+       Assert(!isnull);
+
+       /* Input Function Name */
+       datum =                         heap_getattr(typeTup, Anum_pg_type_typinput, pg_type_dsc, &isnull);
+       Assert(!isnull);
+
+       inputName =             DatumGetCString(DirectFunctionCall1(regprocout, datum));
+
+       /* Output Function Name */
+       datum =                         heap_getattr(typeTup, Anum_pg_type_typoutput, pg_type_dsc, &isnull);
+       Assert(!isnull);
+
+       outputName =            DatumGetCString(DirectFunctionCall1(regprocout, datum));
+
+       /* ReceiveName */
+       datum =                         heap_getattr(typeTup, Anum_pg_type_typreceive, pg_type_dsc, &isnull);
+       Assert(!isnull);
+
+       receiveName =           DatumGetCString(DirectFunctionCall1(regprocout, datum));
+
+       /* SendName */
+       datum =                         heap_getattr(typeTup, Anum_pg_type_typsend, pg_type_dsc, &isnull);
+       Assert(!isnull);
+
+       sendName =                      DatumGetCString(DirectFunctionCall1(regprocout, datum));
+
+       /* TOAST Strategy */
+       storage =                       DatumGetChar(heap_getattr(typeTup, Anum_pg_type_typstorage, pg_type_dsc, &isnull));
+       Assert(!isnull);
+
+       /* Inherited default value */
+       datum =                         heap_getattr(typeTup, Anum_pg_type_typdefault, pg_type_dsc, &isnull);
+       if (!isnull) {
+               defaultValue =  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) {
+               HeapTuple tup;
+
+               tup = SearchSysCache( TYPEOID
+                                                       , datum
+                                                       , 0, 0, 0
+                                                       );
+
+               elemName = NameStr(((Form_pg_type) GETSTRUCT(tup))->typname);
+
+               ReleaseSysCache(tup);
+       }
+
+
+       /*
+        * Run through constraints manually avoids the additional
+        * processing conducted by DefineRelation() and friends.
+        *
+        * Besides, we don't want any constraints to be cooked.  We'll
+        * do that when the table is created via MergeDomainAttributes().
+        */
+       foreach(listptr, schema)
+       {
+               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) {
+                       /*
+                        * The inherited default value may be overridden by the user
+                        * with the DEFAULT <expr> statement.
+                        *
+                        * We have to search the entire constraint tree returned as we
+                        * don't want to cook or fiddle too much.
+                        */
+                       case CONSTR_DEFAULT:
+
+                               /*
+                                * Cook the colDef->raw_expr into an expression to ensure
+                                * that it can be done.  We store the text version of the
+                                * raw value.
+                                *
+                                * 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 */
+                               defaultValue = deparse_expression(expr,
+                                                               deparse_context_for(stmt->domainname,
+                                                                                                       InvalidOid),
+                                                                                                  false);
+
+                               defaultValueBin = nodeToString(expr);
+
+                               break;
+
+                       /*
+                        * Find the NULL constraint.
+                        */
+                       case CONSTR_NOTNULL:
+                               if (nullDefined) {
+                                       elog(ERROR, "CREATE DOMAIN has conflicting NULL / NOT NULL constraint");
+                               } else {
+                                       typNotNull = true;
+                                       nullDefined = true;
+                               }
+
+                               break;
+
+                       case CONSTR_NULL:
+                               if (nullDefined) {
+                                       elog(ERROR, "CREATE DOMAIN has conflicting NULL / NOT NULL constraint");
+                               } else {
+                                       typNotNull = false;
+                                       nullDefined = true;
+                               }
+
+                               break;
+
+                       case CONSTR_UNIQUE:
+                               elog(ERROR, "CREATE DOMAIN / UNIQUE indecies not supported");
+                               break;
+
+                       case CONSTR_PRIMARY:
+                               elog(ERROR, "CREATE DOMAIN / PRIMARY KEY indecies not supported");
+                               break;
+
+
+                       case CONSTR_CHECK:
+
+                               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");
+                               break;
+               }
+
+       }
+
+       /*
+        * Have TypeCreate do all the real work.
+        */
+       TypeCreate(stmt->domainname,    /* type name */
+                          InvalidOid,                  /* preassigned type oid (not done here) */
+                          InvalidOid,                  /* relation oid (n/a here) */
+                          internalLength,              /* internal size */
+                          externalLength,              /* external size */
+                          'd',                                 /* type-type (domain type) */
+                          delimiter,                   /* array element delimiter */
+                          inputName,                   /* input procedure */
+                          outputName,                  /* output procedure */
+                          receiveName,                 /* receive procedure */
+                          sendName,                    /* send procedure */
+                          elemName,                    /* element type name */
+                          typeName,                    /* base type name */
+                          defaultValue,                /* default type value */
+                          defaultValueBin,             /* default type value */
+                          byValue,                             /* passed by value */
+                          alignment,                   /* required alignment */
+                          storage,                             /* TOAST strategy */
+                          stmt->typename->typmod, /* typeMod value */
+                          typNDims,                    /* Array dimensions for base type */
+                          typNotNull); /* Type NOT NULL */
+
+       /*
+        * Now we can clean up.
+        */
+       ReleaseSysCache(typeTup);
+       heap_close(pg_type_rel, NoLock);
+}
+
+
 /*
  * DefineType
  *             Registers a new type.
@@ -490,6 +807,8 @@ 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;
@@ -531,7 +850,7 @@ DefineType(char *typeName, List *parameters)
                else if (strcasecmp(defel->defname, "element") == 0)
                        elemName = defGetString(defel);
                else if (strcasecmp(defel->defname, "default") == 0)
-                       defaultValue = defGetString(defel);
+                       defaultRaw = defel->arg;
                else if (strcasecmp(defel->defname, "passedbyvalue") == 0)
                        byValue = true;
                else if (strcasecmp(defel->defname, "alignment") == 0)
@@ -591,6 +910,32 @@ 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.
         */
@@ -606,10 +951,15 @@ DefineType(char *typeName, List *parameters)
                           receiveName,         /* receive procedure */
                           sendName,            /* send procedure */
                           elemName,            /* element type name */
+                          NULL,                        /* base type name (Non-zero for domains) */
                           defaultValue,        /* default type value */
+                          defaultValueBin,     /* default type value (Binary form) */
                           byValue,                     /* passed by value */
                           alignment,           /* required alignment */
-                          storage);            /* TOAST strategy */
+                          storage,                     /* TOAST strategy */
+                          -1,                          /* typMod (Domains only) */
+                          0,                           /* Array Dimensions of typbasetype */
+                          'f');                        /* Type NOT NULL */
 
        /*
         * When we create a base type (as opposed to a complex type) we need
@@ -632,10 +982,15 @@ DefineType(char *typeName, List *parameters)
                           "array_in",          /* receive procedure */
                           "array_out",         /* send procedure */
                           typeName,            /* element type name */
+                          NULL,                        /* base type name */
                           NULL,                        /* never a default type value */
+                          NULL,                        /* binary default isn't sent either */
                           false,                       /* never passed by value */
                           alignment,           /* see above */
-                          'x');                        /* ARRAY is always toastable */
+                          'x',                         /* ARRAY is always toastable */
+                          -1,                          /* typMod (Domains only) */
+                          0,                           /* Array dimensions of typbasetype */
+                          'f');                        /* Type NOT NULL */
 
        pfree(shadow_type);
 }
index a0456adeb930dc186971072f623d6c4f281dc2be..69e6e1b9000b48191151736256b974c3a8e25f5d 100644 (file)
@@ -1,14 +1,14 @@
 /*-------------------------------------------------------------------------
  *
  * remove.c
- *       POSTGRES remove (function | type | operator ) utilty code.
+ *       POSTGRES remove (domain | function | type | operator ) utilty code.
  *
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.66 2002/03/06 06:09:35 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.67 2002/03/06 20:34:47 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -22,6 +22,7 @@
 #include "commands/comment.h"
 #include "commands/defrem.h"
 #include "miscadmin.h"
+#include "parser/parse.h"
 #include "parser/parse_agg.h"
 #include "parser/parse_expr.h"
 #include "parser/parse_func.h"
@@ -275,6 +276,60 @@ RemoveType(char *typeName)         /* type name to be removed */
        heap_close(relation, RowExclusiveLock);
 }
 
+/*
+ *     RemoveDomain
+ *             Removes the domain 'typeName' and all attributes and relations that
+ *             use it.
+ */
+void
+RemoveDomain(char *domainName, int behavior)           /* domain name to be removed */
+{
+       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),
+                                                0, 0, 0);
+       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);
+
+       if (typtype != 'd') {
+               elog(ERROR, "%s is not a domain", domainName);
+       }
+
+       /* CASCADE unsupported */
+       if (behavior == CASCADE) {
+               elog(ERROR, "DROP DOMAIN does not support the CASCADE keyword");
+       }
+
+       /* Delete any comments associated with this type */
+       DeleteComments(tup->t_data->t_oid, RelationGetRelid(relation));
+
+       simple_heap_delete(relation, &tup->t_self);
+
+       ReleaseSysCache(tup);
+
+       heap_close(relation, RowExclusiveLock);
+}
+
 /*
  * RemoveFunction
  *             Deletes a function.
index d3fe436ac77755e9578619e3c4dffd1c16fc7872..07acc5dde66308faf84d51a3eeb8b9b46bb74da8 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.165 2002/03/01 22:45:11 petere Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.166 2002/03/06 20:34:47 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2227,6 +2227,19 @@ _copyLoadStmt(LoadStmt *from)
        return newnode;
 }
 
+static CreateDomainStmt *
+_copyCreateDomainStmt(CreateDomainStmt *from)
+{
+       CreateDomainStmt *newnode = makeNode(CreateDomainStmt);
+
+       if (from->domainname)
+               newnode->domainname = pstrdup(from->domainname);
+       if (from->typename)
+               newnode->typename = from->typename;
+
+       return newnode;
+}
+
 static CreatedbStmt *
 _copyCreatedbStmt(CreatedbStmt *from)
 {
index 661190dbaa86cec45861f8f2d4849b5c7ea21861..962471a5a97647d307205d9bd088d2bf7a531d42 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.113 2002/03/06 06:09:49 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.114 2002/03/06 20:34:48 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1095,6 +1095,17 @@ _equalLoadStmt(LoadStmt *a, LoadStmt *b)
        return true;
 }
 
+static bool
+_equalCreateDomainStmt(CreateDomainStmt *a, CreateDomainStmt *b)
+{
+       if (!equalstr(a->domainname, b->domainname))
+               return false;
+       if (!equal(a->typename, b->typename))
+               return false;
+
+       return true;
+}
+
 static bool
 _equalCreatedbStmt(CreatedbStmt *a, CreatedbStmt *b)
 {
@@ -2011,6 +2022,9 @@ equal(void *a, void *b)
                case T_LoadStmt:
                        retval = _equalLoadStmt(a, b);
                        break;
+               case T_CreateDomainStmt:
+                       retval = _equalCreateDomainStmt(a, b);
+                       break;
                case T_CreatedbStmt:
                        retval = _equalCreatedbStmt(a, b);
                        break;
index 4f637f48d1a0791fd982a4e84bc2440fbb6904fd..d8b376ba8cecba667664b9f4747ef0293ac4064f 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.46 2001/11/05 17:46:26 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.47 2002/03/06 20:34:49 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -355,7 +355,6 @@ 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;
-       bool            hasdefault;
        Datum           typedefault;
        int16           typlen;
        bool            typbyval;
@@ -392,7 +391,7 @@ build_column_default(Relation rel, int attrno)
                                if (type_id != atttype)
                                {
                                        expr = CoerceTargetExpr(NULL, expr, type_id,
-                                                                                       atttype, atttypmod);
+                                                                                       getBaseType(atttype), atttypmod);
 
                                        /*
                                         * This really shouldn't fail; should have checked the
@@ -430,41 +429,53 @@ build_column_default(Relation rel, int attrno)
                 * element type is, and the element type's default is irrelevant
                 * too.
                 */
-               hasdefault = false;
-               typedefault = (Datum) 0;
                typlen = sizeof(Oid);
                typbyval = true;
+
+               expr = (Node *) makeConst(atttype,
+                                                                 typlen,
+                                                                 (Datum) 0,
+                                                                 true,
+                                                                 typbyval,
+                                                                 false,           /* not a set */
+                                                                 false);
        }
        else
        {
 #ifdef _DROP_COLUMN_HACK__
                if (COLUMN_IS_DROPPED(att_tup))
                {
-                       hasdefault = false;
-                       typedefault = (Datum) 0;
+
+                       expr = (Node *) makeConst(atttype,
+                                                                         typlen,
+                                                                         (Datum) 0,
+                                                                         true,
+                                                                         typbyval,
+                                                                         false,           /* not a set */
+                                                                         false);
                }
                else
 #endif   /* _DROP_COLUMN_HACK__ */
-                       hasdefault = get_typdefault(atttype, &typedefault);
-
+                       expr = get_typdefault(atttype, atttypmod);
+
+               if (expr == NULL) {
+                               expr = (Node *) makeConst(atttype,
+                                                                                 typlen,
+                                                                                 (Datum) 0,
+                                                                                 true,
+                                                                                 typbyval,
+                                                                                 false,                /* not a set */
+                                                                                 false);
+               }
                get_typlenbyval(atttype, &typlen, &typbyval);
        }
 
-       expr = (Node *) makeConst(atttype,
-                                                         typlen,
-                                                         typedefault,
-                                                         !hasdefault,
-                                                         typbyval,
-                                                         false,        /* not a set */
-                                                         false);
-
        /*
         * If the column is a fixed-length type, it may need a length coercion
-        * as well as a type coercion.  But NULLs don't need that.
+        * as well as a type coercion, as well as direction to the final type.
         */
-       if (hasdefault)
-               expr = coerce_type_typmod(NULL, expr,
-                                                                 atttype, atttypmod);
+       expr = coerce_type_typmod(NULL, expr,
+                                                         atttype, atttypmod);
 
        return expr;
 }
index a8aba404e76d91724905fe7919eab516df15256b..c1b46650917fe0c38c1d49b1a7bb8c38af70fadb 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.285 2002/03/06 06:09:53 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.286 2002/03/06 20:34:49 momjian Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -135,7 +135,8 @@ static void doNegateFloat(Value *v);
                ClosePortalStmt, ClusterStmt, CommentStmt, ConstraintsSetStmt,
                CopyStmt, CreateAsStmt, CreateGroupStmt, CreatePLangStmt,
                CreateSchemaStmt, CreateSeqStmt, CreateStmt, CreateTrigStmt,
-               CreateUserStmt, CreatedbStmt, CursorStmt, DefineStmt, DeleteStmt,
+               CreateUserStmt, CreateDomainStmt, CreatedbStmt, CursorStmt,
+               DefineStmt, DeleteStmt,
                DropGroupStmt, DropPLangStmt, DropSchemaStmt, DropStmt, DropTrigStmt,
                DropUserStmt, DropdbStmt, ExplainStmt, FetchStmt,
                GrantStmt, IndexStmt, InsertStmt, ListenStmt, LoadStmt, LockStmt,
@@ -289,6 +290,8 @@ static void doNegateFloat(Value *v);
 %type <list>   constraints_set_namelist
 %type <boolean>        constraints_set_mode
 
+%type <boolean> opt_as
+
 /*
  * If you make any token changes, remember to:
  *             - use "yacc -d" and update parse.h
@@ -343,7 +346,7 @@ static void doNegateFloat(Value *v);
                WITHOUT
 
 /* Keywords (in SQL92 non-reserved words) */
-%token COMMITTED, SERIALIZABLE, TYPE_P
+%token COMMITTED, SERIALIZABLE, TYPE_P, DOMAIN_P
 
 /* Keywords for Postgres support (not in SQL92 reserved words)
  *
@@ -446,6 +449,7 @@ stmt : AlterDatabaseSetStmt
                | CopyStmt
                | CreateStmt
                | CreateAsStmt
+               | CreateDomainStmt
                | CreateSchemaStmt
                | CreateGroupStmt
                | CreateSeqStmt
@@ -776,7 +780,10 @@ DropSchemaStmt:  DROP SCHEMA UserId
                                        n->dbname = $3;
                                        $$ = (Node *)n;
                                }
+               ;
+
 
 
 /*****************************************************************************
  *
@@ -1461,7 +1468,10 @@ ColConstraintElem:
                                        n->name = NULL;
                                        if (exprIsNullConstant($2))
                                        {
-                                               /* DEFAULT NULL should be reported as empty expr */
+                                               /*
+                                                * DEFAULT NULL should be reported as empty expr
+                                                * Required for NOT NULL Domain overrides
+                                                */
                                                n->raw_expr = NULL;
                                        }
                                        else
@@ -2043,7 +2053,16 @@ def_list:  def_elem                                                      { $$ = makeList1($1); }
                | def_list ',' def_elem                         { $$ = lappend($1, $3); }
                ;
 
-def_elem:  ColLabel '=' def_arg
+def_elem:  DEFAULT '=' b_expr
+                               {
+                                       $$ = makeNode(DefElem);
+                                       $$->defname = "default";
+                                       if (exprIsNullConstant($3))
+                                               $$->arg = (Node *)NULL;
+                                       else
+                                               $$->arg = $3;
+                               }
+               | ColLabel '=' def_arg
                                {
                                        $$ = makeNode(DefElem);
                                        $$->defname = $1;
@@ -2078,6 +2097,15 @@ DropStmt:  DROP drop_type name_list
                                        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;
                                }
                ;
@@ -2110,7 +2138,7 @@ TruncateStmt:  TRUNCATE opt_table relation_name
  *  The COMMENT ON statement can take different forms based upon the type of
  *  the object associated with the comment. The form of the statement is:
  *
- *  COMMENT ON [ [ DATABASE | INDEX | RULE | SEQUENCE | TABLE | TYPE | VIEW ] 
+ *  COMMENT ON [ [ DATABASE | DOMAIN | INDEX | RULE | SEQUENCE | TABLE | TYPE | VIEW ] 
  *               <objname> | AGGREGATE <aggname> (<aggtype>) | FUNCTION 
  *              <funcname> (arg1, arg2, ...) | OPERATOR <op> 
  *              (leftoperand_typ rightoperand_typ) | TRIGGER <triggername> ON
@@ -2196,6 +2224,7 @@ comment_type:     DATABASE { $$ = DATABASE; }
                | RULE { $$ = RULE; }
                | SEQUENCE { $$ = SEQUENCE; }
                | TABLE { $$ = TABLE; }
+               | DOMAIN_P { $$ = TYPE_P; }
                | TYPE_P { $$ = TYPE_P; }
                | VIEW { $$ = VIEW; }
                ;               
@@ -3222,6 +3251,30 @@ AlterDatabaseSetStmt: ALTER DATABASE database_name VariableSetStmt
                                }
                ;
 
+/*****************************************************************************
+ *
+ * Manipulate a domain
+ *
+ *
+ *****************************************************************************/
+
+CreateDomainStmt:  CREATE DOMAIN_P name opt_as Typename ColQualList opt_collate
+                               {
+                                       CreateDomainStmt *n = makeNode(CreateDomainStmt);
+                                       n->domainname = $3;
+                                       n->typename = $5;
+                                       n->constraints = $6;
+                                       
+                                       if ($7 != NULL)
+                                               elog(NOTICE,"CREATE DOMAIN / COLLATE %s not yet "
+                                                       "implemented; clause ignored", $7);
+                                       $$ = (Node *)n;
+                               }
+               ;
+
+opt_as:        AS      {$$ = TRUE; }
+       | /* EMPTY */   {$$ = FALSE; }
+       ;
 
 /*****************************************************************************
  *
@@ -5879,6 +5932,7 @@ unreserved_keyword:
                | DEFERRED                                              { $$ = "deferred"; }
                | DELETE                                                { $$ = "delete"; }
                | DELIMITERS                                    { $$ = "delimiters"; }
+               | DOMAIN_P                                              { $$ = "domain"; }
                | DOUBLE                                                { $$ = "double"; }
                | DROP                                                  { $$ = "drop"; }
                | EACH                                                  { $$ = "each"; }
index eaa0f7fa2b0424c051dc14c01397c0f74f05862f..02aff543d02679af0b9a263ee6fbb688bbd32321 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.101 2002/03/05 05:33:15 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.102 2002/03/06 20:34:50 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -97,6 +97,7 @@ static ScanKeyword ScanKeywords[] = {
        {"desc", DESC},
        {"distinct", DISTINCT},
        {"do", DO},
+       {"domain", DOMAIN_P},
        {"double", DOUBLE},
        {"drop", DROP},
        {"each", EACH},
index e81edb3efc530e2613667960f6963a0ded75a34e..8586d5e5cca5f98d8fb7353bc83b09d3ced1d914 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.64 2001/10/25 05:49:39 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.65 2002/03/06 20:34:51 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -38,6 +38,7 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId,
 {
        Node       *result;
 
+
        if (targetTypeId == inputTypeId ||
                targetTypeId == InvalidOid ||
                node == NULL)
@@ -605,3 +606,32 @@ 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
+ */
+Oid
+getBaseType(Oid inType)
+{
+       HeapTuple       tup;
+       Form_pg_type typTup;
+
+       tup = SearchSysCache(TYPEOID,
+                                                ObjectIdGetDatum(inType),
+                                                0, 0, 0);
+
+       typTup = ((Form_pg_type) GETSTRUCT(tup));
+
+       /*
+        * Assume that typbasetype exists and is a base type, where inType
+        * was a domain
+        */
+       if (typTup->typtype == 'd')
+               inType = typTup->typbasetype;
+
+       ReleaseSysCache(tup);
+
+       return inType;
+}
\ No newline at end of file
index 339999c0c6356de510073b896e81697031b82357..b095fa44b874e9d1adc2222d1d3144f8d800f8fe 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.105 2001/11/12 20:05:24 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.106 2002/03/06 20:34:52 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1027,7 +1027,8 @@ parser_typecast_expression(ParseState *pstate,
        if (inputType != targetType)
        {
                expr = CoerceTargetExpr(pstate, expr, inputType,
-                                                               targetType, typename->typmod);
+                                                               getBaseType(targetType),
+                                                               typename->typmod);
                if (expr == NULL)
                        elog(ERROR, "Cannot cast type '%s' to '%s'",
                                 format_type_be(inputType),
@@ -1039,7 +1040,7 @@ parser_typecast_expression(ParseState *pstate,
         * as well as a type coercion.
         */
        expr = coerce_type_typmod(pstate, expr,
-                                                         targetType, typename->typmod);
+                                                         getBaseType(targetType), typename->typmod);
 
        return expr;
 }
index 528b93012c2bbf9285a08bbd87172b4614e63076..947bca0553684d71259b4129c4e2bcff7fe647e5 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.129 2002/03/05 05:33:19 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.130 2002/03/06 20:34:52 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -282,6 +282,11 @@ ProcessUtility(Node *parsetree,
                                                        /* RemoveType does its own permissions checks */
                                                        RemoveType(relname);
                                                        break;
+
+                                               case DROP_DOMAIN_P:
+                                                       /* RemoveDomain does its own permissions checks */
+                                                       RemoveDomain(relname, stmt->behavior);
+                                                       break;
                                        }
 
                                        /*
@@ -742,6 +747,16 @@ ProcessUtility(Node *parsetree,
                        DropProceduralLanguage((DropPLangStmt *) parsetree);
                        break;
 
+                       /*
+                        * ******************************** DOMAIN statements ****
+                        *
+                        */
+               case T_CreateDomainStmt:
+                       set_ps_display(commandTag = "CREATE DOMAIN");
+
+                       DefineDomain((CreateDomainStmt *) parsetree);
+                       break;
+
                        /*
                         * ******************************** USER statements ****
                         *
index 960d0b2bcf065176eca473edd66df70b5e293ea0..b825a5b14d2edee5475993a2e2d5dbd74a81396b 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.24 2002/03/02 21:39:32 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/adt/format_type.c,v 1.25 2002/03/06 20:34:53 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -126,6 +126,7 @@ format_type_internal(Oid type_oid, int32 typemod,
        bool            is_array;
        char       *name;
        char       *buf;
+       char            typtype;
 
        if (type_oid == InvalidOid && allow_invalid)
                return pstrdup("-");
@@ -144,6 +145,31 @@ format_type_internal(Oid type_oid, int32 typemod,
 
        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)
        {
                /* Switch our attention to the array element type */
index 706397d28c6a25aa328a463e0eb6db9e4c96c5d2..3247c0aa8f6416d2b39b2b6312442e563eaaa49a 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.60 2002/03/01 04:09:26 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.61 2002/03/06 20:34:54 momjian Exp $
  *
  * NOTES
  *       Eventually, the index information should go through here, too.
@@ -23,6 +23,7 @@
 #include "catalog/pg_shadow.h"
 #include "catalog/pg_statistic.h"
 #include "catalog/pg_type.h"
+#include "parser/parse_coerce.h"
 #include "utils/array.h"
 #include "utils/builtins.h"
 #include "utils/lsyscache.h"
@@ -822,16 +823,17 @@ get_typstorage(Oid typid)
  *       Returns FALSE if there is no default (effectively, default is NULL).
  *       The result points to palloc'd storage for pass-by-reference types.
  */
-bool
-get_typdefault(Oid typid, Datum *defaultValue)
+Node *
+get_typdefault(Oid typid, int32 atttypmod)
 {
        HeapTuple       typeTuple;
        Form_pg_type type;
-       Oid                     typinput,
-                               typelem;
-       Datum           textDefaultVal;
+       Oid                     typinput;
+       Oid                     typbasetype;
+       char            typtype;
+       Datum           datum;
        bool            isNull;
-       char       *strDefaultVal;
+       Node       *expr;
 
        typeTuple = SearchSysCache(TYPEOID,
                                                           ObjectIdGetDatum(typid),
@@ -843,38 +845,41 @@ get_typdefault(Oid typid, Datum *defaultValue)
        type = (Form_pg_type) GETSTRUCT(typeTuple);
 
        typinput = type->typinput;
-       typelem = type->typelem;
+       typbasetype = type->typbasetype;
+       typtype = type->typtype;
 
        /*
-        * typdefault is potentially null, so don't try to access it as a
+        * typdefaultbin is potentially null, so don't try to access it as a
         * struct field. Must do it the hard way with SysCacheGetAttr.
         */
-       textDefaultVal = SysCacheGetAttr(TYPEOID,
-                                                                        typeTuple,
-                                                                        Anum_pg_type_typdefault,
-                                                                        &isNull);
+       datum = SysCacheGetAttr(TYPEOID,
+                                                       typeTuple,
+                                                       Anum_pg_type_typdefaultbin,
+                                                       &isNull);
 
+       ReleaseSysCache(typeTuple);
        if (isNull)
-       {
-               ReleaseSysCache(typeTuple);
-               *defaultValue = (Datum) 0;
-               return false;
-       }
+               return (Node *) NULL;
 
-       /* Convert text datum to C string */
-       strDefaultVal = DatumGetCString(DirectFunctionCall1(textout,
-                                                                                                               textDefaultVal));
+       /* Convert Datum to a Node */
+       expr = stringToNode(DatumGetCString(
+                                               DirectFunctionCall1(textout, datum)));
 
-       /* Convert C string to a value of the given type */
-       *defaultValue = OidFunctionCall3(typinput,
-                                                                        CStringGetDatum(strDefaultVal),
-                                                                        ObjectIdGetDatum(typelem),
-                                                                        Int32GetDatum(-1));
 
-       pfree(strDefaultVal);
-       ReleaseSysCache(typeTuple);
+       /*
+        * Ensure we goto the basetype before the domain type.
+        *
+        * Prevents scenarios like the below from failing:
+        * CREATE DOMAIN dom text DEFAULT random();
+        *
+        */
+       if (typbasetype != InvalidOid) {
+               expr = coerce_type(NULL, expr, typid,
+                                                 typbasetype, atttypmod);
+       }
 
-       return true;
+
+       return expr;
 }
 
 /*
index 233689c22d72788ac5d5e51acce7bb1f43bad2a2..9997b25db1208cb7c32351f2812b499cae1c394b 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.154 2002/03/06 06:10:21 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.155 2002/03/06 20:34:54 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -512,8 +512,12 @@ RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
                           (char *) attp,
                           ATTRIBUTE_TUPLE_SIZE);
 
-               /* Update constraint/default info */
-               if (attp->attnotnull)
+
+
+               /*
+                * Update constraint/default info
+                */
+       if (attp->attnotnull)
                        constr->has_not_null = true;
 
                if (attp->atthasdef)
index c68a5d4b50a9d00b8f1c8edcc4f00aa61c1f1aab..79c9e0b23a78f45b98f761693e57d44d4741a98b 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.41 2001/11/05 17:46:31 momjian Exp $
+ * $Id: heap.h,v 1.42 2002/03/06 20:34:55 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -15,6 +15,8 @@
 #define HEAP_H
 
 #include "catalog/pg_attribute.h"
+#include "nodes/parsenodes.h"
+#include "parser/parse_node.h"
 #include "utils/rel.h"
 
 typedef struct RawColumnDefault
@@ -45,6 +47,12 @@ extern void AddRelationRawConstraints(Relation rel,
                                                  List *rawColDefaults,
                                                  List *rawConstraints);
 
+extern Node *cookDefault(ParseState *pstate
+                                               , Node *raw_default
+                                               , Oid atttypid
+                                               , int32 atttypmod
+                                               , char *attname);
+
 extern int     RemoveCheckConstraint(Relation rel, const char *constrName, bool inh);
 
 extern Form_pg_attribute SystemAttributeDefinition(AttrNumber attno,
index 43f806188e68593b77ff52d0b2481c170b49c2b3..e8d59f3ed2463a68faccc0083e4e074d2b75c3bb 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.81 2002/03/01 22:45:16 petere Exp $
+ * $Id: pg_attribute.h,v 1.82 2002/03/06 20:34:56 momjian Exp $
  *
  * NOTES
  *       the genbki.sh script reads this file and generates .bki
@@ -240,7 +240,13 @@ typedef FormData_pg_attribute *Form_pg_attribute;
 { 1247, {"typsend"},      24, 0,       4, 14, 0, -1, -1, true, 'p', false, 'i', false, false }, \
 { 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, {"typdefault"},    25, 0,  -1, 17, 0, -1, -1, false , 'x', false, 'i', 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, {"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 }
+
 
 DATA(insert ( 1247 typname                     19 DEFAULT_ATTSTATTARGET NAMEDATALEN   1 0 -1 -1 f p f i f f));
 DATA(insert ( 1247 typowner                    23 0  4   2 0 -1 -1 t p f i f f));
@@ -258,7 +264,12 @@ DATA(insert ( 1247 typreceive              24 0  4  13 0 -1 -1 t p f i f f));
 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 typdefault          25 0 -1  17 0 -1 -1 f x f i 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 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));
 DATA(insert ( 1247 ctid                                27 0  6  -1 0 -1 -1 f p f i f f));
 DATA(insert ( 1247 oid                         26 0  4  -2 0 -1 -1 t p f i f f));
 DATA(insert ( 1247 xmin                                28 0  4  -3 0 -1 -1 t p f i f f));
index 2a4bc84a363834e7bb7dc63011f7e9b0281335ca..ffe7285c3cd37be558cecd0e2e0a89b601b44124 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_class.h,v 1.59 2002/03/01 22:45:17 petere Exp $
+ * $Id: pg_class.h,v 1.60 2002/03/06 20:34:56 momjian Exp $
  *
  * NOTES
  *       the genbki.sh script reads this file and generates .bki
@@ -132,7 +132,7 @@ typedef FormData_pg_class *Form_pg_class;
  * ----------------
  */
 
-DATA(insert OID = 1247 (  pg_type              71      PGUID 0 1247 0 0 0 0 f f r 17 0 0 0 0 0 t f f f _null_ ));
+DATA(insert OID = 1247 (  pg_type              71      PGUID 0 1247 0 0 0 0 f f r 22 0 0 0 0 0 t f f f _null_ ));
 DESCR("");
 DATA(insert OID = 1249 (  pg_attribute 75      PGUID 0 1249 0 0 0 0 f f r 15 0 0 0 0 0 f f f f _null_ ));
 DESCR("");
index 83b7d1bcc46cd953b12bf8427f6017cf28b1c15d..2fa15e3c38fc5922408d70be9a31c80094af3ce4 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.114 2001/11/05 17:46:33 momjian Exp $
+ * $Id: pg_type.h,v 1.115 2002/03/06 20:34:57 momjian Exp $
  *
  * NOTES
  *       the genbki.sh script reads this file and generates .bki
@@ -140,13 +140,50 @@ CATALOG(pg_type) BOOTSTRAP
         */
        char            typstorage;
 
+       /*
+        * This flag represents a "NOT NULL" constraint against this datatype.
+        *
+        * If true, the attnotnull column for a corresponding table column using
+        * this datatype will always enforce the NOT NULL constraint.
+        *
+        * Used primarily for domain types.
+        */
+       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.
+        */
+       int4            typmod;
+
+       /*
+        * 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.
+        */
+       Oid                     typbasetype;
+
+       /*
+        * typndims is the declared number of dimensions, if an array typbasetype,
+        * otherwise zero.
+        */
+       int4            typndims;
+
+       /*
+        * typdefaultbin is the binary representation of typdefault
+        */
+       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 --- this default is used whenever no
-        * per-column default is specified for a column of the datatype.
+        * type's default value
         */
        text            typdefault;             /* VARIABLE LENGTH FIELD */
+
 } FormData_pg_type;
 
 /* ----------------
@@ -160,7 +197,7 @@ typedef FormData_pg_type *Form_pg_type;
  *             compiler constants for pg_type
  * ----------------
  */
-#define Natts_pg_type                                  17
+#define Natts_pg_type                                  22
 #define Anum_pg_type_typname                   1
 #define Anum_pg_type_typowner                  2
 #define Anum_pg_type_typlen                            3
@@ -177,7 +214,13 @@ typedef FormData_pg_type *Form_pg_type;
 #define Anum_pg_type_typsend                   14
 #define Anum_pg_type_typalign                  15
 #define Anum_pg_type_typstorage                        16
-#define Anum_pg_type_typdefault                        17
+#define Anum_pg_type_typnotnull                        17
+#define Anum_pg_type_typmod                            18
+#define Anum_pg_type_typbasetype               19
+#define Anum_pg_type_typndims                  20
+#define Anum_pg_type_typdefaultbin             21
+#define Anum_pg_type_typdefault                        22
+
 
 /* ----------------
  *             initial contents of pg_type
@@ -192,82 +235,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 _null_ ));
+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_ ));
 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 _null_ ));
+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_ ));
 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 _null_ ));
+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_ ));
 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 _null_ ));
+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_ ));
 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 _null_ ));
+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_ ));
 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 _null_ ));
+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_ ));
 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 _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 -1 0 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 _null_ ));
+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_ ));
 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 _null_ ));
+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_ ));
 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 _null_ ));
+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_ ));
 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 _null_ ));
+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_ ));
 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 _null_ ));
+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_ ));
 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 _null_ ));
+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_ ));
 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 _null_ ));
+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_ ));
 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 _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 -1 0 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 _null_ ));
+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_ ));
 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 _null_));
-DATA(insert OID = 75 ( pg_attribute PGUID 4 4 t c t \054 1249 0 int4in int4out int4in int4out i p _null_));
-DATA(insert OID = 81 ( pg_proc          PGUID 4 4 t c t \054 1255 0 int4in int4out int4in int4out i p _null_));
-DATA(insert OID = 83 ( pg_class         PGUID 4 4 t c t \054 1259 0 int4in int4out int4in int4out i p _null_));
-DATA(insert OID = 86 ( pg_shadow        PGUID 4 4 t c t \054 1260 0 int4in int4out int4in int4out i p _null_));
-DATA(insert OID = 87 ( pg_group         PGUID 4 4 t c t \054 1261 0 int4in int4out int4in int4out i p _null_));
-DATA(insert OID = 88 ( pg_database  PGUID 4 4 t c t \054 1262 0 int4in int4out int4in int4out i p _null_));
+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_ ));
 
 /* 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 _null_ ));
+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_ ));
 DESCR("storage manager");
 
 /* OIDS 300 - 399 */
@@ -277,167 +320,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 _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 -1 0 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 _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 -1 0 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 _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 -1 0 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 _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 -1 0 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 _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 -1 0 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 _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 -1 0 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 _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 -1 0 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 _null_ ));
+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_ ));
 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 _null_ ));
+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_ ));
 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 _null_ ));
+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_ ));
 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 _null_ ));
+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_ ));
 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 _null_ ));
+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_ ));
 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 _null_ ));
+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_ ));
 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 _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 -1 0 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 _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 _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 -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_ ));
 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 _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 -1 0 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 _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 -1 0 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 _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 -1 0 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 _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 -1 0 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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 -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_ ));
 /*
  *     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 _null_ ));
+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_ ));
 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 _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 _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 _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 _null_ ));
-DATA(insert OID = 1042 ( bpchar                 PGUID -1  -1 f b t \054 0      0 bpcharin bpcharout bpcharin bpcharout i x _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 -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_ ));
 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 _null_ ));
+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_ ));
 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 _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 -1 0 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 _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 -1 0 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 _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 -1 0 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 _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 _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 _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 _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 -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_ ));
 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 _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 _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 -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_ ));
 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 _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 -1 0 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 _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 _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 -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_ ));
 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 _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 -1 0 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 _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 -1 0 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 _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 _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 -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_ ));
 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 _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 -1 0 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 _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 -1 0 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 _null_ ));
+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_ ));
 DESCR("reference cursor (portal name)");
 #define REFCURSOROID   1790
 
@@ -447,6 +490,7 @@ DESCR("reference cursor (portal name)");
  */
 extern Oid     TypeGet(char *typeName, bool *defined);
 extern Oid     TypeShellMake(char *typeName);
+
 extern Oid TypeCreate(char *typeName,
                   Oid assignedTypeOid,
                   Oid relationOid,
@@ -459,10 +503,17 @@ extern Oid TypeCreate(char *typeName,
                   char *receiveProcedure,
                   char *sendProcedure,
                   char *elementTypeName,
+                  char *baseTypeName,
                   char *defaultTypeValue,
+                  char *defaultTypeBin,
                   bool passedByValue,
                   char alignment,
-                  char storage);
+                  char storage,
+                  int32 typeMod,
+                  int32 typNDims,
+                  bool typeNotNull);
+
+
 extern void TypeRename(const char *oldTypeName, const char *newTypeName);
 extern char *makeArrayTypeName(char *typeName);
 
index a69da106b4278e4cab210cd287888843769332cd..00ea79a03b81dfae8bcaf56d7ce450cdcc349c13 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: defrem.h,v 1.28 2001/11/05 17:46:33 momjian Exp $
+ * $Id: defrem.h,v 1.29 2002/03/06 20:34:59 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -39,10 +39,12 @@ extern void CreateFunction(ProcedureStmt *stmt);
 extern void DefineOperator(char *name, List *parameters);
 extern void DefineAggregate(char *name, List *parameters);
 extern void DefineType(char *name, List *parameters);
+extern void DefineDomain(CreateDomainStmt *stmt);
 
 /*
  * prototypes in remove.c
  */
+extern void RemoveDomain(char *domainName, int behavior);
 extern void RemoveFunction(char *functionName, List *argTypes);
 extern void RemoveOperator(char *operatorName,
                           char *typeName1, char *typeName2);
index 96a89d9df56662f8999654ef6582154b72bad4b4..7c455a4c65c847b3c36d84ffa38a5ec1a60a64b9 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: nodes.h,v 1.98 2002/03/01 22:45:17 petere Exp $
+ * $Id: nodes.h,v 1.99 2002/03/06 20:35:00 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -172,6 +172,7 @@ typedef enum NodeTag
        T_TransactionStmt,
        T_ViewStmt,
        T_LoadStmt,
+       T_CreateDomainStmt,
        T_CreatedbStmt,
        T_DropdbStmt,
        T_VacuumStmt,
index c6b1feb79b95790c1748f2aaaacdca021211c77a..330a3bd35986bd416e3a05b688f334c6dee6f7ba 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.156 2002/03/05 05:33:31 momjian Exp $
+ * $Id: parsenodes.h,v 1.157 2002/03/06 20:35:00 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -468,12 +468,14 @@ typedef struct DefineStmt
 #define DROP_INDEX       4
 #define DROP_RULE        5
 #define DROP_TYPE_P   6
+#define DROP_DOMAIN_P 7
 
 typedef struct DropStmt
 {
        NodeTag         type;
        List       *names;
        int                     removeType;
+       int                     behavior;               /* CASCADE or RESTRICT drop behavior */
 } DropStmt;
 
 /* ----------------------
@@ -682,6 +684,7 @@ typedef struct LoadStmt
        char       *filename;           /* file to load */
 } LoadStmt;
 
+
 /* ----------------------
  *             Createdb Statement
  * ----------------------
@@ -1280,6 +1283,22 @@ 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
  ****************************************************************************/
index ce9fb7b558a3e960424dfa151bcdffd7f3f62f5f..c8f1891415b8e56cdd3d78aba847f9518c5fe907 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.37 2001/11/05 17:46:34 momjian Exp $
+ * $Id: parse_coerce.h,v 1.38 2002/03/06 20:35:01 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -81,5 +81,6 @@ 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 c76c8d53d88030dcd2216c73213bb01c3e932a1b..6454a56a9441d307af5b2356687e7b0bf77f9839 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.40 2002/03/01 04:09:28 tgl Exp $
+ * $Id: lsyscache.h,v 1.41 2002/03/06 20:35:02 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -44,7 +44,7 @@ extern int16 get_typlen(Oid typid);
 extern bool get_typbyval(Oid typid);
 extern void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval);
 extern char get_typstorage(Oid typid);
-extern bool get_typdefault(Oid typid, Datum *defaultValue);
+extern Node *get_typdefault(Oid typid, int32 atttypmod);
 extern int32 get_typavgwidth(Oid typid, int32 typmod);
 extern int32 get_attavgwidth(Oid relid, AttrNumber attnum);
 extern bool get_attstatsslot(HeapTuple statstuple,