Commit 01c76f74 authored by Bruce Momjian's avatar Bruce Momjian

Ok. Updated patch attached.

- 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
parent 3d9f865e
-- 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;
<!-- <!--
Documentation of the system catalogs, directed toward PostgreSQL developers 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"> <chapter id="catalogs">
...@@ -2510,6 +2510,53 @@ ...@@ -2510,6 +2510,53 @@
</para></entry> </para></entry>
</row> </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> <row>
<entry>typdefault</entry> <entry>typdefault</entry>
<entry><type>text</type></entry> <entry><type>text</type></entry>
......
<!-- <!--
$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 PostgreSQL documentation
Complete list of usable sgml source files in this directory. Complete list of usable sgml source files in this directory.
--> -->
...@@ -52,6 +52,7 @@ 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 createAggregate system "create_aggregate.sgml">
<!entity createConstraint system "create_constraint.sgml"> <!entity createConstraint system "create_constraint.sgml">
<!entity createDatabase system "create_database.sgml"> <!entity createDatabase system "create_database.sgml">
<!entity createDomain system "create_domain.sgml">
<!entity createFunction system "create_function.sgml"> <!entity createFunction system "create_function.sgml">
<!entity createGroup system "create_group.sgml"> <!entity createGroup system "create_group.sgml">
<!entity createIndex system "create_index.sgml"> <!entity createIndex system "create_index.sgml">
...@@ -69,6 +70,7 @@ Complete list of usable sgml source files in this directory. ...@@ -69,6 +70,7 @@ Complete list of usable sgml source files in this directory.
<!entity delete system "delete.sgml"> <!entity delete system "delete.sgml">
<!entity dropAggregate system "drop_aggregate.sgml"> <!entity dropAggregate system "drop_aggregate.sgml">
<!entity dropDatabase system "drop_database.sgml"> <!entity dropDatabase system "drop_database.sgml">
<!entity dropDomain system "drop_domain.sgml">
<!entity dropFunction system "drop_function.sgml"> <!entity dropFunction system "drop_function.sgml">
<!entity dropGroup system "drop_group.sgml"> <!entity dropGroup system "drop_group.sgml">
<!entity dropIndex system "drop_index.sgml"> <!entity dropIndex system "drop_index.sgml">
......
<!-- <!--
$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 PostgreSQL documentation
--> -->
...@@ -25,7 +25,7 @@ PostgreSQL documentation ...@@ -25,7 +25,7 @@ PostgreSQL documentation
<synopsis> <synopsis>
COMMENT ON 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> | 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>) | 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>, ...) | FUNCTION <replaceable class="PARAMETER">func_name</replaceable> (<replaceable class="PARAMETER">arg1</replaceable>, <replaceable class="PARAMETER">arg2</replaceable>, ...) |
...@@ -141,6 +141,7 @@ COMMENT ON mytable IS 'This is my table.'; ...@@ -141,6 +141,7 @@ COMMENT ON mytable IS 'This is my table.';
<programlisting> <programlisting>
COMMENT ON DATABASE my_database IS 'Development Database'; 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 INDEX my_index IS 'Enforces uniqueness on employee id';
COMMENT ON RULE my_rule IS 'Logs UPDATES of employee records'; COMMENT ON RULE my_rule IS 'Logs UPDATES of employee records';
COMMENT ON SEQUENCE my_sequence IS 'Used to generate primary keys'; COMMENT ON SEQUENCE my_sequence IS 'Used to generate primary keys';
......
<!--
$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:
-->
<!--
$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:
-->
<!-- reference.sgml <!-- 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 PostgreSQL Reference Manual
--> -->
...@@ -61,6 +61,7 @@ PostgreSQL Reference Manual ...@@ -61,6 +61,7 @@ PostgreSQL Reference Manual
&createAggregate; &createAggregate;
&createConstraint; &createConstraint;
&createDatabase; &createDatabase;
&createDomain;
&createFunction; &createFunction;
&createGroup; &createGroup;
&createIndex; &createIndex;
...@@ -78,6 +79,7 @@ PostgreSQL Reference Manual ...@@ -78,6 +79,7 @@ PostgreSQL Reference Manual
&delete; &delete;
&dropAggregate; &dropAggregate;
&dropDatabase; &dropDatabase;
&dropDomain;
&dropFunction; &dropFunction;
&dropGroup; &dropGroup;
&dropIndex; &dropIndex;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * INTERFACE ROUTINES
...@@ -698,10 +698,15 @@ AddNewRelationType(char *typeName, Oid new_rel_oid, Oid new_type_oid) ...@@ -698,10 +698,15 @@ AddNewRelationType(char *typeName, Oid new_rel_oid, Oid new_type_oid)
"oidin", /* receive procedure */ "oidin", /* receive procedure */
"oidout", /* send procedure */ "oidout", /* send procedure */
NULL, /* array element type - irrelevant */ NULL, /* array element type - irrelevant */
NULL, /* baseType Name -- typically for domiains */
NULL, /* default type value - none */ NULL, /* default type value - none */
NULL, /* default type binary representation */
true, /* passed by value */ true, /* passed by value */
'i', /* default alignment - same as for OID */ '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, ...@@ -1584,6 +1589,10 @@ AddRelationRawConstraints(Relation rel,
int numchecks; int numchecks;
List *listptr; List *listptr;
/* Probably shouldn't be null by default */
Node *expr = NULL;
/* /*
* Get info about existing constraints. * Get info about existing constraints.
*/ */
...@@ -1614,68 +1623,13 @@ AddRelationRawConstraints(Relation rel, ...@@ -1614,68 +1623,13 @@ AddRelationRawConstraints(Relation rel,
foreach(listptr, rawColDefaults) foreach(listptr, rawColDefaults)
{ {
RawColumnDefault *colDef = (RawColumnDefault *) lfirst(listptr); 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]; Form_pg_attribute atp = rel->rd_att->attrs[colDef->attnum - 1];
if (type_id != atp->atttypid) expr = cookDefault(pstate, colDef->raw_default
{ , atp->atttypid, atp->atttypmod
if (CoerceTargetExpr(NULL, expr, type_id, , NameStr(atp->attname));
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));
}
}
/*
* 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);
/* /*
* OK, store it. * OK, store it.
...@@ -1892,6 +1846,88 @@ SetRelationNumChecks(Relation rel, int numchecks) ...@@ -1892,6 +1846,88 @@ SetRelationNumChecks(Relation rel, int numchecks)
heap_close(relrel, RowExclusiveLock); 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 static void
RemoveAttrDefaults(Relation rel) RemoveAttrDefaults(Relation rel)
{ {
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -178,8 +178,13 @@ TypeShellMakeWithOpenRelation(Relation pg_type_desc, char *typeName)
values[i++] = ObjectIdGetDatum(InvalidOid); /* 14 */ values[i++] = ObjectIdGetDatum(InvalidOid); /* 14 */
values[i++] = CharGetDatum('i'); /* 15 */ values[i++] = CharGetDatum('i'); /* 15 */
values[i++] = CharGetDatum('p'); /* 16 */ values[i++] = CharGetDatum('p'); /* 16 */
values[i++] = BoolGetDatum(false); /* 17 */
values[i++] = Int32GetDatum(-1); /* 18 */
values[i++] = DirectFunctionCall1(textin, values[i++] = DirectFunctionCall1(textin,
CStringGetDatum(typeName)); /* 17 */ CStringGetDatum(typeName)); /* 19 */
values[i++] = DirectFunctionCall1(textin,
CStringGetDatum(typeName)); /* 20 */
/* /*
* create a new type tuple with FormHeapTuple * create a new type tuple with FormHeapTuple
...@@ -274,10 +279,15 @@ TypeCreate(char *typeName, ...@@ -274,10 +279,15 @@ TypeCreate(char *typeName,
char *receiveProcedure, char *receiveProcedure,
char *sendProcedure, char *sendProcedure,
char *elementTypeName, char *elementTypeName,
char *defaultTypeValue, /* internal rep */ char *baseTypeName,
char *defaultTypeValue, /* human readable rep */
char *defaultTypeBin, /* cooked rep */
bool passedByValue, bool passedByValue,
char alignment, char alignment,
char storage) char storage,
int32 typeMod,
int32 typNDims, /* Array dimensions for baseTypeName */
bool typeNotNull) /* binary default representation (cooked) */
{ {
int i, int i,
j; j;
...@@ -285,6 +295,7 @@ TypeCreate(char *typeName, ...@@ -285,6 +295,7 @@ TypeCreate(char *typeName,
HeapScanDesc pg_type_scan; HeapScanDesc pg_type_scan;
Oid typeObjectId; Oid typeObjectId;
Oid elementObjectId = InvalidOid; Oid elementObjectId = InvalidOid;
Oid baseObjectId = InvalidOid;
HeapTuple tup; HeapTuple tup;
char nulls[Natts_pg_type]; char nulls[Natts_pg_type];
char replaces[Natts_pg_type]; char replaces[Natts_pg_type];
...@@ -317,6 +328,17 @@ TypeCreate(char *typeName, ...@@ -317,6 +328,17 @@ TypeCreate(char *typeName,
elog(ERROR, "type %s does not exist", elementTypeName); 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 * validate size specifications: either positive (fixed-length) or -1
* (variable-length). * (variable-length).
...@@ -388,7 +410,7 @@ TypeCreate(char *typeName, ...@@ -388,7 +410,7 @@ TypeCreate(char *typeName,
* signature is 0,OIDOID,INT4OID. The output procedures may * signature is 0,OIDOID,INT4OID. The output procedures may
* take 2 args (data value, element OID). * take 2 args (data value, element OID).
*/ */
if (OidIsValid(elementObjectId)) if (OidIsValid(elementObjectId) || OidIsValid(baseObjectId))
{ {
int nargs; int nargs;
...@@ -411,6 +433,7 @@ TypeCreate(char *typeName, ...@@ -411,6 +433,7 @@ TypeCreate(char *typeName,
PointerGetDatum(argList), PointerGetDatum(argList),
0); 0);
} }
if (!OidIsValid(procOid)) if (!OidIsValid(procOid))
func_error("TypeCreate", procname, 1, argList, NULL); func_error("TypeCreate", procname, 1, argList, NULL);
} }
...@@ -428,6 +451,34 @@ TypeCreate(char *typeName, ...@@ -428,6 +451,34 @@ TypeCreate(char *typeName,
*/ */
values[i++] = CharGetDatum(storage); /* 16 */ 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. * initialize the default value for this type.
*/ */
...@@ -436,7 +487,7 @@ TypeCreate(char *typeName, ...@@ -436,7 +487,7 @@ TypeCreate(char *typeName,
CStringGetDatum(defaultTypeValue)); CStringGetDatum(defaultTypeValue));
else else
nulls[i] = 'n'; nulls[i] = 'n';
i++; /* 17 */ i++; /* 22 */
/* /*
* open pg_type and begin a scan for the type name. * open pg_type and begin a scan for the type name.
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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); ...@@ -39,7 +39,7 @@ static bool change_varattnos_of_a_node(Node *node, const AttrNumber *newattno);
static void StoreCatalogInheritance(Oid relationId, List *supers); static void StoreCatalogInheritance(Oid relationId, List *supers);
static int findAttrByName(const char *attributeName, List *schema); static int findAttrByName(const char *attributeName, List *schema);
static void setRelhassubclassInRelation(Oid relationId, bool relhassubclass); static void setRelhassubclassInRelation(Oid relationId, bool relhassubclass);
static List *MergeDomainAttributes(List *schema);
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------
* DefineRelation * DefineRelation
...@@ -69,6 +69,13 @@ DefineRelation(CreateStmt *stmt, char relkind) ...@@ -69,6 +69,13 @@ DefineRelation(CreateStmt *stmt, char relkind)
*/ */
StrNCpy(relname, stmt->relname, NAMEDATALEN); 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, * Look up inheritance ancestors and generate relation schema,
* including inherited attributes. * including inherited attributes.
...@@ -237,6 +244,88 @@ TruncateRelation(char *name) ...@@ -237,6 +244,88 @@ TruncateRelation(char *name)
heap_truncate(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 * MergeAttributes
* Returns new schema given initial schema and superclasses. * Returns new schema given initial schema and superclasses.
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * 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 * DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the * The "DefineFoo" routines take the parse tree and pick out the
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include "access/heapam.h" #include "access/heapam.h"
#include "catalog/catname.h" #include "catalog/catname.h"
#include "catalog/heap.h"
#include "catalog/pg_aggregate.h" #include "catalog/pg_aggregate.h"
#include "catalog/pg_language.h" #include "catalog/pg_language.h"
#include "catalog/pg_operator.h" #include "catalog/pg_operator.h"
...@@ -475,6 +476,322 @@ DefineAggregate(char *aggName, List *parameters) ...@@ -475,6 +476,322 @@ DefineAggregate(char *aggName, List *parameters)
initval); /* initial condition */ 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 * DefineType
* Registers a new type. * Registers a new type.
...@@ -490,6 +807,8 @@ DefineType(char *typeName, List *parameters) ...@@ -490,6 +807,8 @@ DefineType(char *typeName, List *parameters)
char *sendName = NULL; char *sendName = NULL;
char *receiveName = NULL; char *receiveName = NULL;
char *defaultValue = NULL; char *defaultValue = NULL;
char *defaultValueBin = NULL;
Node *defaultRaw = (Node *) NULL;
bool byValue = false; bool byValue = false;
char delimiter = DEFAULT_TYPDELIM; char delimiter = DEFAULT_TYPDELIM;
char *shadow_type; char *shadow_type;
...@@ -531,7 +850,7 @@ DefineType(char *typeName, List *parameters) ...@@ -531,7 +850,7 @@ DefineType(char *typeName, List *parameters)
else if (strcasecmp(defel->defname, "element") == 0) else if (strcasecmp(defel->defname, "element") == 0)
elemName = defGetString(defel); elemName = defGetString(defel);
else if (strcasecmp(defel->defname, "default") == 0) else if (strcasecmp(defel->defname, "default") == 0)
defaultValue = defGetString(defel); defaultRaw = defel->arg;
else if (strcasecmp(defel->defname, "passedbyvalue") == 0) else if (strcasecmp(defel->defname, "passedbyvalue") == 0)
byValue = true; byValue = true;
else if (strcasecmp(defel->defname, "alignment") == 0) else if (strcasecmp(defel->defname, "alignment") == 0)
...@@ -591,6 +910,32 @@ DefineType(char *typeName, List *parameters) ...@@ -591,6 +910,32 @@ DefineType(char *typeName, List *parameters)
if (outputName == NULL) if (outputName == NULL)
elog(ERROR, "Define: \"output\" unspecified"); 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. * now have TypeCreate do all the real work.
*/ */
...@@ -606,10 +951,15 @@ DefineType(char *typeName, List *parameters) ...@@ -606,10 +951,15 @@ DefineType(char *typeName, List *parameters)
receiveName, /* receive procedure */ receiveName, /* receive procedure */
sendName, /* send procedure */ sendName, /* send procedure */
elemName, /* element type name */ elemName, /* element type name */
NULL, /* base type name (Non-zero for domains) */
defaultValue, /* default type value */ defaultValue, /* default type value */
defaultValueBin, /* default type value (Binary form) */
byValue, /* passed by value */ byValue, /* passed by value */
alignment, /* required alignment */ 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 * When we create a base type (as opposed to a complex type) we need
...@@ -632,10 +982,15 @@ DefineType(char *typeName, List *parameters) ...@@ -632,10 +982,15 @@ DefineType(char *typeName, List *parameters)
"array_in", /* receive procedure */ "array_in", /* receive procedure */
"array_out", /* send procedure */ "array_out", /* send procedure */
typeName, /* element type name */ typeName, /* element type name */
NULL, /* base type name */
NULL, /* never a default type value */ NULL, /* never a default type value */
NULL, /* binary default isn't sent either */
false, /* never passed by value */ false, /* never passed by value */
alignment, /* see above */ 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); pfree(shadow_type);
} }
......
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
* *
* remove.c * 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) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* *
* IDENTIFICATION * 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 @@ ...@@ -22,6 +22,7 @@
#include "commands/comment.h" #include "commands/comment.h"
#include "commands/defrem.h" #include "commands/defrem.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "parser/parse.h"
#include "parser/parse_agg.h" #include "parser/parse_agg.h"
#include "parser/parse_expr.h" #include "parser/parse_expr.h"
#include "parser/parse_func.h" #include "parser/parse_func.h"
...@@ -275,6 +276,60 @@ RemoveType(char *typeName) /* type name to be removed */ ...@@ -275,6 +276,60 @@ RemoveType(char *typeName) /* type name to be removed */
heap_close(relation, RowExclusiveLock); 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 * RemoveFunction
* Deletes a function. * Deletes a function.
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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) ...@@ -2227,6 +2227,19 @@ _copyLoadStmt(LoadStmt *from)
return newnode; 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 * static CreatedbStmt *
_copyCreatedbStmt(CreatedbStmt *from) _copyCreatedbStmt(CreatedbStmt *from)
{ {
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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) ...@@ -1095,6 +1095,17 @@ _equalLoadStmt(LoadStmt *a, LoadStmt *b)
return true; 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 static bool
_equalCreatedbStmt(CreatedbStmt *a, CreatedbStmt *b) _equalCreatedbStmt(CreatedbStmt *a, CreatedbStmt *b)
{ {
...@@ -2011,6 +2022,9 @@ equal(void *a, void *b) ...@@ -2011,6 +2022,9 @@ equal(void *a, void *b)
case T_LoadStmt: case T_LoadStmt:
retval = _equalLoadStmt(a, b); retval = _equalLoadStmt(a, b);
break; break;
case T_CreateDomainStmt:
retval = _equalCreateDomainStmt(a, b);
break;
case T_CreatedbStmt: case T_CreatedbStmt:
retval = _equalCreatedbStmt(a, b); retval = _equalCreatedbStmt(a, b);
break; break;
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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) ...@@ -355,7 +355,6 @@ build_column_default(Relation rel, int attrno)
Form_pg_attribute att_tup = rd_att->attrs[attrno - 1]; Form_pg_attribute att_tup = rd_att->attrs[attrno - 1];
Oid atttype = att_tup->atttypid; Oid atttype = att_tup->atttypid;
int32 atttypmod = att_tup->atttypmod; int32 atttypmod = att_tup->atttypmod;
bool hasdefault;
Datum typedefault; Datum typedefault;
int16 typlen; int16 typlen;
bool typbyval; bool typbyval;
...@@ -392,7 +391,7 @@ build_column_default(Relation rel, int attrno) ...@@ -392,7 +391,7 @@ build_column_default(Relation rel, int attrno)
if (type_id != atttype) if (type_id != atttype)
{ {
expr = CoerceTargetExpr(NULL, expr, type_id, expr = CoerceTargetExpr(NULL, expr, type_id,
atttype, atttypmod); getBaseType(atttype), atttypmod);
/* /*
* This really shouldn't fail; should have checked the * This really shouldn't fail; should have checked the
...@@ -430,39 +429,51 @@ build_column_default(Relation rel, int attrno) ...@@ -430,39 +429,51 @@ build_column_default(Relation rel, int attrno)
* element type is, and the element type's default is irrelevant * element type is, and the element type's default is irrelevant
* too. * too.
*/ */
hasdefault = false;
typedefault = (Datum) 0;
typlen = sizeof(Oid); typlen = sizeof(Oid);
typbyval = true; typbyval = true;
expr = (Node *) makeConst(atttype,
typlen,
(Datum) 0,
true,
typbyval,
false, /* not a set */
false);
} }
else else
{ {
#ifdef _DROP_COLUMN_HACK__ #ifdef _DROP_COLUMN_HACK__
if (COLUMN_IS_DROPPED(att_tup)) 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 else
#endif /* _DROP_COLUMN_HACK__ */ #endif /* _DROP_COLUMN_HACK__ */
hasdefault = get_typdefault(atttype, &typedefault); expr = get_typdefault(atttype, atttypmod);
get_typlenbyval(atttype, &typlen, &typbyval);
}
if (expr == NULL) {
expr = (Node *) makeConst(atttype, expr = (Node *) makeConst(atttype,
typlen, typlen,
typedefault, (Datum) 0,
!hasdefault, true,
typbyval, typbyval,
false, /* not a set */ false, /* not a set */
false); false);
}
get_typlenbyval(atttype, &typlen, &typbyval);
}
/* /*
* If the column is a fixed-length type, it may need a length coercion * 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, expr = coerce_type_typmod(NULL, expr,
atttype, atttypmod); atttype, atttypmod);
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * 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 * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -135,7 +135,8 @@ static void doNegateFloat(Value *v); ...@@ -135,7 +135,8 @@ static void doNegateFloat(Value *v);
ClosePortalStmt, ClusterStmt, CommentStmt, ConstraintsSetStmt, ClosePortalStmt, ClusterStmt, CommentStmt, ConstraintsSetStmt,
CopyStmt, CreateAsStmt, CreateGroupStmt, CreatePLangStmt, CopyStmt, CreateAsStmt, CreateGroupStmt, CreatePLangStmt,
CreateSchemaStmt, CreateSeqStmt, CreateStmt, CreateTrigStmt, CreateSchemaStmt, CreateSeqStmt, CreateStmt, CreateTrigStmt,
CreateUserStmt, CreatedbStmt, CursorStmt, DefineStmt, DeleteStmt, CreateUserStmt, CreateDomainStmt, CreatedbStmt, CursorStmt,
DefineStmt, DeleteStmt,
DropGroupStmt, DropPLangStmt, DropSchemaStmt, DropStmt, DropTrigStmt, DropGroupStmt, DropPLangStmt, DropSchemaStmt, DropStmt, DropTrigStmt,
DropUserStmt, DropdbStmt, ExplainStmt, FetchStmt, DropUserStmt, DropdbStmt, ExplainStmt, FetchStmt,
GrantStmt, IndexStmt, InsertStmt, ListenStmt, LoadStmt, LockStmt, GrantStmt, IndexStmt, InsertStmt, ListenStmt, LoadStmt, LockStmt,
...@@ -289,6 +290,8 @@ static void doNegateFloat(Value *v); ...@@ -289,6 +290,8 @@ static void doNegateFloat(Value *v);
%type <list> constraints_set_namelist %type <list> constraints_set_namelist
%type <boolean> constraints_set_mode %type <boolean> constraints_set_mode
%type <boolean> opt_as
/* /*
* If you make any token changes, remember to: * If you make any token changes, remember to:
* - use "yacc -d" and update parse.h * - use "yacc -d" and update parse.h
...@@ -343,7 +346,7 @@ static void doNegateFloat(Value *v); ...@@ -343,7 +346,7 @@ static void doNegateFloat(Value *v);
WITHOUT WITHOUT
/* Keywords (in SQL92 non-reserved words) */ /* 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) /* Keywords for Postgres support (not in SQL92 reserved words)
* *
...@@ -446,6 +449,7 @@ stmt : AlterDatabaseSetStmt ...@@ -446,6 +449,7 @@ stmt : AlterDatabaseSetStmt
| CopyStmt | CopyStmt
| CreateStmt | CreateStmt
| CreateAsStmt | CreateAsStmt
| CreateDomainStmt
| CreateSchemaStmt | CreateSchemaStmt
| CreateGroupStmt | CreateGroupStmt
| CreateSeqStmt | CreateSeqStmt
...@@ -776,6 +780,9 @@ DropSchemaStmt: DROP SCHEMA UserId ...@@ -776,6 +780,9 @@ DropSchemaStmt: DROP SCHEMA UserId
n->dbname = $3; n->dbname = $3;
$$ = (Node *)n; $$ = (Node *)n;
} }
;
/***************************************************************************** /*****************************************************************************
...@@ -1461,7 +1468,10 @@ ColConstraintElem: ...@@ -1461,7 +1468,10 @@ ColConstraintElem:
n->name = NULL; n->name = NULL;
if (exprIsNullConstant($2)) 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; n->raw_expr = NULL;
} }
else else
...@@ -2043,7 +2053,16 @@ def_list: def_elem { $$ = makeList1($1); } ...@@ -2043,7 +2053,16 @@ def_list: def_elem { $$ = makeList1($1); }
| def_list ',' def_elem { $$ = lappend($1, $3); } | 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); $$ = makeNode(DefElem);
$$->defname = $1; $$->defname = $1;
...@@ -2078,6 +2097,15 @@ DropStmt: DROP drop_type name_list ...@@ -2078,6 +2097,15 @@ DropStmt: DROP drop_type name_list
DropStmt *n = makeNode(DropStmt); DropStmt *n = makeNode(DropStmt);
n->removeType = $2; n->removeType = $2;
n->names = $3; 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; $$ = (Node *)n;
} }
; ;
...@@ -2110,7 +2138,7 @@ TruncateStmt: TRUNCATE opt_table relation_name ...@@ -2110,7 +2138,7 @@ TruncateStmt: TRUNCATE opt_table relation_name
* The COMMENT ON statement can take different forms based upon the type of * 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: * 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 * <objname> | AGGREGATE <aggname> (<aggtype>) | FUNCTION
* <funcname> (arg1, arg2, ...) | OPERATOR <op> * <funcname> (arg1, arg2, ...) | OPERATOR <op>
* (leftoperand_typ rightoperand_typ) | TRIGGER <triggername> ON * (leftoperand_typ rightoperand_typ) | TRIGGER <triggername> ON
...@@ -2196,6 +2224,7 @@ comment_type: DATABASE { $$ = DATABASE; } ...@@ -2196,6 +2224,7 @@ comment_type: DATABASE { $$ = DATABASE; }
| RULE { $$ = RULE; } | RULE { $$ = RULE; }
| SEQUENCE { $$ = SEQUENCE; } | SEQUENCE { $$ = SEQUENCE; }
| TABLE { $$ = TABLE; } | TABLE { $$ = TABLE; }
| DOMAIN_P { $$ = TYPE_P; }
| TYPE_P { $$ = TYPE_P; } | TYPE_P { $$ = TYPE_P; }
| VIEW { $$ = VIEW; } | VIEW { $$ = VIEW; }
; ;
...@@ -3222,6 +3251,30 @@ AlterDatabaseSetStmt: ALTER DATABASE database_name VariableSetStmt ...@@ -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: ...@@ -5879,6 +5932,7 @@ unreserved_keyword:
| DEFERRED { $$ = "deferred"; } | DEFERRED { $$ = "deferred"; }
| DELETE { $$ = "delete"; } | DELETE { $$ = "delete"; }
| DELIMITERS { $$ = "delimiters"; } | DELIMITERS { $$ = "delimiters"; }
| DOMAIN_P { $$ = "domain"; }
| DOUBLE { $$ = "double"; } | DOUBLE { $$ = "double"; }
| DROP { $$ = "drop"; } | DROP { $$ = "drop"; }
| EACH { $$ = "each"; } | EACH { $$ = "each"; }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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[] = { ...@@ -97,6 +97,7 @@ static ScanKeyword ScanKeywords[] = {
{"desc", DESC}, {"desc", DESC},
{"distinct", DISTINCT}, {"distinct", DISTINCT},
{"do", DO}, {"do", DO},
{"domain", DOMAIN_P},
{"double", DOUBLE}, {"double", DOUBLE},
{"drop", DROP}, {"drop", DROP},
{"each", EACH}, {"each", EACH},
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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, ...@@ -38,6 +38,7 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId,
{ {
Node *result; Node *result;
if (targetTypeId == inputTypeId || if (targetTypeId == inputTypeId ||
targetTypeId == InvalidOid || targetTypeId == InvalidOid ||
node == NULL) node == NULL)
...@@ -605,3 +606,32 @@ PreferredType(CATEGORY category, Oid type) ...@@ -605,3 +606,32 @@ PreferredType(CATEGORY category, Oid type)
} }
return result; return result;
} /* PreferredType() */ } /* 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
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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, ...@@ -1027,7 +1027,8 @@ parser_typecast_expression(ParseState *pstate,
if (inputType != targetType) if (inputType != targetType)
{ {
expr = CoerceTargetExpr(pstate, expr, inputType, expr = CoerceTargetExpr(pstate, expr, inputType,
targetType, typename->typmod); getBaseType(targetType),
typename->typmod);
if (expr == NULL) if (expr == NULL)
elog(ERROR, "Cannot cast type '%s' to '%s'", elog(ERROR, "Cannot cast type '%s' to '%s'",
format_type_be(inputType), format_type_be(inputType),
...@@ -1039,7 +1040,7 @@ parser_typecast_expression(ParseState *pstate, ...@@ -1039,7 +1040,7 @@ parser_typecast_expression(ParseState *pstate,
* as well as a type coercion. * as well as a type coercion.
*/ */
expr = coerce_type_typmod(pstate, expr, expr = coerce_type_typmod(pstate, expr,
targetType, typename->typmod); getBaseType(targetType), typename->typmod);
return expr; return expr;
} }
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * 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, ...@@ -282,6 +282,11 @@ ProcessUtility(Node *parsetree,
/* RemoveType does its own permissions checks */ /* RemoveType does its own permissions checks */
RemoveType(relname); RemoveType(relname);
break; break;
case DROP_DOMAIN_P:
/* RemoveDomain does its own permissions checks */
RemoveDomain(relname, stmt->behavior);
break;
} }
/* /*
...@@ -742,6 +747,16 @@ ProcessUtility(Node *parsetree, ...@@ -742,6 +747,16 @@ ProcessUtility(Node *parsetree,
DropProceduralLanguage((DropPLangStmt *) parsetree); DropProceduralLanguage((DropPLangStmt *) parsetree);
break; break;
/*
* ******************************** DOMAIN statements ****
*
*/
case T_CreateDomainStmt:
set_ps_display(commandTag = "CREATE DOMAIN");
DefineDomain((CreateDomainStmt *) parsetree);
break;
/* /*
* ******************************** USER statements **** * ******************************** USER statements ****
* *
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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, ...@@ -126,6 +126,7 @@ format_type_internal(Oid type_oid, int32 typemod,
bool is_array; bool is_array;
char *name; char *name;
char *buf; char *buf;
char typtype;
if (type_oid == InvalidOid && allow_invalid) if (type_oid == InvalidOid && allow_invalid)
return pstrdup("-"); return pstrdup("-");
...@@ -144,6 +145,31 @@ format_type_internal(Oid type_oid, int32 typemod, ...@@ -144,6 +145,31 @@ format_type_internal(Oid type_oid, int32 typemod,
array_base_type = ((Form_pg_type) GETSTRUCT(tuple))->typelem; array_base_type = ((Form_pg_type) GETSTRUCT(tuple))->typelem;
typlen = ((Form_pg_type) GETSTRUCT(tuple))->typlen; typlen = ((Form_pg_type) GETSTRUCT(tuple))->typlen;
typtype = ((Form_pg_type) GETSTRUCT(tuple))->typtype;
/*
* Domains look alot like arrays, so lets process them first, and return
* back to avoid the array and 'standard' formatting procedures that are
* use for base types.
*/
if (typtype == 'd') {
name = NameStr(((Form_pg_type) GETSTRUCT(tuple))->typname);
/*
* Double-quote the name if it's not a standard identifier.
* Note this is *necessary* for ruleutils.c's use.
*/
if (strspn(name, "abcdefghijklmnopqrstuvwxyz0123456789_") != strlen(name)
|| isdigit((unsigned char) name[0]))
buf = psnprintf(strlen(name) + 3, "\"%s\"", name);
else
buf = pstrdup(name);
ReleaseSysCache(tuple);
return buf;
}
if (array_base_type != InvalidOid && typlen < 0) if (array_base_type != InvalidOid && typlen < 0)
{ {
/* Switch our attention to the array element type */ /* Switch our attention to the array element type */
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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 * NOTES
* Eventually, the index information should go through here, too. * Eventually, the index information should go through here, too.
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "catalog/pg_shadow.h" #include "catalog/pg_shadow.h"
#include "catalog/pg_statistic.h" #include "catalog/pg_statistic.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "parser/parse_coerce.h"
#include "utils/array.h" #include "utils/array.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
...@@ -822,16 +823,17 @@ get_typstorage(Oid typid) ...@@ -822,16 +823,17 @@ get_typstorage(Oid typid)
* Returns FALSE if there is no default (effectively, default is NULL). * Returns FALSE if there is no default (effectively, default is NULL).
* The result points to palloc'd storage for pass-by-reference types. * The result points to palloc'd storage for pass-by-reference types.
*/ */
bool Node *
get_typdefault(Oid typid, Datum *defaultValue) get_typdefault(Oid typid, int32 atttypmod)
{ {
HeapTuple typeTuple; HeapTuple typeTuple;
Form_pg_type type; Form_pg_type type;
Oid typinput, Oid typinput;
typelem; Oid typbasetype;
Datum textDefaultVal; char typtype;
Datum datum;
bool isNull; bool isNull;
char *strDefaultVal; Node *expr;
typeTuple = SearchSysCache(TYPEOID, typeTuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(typid), ObjectIdGetDatum(typid),
...@@ -843,38 +845,41 @@ get_typdefault(Oid typid, Datum *defaultValue) ...@@ -843,38 +845,41 @@ get_typdefault(Oid typid, Datum *defaultValue)
type = (Form_pg_type) GETSTRUCT(typeTuple); type = (Form_pg_type) GETSTRUCT(typeTuple);
typinput = type->typinput; 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. * struct field. Must do it the hard way with SysCacheGetAttr.
*/ */
textDefaultVal = SysCacheGetAttr(TYPEOID, datum = SysCacheGetAttr(TYPEOID,
typeTuple, typeTuple,
Anum_pg_type_typdefault, Anum_pg_type_typdefaultbin,
&isNull); &isNull);
if (isNull)
{
ReleaseSysCache(typeTuple); ReleaseSysCache(typeTuple);
*defaultValue = (Datum) 0; if (isNull)
return false; return (Node *) NULL;
}
/* Convert text datum to C string */ /* Convert Datum to a Node */
strDefaultVal = DatumGetCString(DirectFunctionCall1(textout, expr = stringToNode(DatumGetCString(
textDefaultVal)); 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;
} }
/* /*
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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,7 +512,11 @@ RelationBuildTupleDesc(RelationBuildDescInfo buildinfo, ...@@ -512,7 +512,11 @@ RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
(char *) attp, (char *) attp,
ATTRIBUTE_TUPLE_SIZE); ATTRIBUTE_TUPLE_SIZE);
/* Update constraint/default info */
/*
* Update constraint/default info
*/
if (attp->attnotnull) if (attp->attnotnull)
constr->has_not_null = true; constr->has_not_null = true;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 @@ ...@@ -15,6 +15,8 @@
#define HEAP_H #define HEAP_H
#include "catalog/pg_attribute.h" #include "catalog/pg_attribute.h"
#include "nodes/parsenodes.h"
#include "parser/parse_node.h"
#include "utils/rel.h" #include "utils/rel.h"
typedef struct RawColumnDefault typedef struct RawColumnDefault
...@@ -45,6 +47,12 @@ extern void AddRelationRawConstraints(Relation rel, ...@@ -45,6 +47,12 @@ extern void AddRelationRawConstraints(Relation rel,
List *rawColDefaults, List *rawColDefaults,
List *rawConstraints); 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 int RemoveCheckConstraint(Relation rel, const char *constrName, bool inh);
extern Form_pg_attribute SystemAttributeDefinition(AttrNumber attno, extern Form_pg_attribute SystemAttributeDefinition(AttrNumber attno,
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
...@@ -240,7 +240,13 @@ typedef FormData_pg_attribute *Form_pg_attribute; ...@@ -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, {"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, {"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, {"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 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)); 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)); ...@@ -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 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 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 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 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 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)); DATA(insert ( 1247 xmin 28 0 4 -3 0 -1 -1 t p f i f f));
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
...@@ -132,7 +132,7 @@ typedef FormData_pg_class *Form_pg_class; ...@@ -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(""); 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_ )); 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(""); DESCR("");
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
...@@ -140,13 +140,50 @@ CATALOG(pg_type) BOOTSTRAP ...@@ -140,13 +140,50 @@ CATALOG(pg_type) BOOTSTRAP
*/ */
char typstorage; 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 * typdefault is NULL if the type has no associated default value. If
* it's not NULL, it contains the external representation of the * it's not NULL, it contains the external representation of the
* type's default value --- this default is used whenever no * type's default value
* per-column default is specified for a column of the datatype.
*/ */
text typdefault; /* VARIABLE LENGTH FIELD */ text typdefault; /* VARIABLE LENGTH FIELD */
} FormData_pg_type; } FormData_pg_type;
/* ---------------- /* ----------------
...@@ -160,7 +197,7 @@ typedef FormData_pg_type *Form_pg_type; ...@@ -160,7 +197,7 @@ typedef FormData_pg_type *Form_pg_type;
* compiler constants for 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_typname 1
#define Anum_pg_type_typowner 2 #define Anum_pg_type_typowner 2
#define Anum_pg_type_typlen 3 #define Anum_pg_type_typlen 3
...@@ -177,7 +214,13 @@ typedef FormData_pg_type *Form_pg_type; ...@@ -177,7 +214,13 @@ typedef FormData_pg_type *Form_pg_type;
#define Anum_pg_type_typsend 14 #define Anum_pg_type_typsend 14
#define Anum_pg_type_typalign 15 #define Anum_pg_type_typalign 15
#define Anum_pg_type_typstorage 16 #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 * initial contents of pg_type
...@@ -192,82 +235,82 @@ typedef FormData_pg_type *Form_pg_type; ...@@ -192,82 +235,82 @@ typedef FormData_pg_type *Form_pg_type;
*/ */
/* OIDS 1 - 99 */ /* 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'"); DESCR("boolean, 'true'/'false'");
#define BOOLOID 16 #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"); DESCR("variable-length string, binary values escaped");
#define BYTEAOID 17 #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"); DESCR("single character");
#define CHAROID 18 #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"); DESCR("31-character type for storing system identifiers");
#define NAMEOID 19 #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"); DESCR("~18 digit integer, 8-byte storage");
#define INT8OID 20 #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"); DESCR("-32 thousand to 32 thousand, 2-byte storage");
#define INT2OID 21 #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"); DESCR("array of INDEX_MAX_KEYS int2 integers, used in system tables");
#define INT2VECTOROID 22 #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"); DESCR("-2 billion to 2 billion integer, 4-byte storage");
#define INT4OID 23 #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"); DESCR("registered procedure");
#define REGPROCOID 24 #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"); DESCR("variable-length string, no limit specified");
#define TEXTOID 25 #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"); DESCR("object identifier(oid), maximum 4 billion");
#define OIDOID 26 #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"); DESCR("(Block, offset), physical location of tuple");
#define TIDOID 27 #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"); DESCR("transaction id");
#define XIDOID 28 #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"); DESCR("command identifier type, sequence in transaction id");
#define CIDOID 29 #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"); DESCR("array of INDEX_MAX_KEYS oids, used in system tables");
#define OIDVECTOROID 30 #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"); 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 = 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 _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 _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 _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 _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 _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 _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 100 - 199 */
/* OIDS 200 - 299 */ /* 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"); DESCR("storage manager");
/* OIDS 300 - 399 */ /* OIDS 300 - 399 */
...@@ -277,167 +320,167 @@ DESCR("storage manager"); ...@@ -277,167 +320,167 @@ DESCR("storage manager");
/* OIDS 500 - 599 */ /* OIDS 500 - 599 */
/* OIDS 600 - 699 */ /* 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)'"); DESCR("geometric point '(x, y)'");
#define POINTOID 600 #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)'"); DESCR("geometric line segment '(pt1,pt2)'");
#define LSEGOID 601 #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,...)'"); DESCR("geometric path '(pt1,...)'");
#define PATHOID 602 #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)'"); DESCR("geometric box '(lower left,upper right)'");
#define BOXOID 603 #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,...)'"); DESCR("geometric polygon '(pt1,...)'");
#define POLYGONOID 604 #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)'"); DESCR("geometric line '(pt1,pt2)'");
#define LINEOID 628 #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(""); DESCR("");
/* OIDS 700 - 799 */ /* 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"); DESCR("single-precision floating point number, 4-byte storage");
#define FLOAT4OID 700 #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"); DESCR("double-precision floating point number, 8-byte storage");
#define FLOAT8OID 701 #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)"); DESCR("absolute, limited-range date and time (Unix system time)");
#define ABSTIMEOID 702 #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)"); DESCR("relative, limited-range time interval (Unix delta time)");
#define RELTIMEOID 703 #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"); DESCR("(abstime,abstime), time interval");
#define TINTERVALOID 704 #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(""); DESCR("");
#define UNKNOWNOID 705 #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)'"); DESCR("geometric circle '(center,radius)'");
#define CIRCLEOID 718 #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 = 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 _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"); DESCR("$d,ddd.cc, money");
#define CASHOID 790 #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 */ /* 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"); DESCR("XX:XX:XX:XX:XX:XX, MAC address");
#define MACADDROID 829 #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"); DESCR("IP address/netmask, host address, netmask optional");
#define INETOID 869 #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"); DESCR("network IP address/netmask, network address");
#define CIDROID 650 #define CIDROID 650
/* OIDS 900 - 999 */ /* OIDS 900 - 999 */
/* OIDS 1000 - 1099 */ /* 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 = 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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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. * Note: the size of aclitem needs to match sizeof(AclItem) in acl.h.
* Thanks to some padding, this will be 8 on all platforms. * Thanks to some padding, this will be 8 on all platforms.
* We also have an Assert to make sure. * We also have an Assert to make sure.
*/ */
#define ACLITEMSIZE 8 #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"); 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 = 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 _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 _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 _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 _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"); DESCR("char(length), blank-padded string, fixed storage length");
#define BPCHAROID 1042 #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"); DESCR("varchar(length), non-blank-padded string, variable storage length");
#define VARCHAROID 1043 #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"); DESCR("ANSI SQL date");
#define DATEOID 1082 #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"); DESCR("hh:mm:ss, ANSI SQL time");
#define TIMEOID 1083 #define TIMEOID 1083
/* OIDS 1100 - 1199 */ /* 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"); DESCR("date and time");
#define TIMESTAMPOID 1114 #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 = 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 _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 _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 _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"); DESCR("date and time with time zone");
#define TIMESTAMPTZOID 1184 #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 = 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 _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"); DESCR("@ <number> <units>, time interval");
#define INTERVALOID 1186 #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 */ /* 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 = 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 _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"); DESCR("hh:mm:ss, ANSI SQL time");
#define TIMETZOID 1266 #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 */ /* 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"); DESCR("fixed-length bit string");
#define BITOID 1560 #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 = 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 _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"); DESCR("variable-length bit string");
#define VARBITOID 1562 #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 1600 - 1699 */
/* OIDS 1700 - 1799 */ /* 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"); DESCR("numeric(precision, decimal), arbitrary precision number");
#define NUMERICOID 1700 #define NUMERICOID 1700
/* OID 1790 */ /* 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)"); DESCR("reference cursor (portal name)");
#define REFCURSOROID 1790 #define REFCURSOROID 1790
...@@ -447,6 +490,7 @@ DESCR("reference cursor (portal name)"); ...@@ -447,6 +490,7 @@ DESCR("reference cursor (portal name)");
*/ */
extern Oid TypeGet(char *typeName, bool *defined); extern Oid TypeGet(char *typeName, bool *defined);
extern Oid TypeShellMake(char *typeName); extern Oid TypeShellMake(char *typeName);
extern Oid TypeCreate(char *typeName, extern Oid TypeCreate(char *typeName,
Oid assignedTypeOid, Oid assignedTypeOid,
Oid relationOid, Oid relationOid,
...@@ -459,10 +503,17 @@ extern Oid TypeCreate(char *typeName, ...@@ -459,10 +503,17 @@ extern Oid TypeCreate(char *typeName,
char *receiveProcedure, char *receiveProcedure,
char *sendProcedure, char *sendProcedure,
char *elementTypeName, char *elementTypeName,
char *baseTypeName,
char *defaultTypeValue, char *defaultTypeValue,
char *defaultTypeBin,
bool passedByValue, bool passedByValue,
char alignment, char alignment,
char storage); char storage,
int32 typeMod,
int32 typNDims,
bool typeNotNull);
extern void TypeRename(const char *oldTypeName, const char *newTypeName); extern void TypeRename(const char *oldTypeName, const char *newTypeName);
extern char *makeArrayTypeName(char *typeName); extern char *makeArrayTypeName(char *typeName);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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); ...@@ -39,10 +39,12 @@ extern void CreateFunction(ProcedureStmt *stmt);
extern void DefineOperator(char *name, List *parameters); extern void DefineOperator(char *name, List *parameters);
extern void DefineAggregate(char *name, List *parameters); extern void DefineAggregate(char *name, List *parameters);
extern void DefineType(char *name, List *parameters); extern void DefineType(char *name, List *parameters);
extern void DefineDomain(CreateDomainStmt *stmt);
/* /*
* prototypes in remove.c * prototypes in remove.c
*/ */
extern void RemoveDomain(char *domainName, int behavior);
extern void RemoveFunction(char *functionName, List *argTypes); extern void RemoveFunction(char *functionName, List *argTypes);
extern void RemoveOperator(char *operatorName, extern void RemoveOperator(char *operatorName,
char *typeName1, char *typeName2); char *typeName1, char *typeName2);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 ...@@ -172,6 +172,7 @@ typedef enum NodeTag
T_TransactionStmt, T_TransactionStmt,
T_ViewStmt, T_ViewStmt,
T_LoadStmt, T_LoadStmt,
T_CreateDomainStmt,
T_CreatedbStmt, T_CreatedbStmt,
T_DropdbStmt, T_DropdbStmt,
T_VacuumStmt, T_VacuumStmt,
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 ...@@ -468,12 +468,14 @@ typedef struct DefineStmt
#define DROP_INDEX 4 #define DROP_INDEX 4
#define DROP_RULE 5 #define DROP_RULE 5
#define DROP_TYPE_P 6 #define DROP_TYPE_P 6
#define DROP_DOMAIN_P 7
typedef struct DropStmt typedef struct DropStmt
{ {
NodeTag type; NodeTag type;
List *names; List *names;
int removeType; int removeType;
int behavior; /* CASCADE or RESTRICT drop behavior */
} DropStmt; } DropStmt;
/* ---------------------- /* ----------------------
...@@ -682,6 +684,7 @@ typedef struct LoadStmt ...@@ -682,6 +684,7 @@ typedef struct LoadStmt
char *filename; /* file to load */ char *filename; /* file to load */
} LoadStmt; } LoadStmt;
/* ---------------------- /* ----------------------
* Createdb Statement * Createdb Statement
* ---------------------- * ----------------------
...@@ -1280,6 +1283,22 @@ typedef struct DefElem ...@@ -1280,6 +1283,22 @@ typedef struct DefElem
} 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 * Nodes for a Query tree
****************************************************************************/ ****************************************************************************/
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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); ...@@ -81,5 +81,6 @@ extern Oid select_common_type(List *typeids, const char *context);
extern Node *coerce_to_common_type(ParseState *pstate, Node *node, extern Node *coerce_to_common_type(ParseState *pstate, Node *node,
Oid targetTypeId, Oid targetTypeId,
const char *context); const char *context);
extern Oid getBaseType(Oid inType);
#endif /* PARSE_COERCE_H */ #endif /* PARSE_COERCE_H */
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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); ...@@ -44,7 +44,7 @@ extern int16 get_typlen(Oid typid);
extern bool get_typbyval(Oid typid); extern bool get_typbyval(Oid typid);
extern void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval); extern void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval);
extern char get_typstorage(Oid typid); 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_typavgwidth(Oid typid, int32 typmod);
extern int32 get_attavgwidth(Oid relid, AttrNumber attnum); extern int32 get_attavgwidth(Oid relid, AttrNumber attnum);
extern bool get_attstatsslot(HeapTuple statstuple, extern bool get_attstatsslot(HeapTuple statstuple,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment