Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
d3788c33
Commit
d3788c33
authored
Mar 19, 2002
by
Bruce Momjian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add DOMAIN support. Includes manual pages and regression tests, from
Rod Taylor.
parent
525b1939
Changes
36
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
36 changed files
with
1805 additions
and
286 deletions
+1805
-286
doc/src/sgml/catalogs.sgml
doc/src/sgml/catalogs.sgml
+48
-1
doc/src/sgml/ref/allfiles.sgml
doc/src/sgml/ref/allfiles.sgml
+3
-1
doc/src/sgml/ref/comment.sgml
doc/src/sgml/ref/comment.sgml
+8
-7
doc/src/sgml/ref/create_domain.sgml
doc/src/sgml/ref/create_domain.sgml
+231
-0
doc/src/sgml/ref/drop_domain.sgml
doc/src/sgml/ref/drop_domain.sgml
+167
-0
doc/src/sgml/reference.sgml
doc/src/sgml/reference.sgml
+4
-2
src/backend/catalog/heap.c
src/backend/catalog/heap.c
+98
-61
src/backend/catalog/pg_type.c
src/backend/catalog/pg_type.c
+61
-9
src/backend/commands/creatinh.c
src/backend/commands/creatinh.c
+69
-2
src/backend/commands/define.c
src/backend/commands/define.c
+360
-4
src/backend/commands/remove.c
src/backend/commands/remove.c
+57
-2
src/backend/nodes/copyfuncs.c
src/backend/nodes/copyfuncs.c
+18
-1
src/backend/nodes/equalfuncs.c
src/backend/nodes/equalfuncs.c
+17
-1
src/backend/optimizer/prep/preptlist.c
src/backend/optimizer/prep/preptlist.c
+32
-22
src/backend/parser/gram.y
src/backend/parser/gram.y
+67
-14
src/backend/parser/keywords.c
src/backend/parser/keywords.c
+2
-1
src/backend/parser/parse_coerce.c
src/backend/parser/parse_coerce.c
+30
-1
src/backend/parser/parse_expr.c
src/backend/parser/parse_expr.c
+4
-3
src/backend/tcop/postgres.c
src/backend/tcop/postgres.c
+4
-3
src/backend/tcop/utility.c
src/backend/tcop/utility.c
+19
-1
src/backend/utils/adt/format_type.c
src/backend/utils/adt/format_type.c
+27
-1
src/backend/utils/cache/lsyscache.c
src/backend/utils/cache/lsyscache.c
+34
-29
src/backend/utils/cache/relcache.c
src/backend/utils/cache/relcache.c
+7
-3
src/include/catalog/heap.h
src/include/catalog/heap.h
+9
-1
src/include/catalog/pg_attribute.h
src/include/catalog/pg_attribute.h
+14
-3
src/include/catalog/pg_class.h
src/include/catalog/pg_class.h
+2
-2
src/include/catalog/pg_type.h
src/include/catalog/pg_type.h
+154
-103
src/include/commands/defrem.h
src/include/commands/defrem.h
+3
-1
src/include/nodes/nodes.h
src/include/nodes/nodes.h
+2
-1
src/include/nodes/parsenodes.h
src/include/nodes/parsenodes.h
+21
-1
src/include/parser/parse_coerce.h
src/include/parser/parse_coerce.h
+2
-1
src/include/utils/lsyscache.h
src/include/utils/lsyscache.h
+2
-2
src/test/regress/expected/domain.out
src/test/regress/expected/domain.out
+114
-0
src/test/regress/parallel_schedule
src/test/regress/parallel_schedule
+1
-1
src/test/regress/serial_schedule
src/test/regress/serial_schedule
+3
-1
src/test/regress/sql/domain.sql
src/test/regress/sql/domain.sql
+111
-0
No files found.
doc/src/sgml/catalogs.sgml
View file @
d3788c33
<!--
Documentation of the system catalogs, directed toward PostgreSQL developers
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.3
3 2002/03/07 16:35:32
momjian Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.3
4 2002/03/19 02:18:10
momjian Exp $
-->
<chapter id="catalogs">
...
...
@@ -2510,6 +2510,53 @@
</para></entry>
</row>
<row>
<entry>typbasetype</entry>
<entry><type>oid</type></entry>
<entry></entry>
<entry><para>
<structfield>typbasetype</structfield> is the type that this one is based
on. 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. Used for domains only.
</para></entry>
</row>
<row>
<entry>typmod</entry>
<entry><type>integer</type></entry>
<entry></entry>
<entry><para>
<structfield>typmod</structfield> records type-specific data
supplied at table creation time (for example, the maximum
length of a <type>varchar</type> column). It is passed to
type-specific input and output functions as the third
argument. The value will generally be -1 for types that do not
need typmod. This data is copied to
<structfield>pg_attribute.atttypmod</structfield> on creation
of a table using a domain as it's field type.
</para></entry>
</row>
<row>
<entry>typdefaultbin</entry>
<entry><type>text</type></entry>
<entry></entry>
<entry><para>
<structfield>typdefaultbin</structfield> is NULL for types without a
default value. If it's not NULL, it contains the internal string
representation of the default expression node.
</para></entry>
</row>
<row>
<entry>typdefault</entry>
<entry><type>text</type></entry>
...
...
doc/src/sgml/ref/allfiles.sgml
View file @
d3788c33
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/allfiles.sgml,v 1.3
5 2002/03/07 16:35:3
2 momjian Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/allfiles.sgml,v 1.3
6 2002/03/19 02:18:1
2 momjian Exp $
PostgreSQL documentation
Complete list of usable sgml source files in this directory.
-->
...
...
@@ -52,6 +52,7 @@ Complete list of usable sgml source files in this directory.
<!entity createAggregate system "create_aggregate.sgml">
<!entity createConstraint system "create_constraint.sgml">
<!entity createDatabase system "create_database.sgml">
<!entity createDomain system "create_domain.sgml">
<!entity createFunction system "create_function.sgml">
<!entity createGroup system "create_group.sgml">
<!entity createIndex system "create_index.sgml">
...
...
@@ -69,6 +70,7 @@ Complete list of usable sgml source files in this directory.
<!entity delete system "delete.sgml">
<!entity dropAggregate system "drop_aggregate.sgml">
<!entity dropDatabase system "drop_database.sgml">
<!entity dropDomain system "drop_domain.sgml">
<!entity dropFunction system "drop_function.sgml">
<!entity dropGroup system "drop_group.sgml">
<!entity dropIndex system "drop_index.sgml">
...
...
doc/src/sgml/ref/comment.sgml
View file @
d3788c33
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/comment.sgml,v 1.1
4 2002/03/07 16:35:33
momjian Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/comment.sgml,v 1.1
5 2002/03/19 02:18:12
momjian Exp $
PostgreSQL documentation
-->
...
...
@@ -25,7 +25,7 @@ PostgreSQL documentation
<synopsis>
COMMENT ON
[
[ DATABASE | INDEX | RULE | SEQUENCE | TABLE | TYPE | VIEW ] <replaceable class="PARAMETER">object_name</replaceable> |
[ DATABASE |
DOMAIN |
INDEX | RULE | SEQUENCE | TABLE | TYPE | VIEW ] <replaceable class="PARAMETER">object_name</replaceable> |
COLUMN <replaceable class="PARAMETER">table_name</replaceable>.<replaceable class="PARAMETER">column_name</replaceable> |
AGGREGATE <replaceable class="PARAMETER">agg_name</replaceable> (<replaceable class="PARAMETER">agg_type</replaceable>) |
FUNCTION <replaceable class="PARAMETER">func_name</replaceable> (<replaceable class="PARAMETER">arg1</replaceable>, <replaceable class="PARAMETER">arg2</replaceable>, ...) |
...
...
@@ -33,7 +33,7 @@ COMMENT ON
TRIGGER <replaceable class="PARAMETER">trigger_name</replaceable> ON <replaceable class="PARAMETER">table_name</replaceable>
] IS <replaceable class="PARAMETER">'text'</replaceable>
</synopsis>
<refsect2 id="R2-SQL-COMMENT-1">
<refsect2info>
<date>1999-10-25</date>
...
...
@@ -64,7 +64,7 @@ COMMENT ON
</variablelist>
</para>
</refsect2>
<refsect2 id="R2-SQL-COMMENT-2">
<refsect2info>
<date>1998-09-08</date>
...
...
@@ -99,7 +99,7 @@ COMMENT
</title>
<para>
<command>COMMENT</command> stores a comment about a database object.
Comments can be
Comments can be
easily retrieved with <command>psql</command>'s
<command>\dd</command>, <command>\d+</command>, or <command>\l+</command>
commands. Other user interfaces to retrieve comments can be built atop
...
...
@@ -141,6 +141,7 @@ COMMENT ON mytable IS 'This is my table.';
<programlisting>
COMMENT ON DATABASE my_database IS 'Development Database';
COMMENT ON DOMAIN my_domain IS 'Email Address Domain';
COMMENT ON INDEX my_index IS 'Enforces uniqueness on employee id';
COMMENT ON RULE my_rule IS 'Logs UPDATES of employee records';
COMMENT ON SEQUENCE my_sequence IS 'Used to generate primary keys';
...
...
@@ -155,12 +156,12 @@ COMMENT ON TRIGGER my_trigger ON my_table IS 'Used for R.I.';
</programlisting>
</para>
</refsect1>
<refsect1 id="R1-SQL-COMMENT-3">
<title>
Compatibility
</title>
<refsect2 id="R2-SQL-COMMENT-4">
<refsect2info>
<date>1998-09-08</date>
...
...
doc/src/sgml/ref/create_domain.sgml
0 → 100644
View file @
d3788c33
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_domain.sgml,v 1.3 2002/03/19 02:18:13 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:
-->
doc/src/sgml/ref/drop_domain.sgml
0 → 100644
View file @
d3788c33
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_domain.sgml,v 1.3 2002/03/19 02:18:13 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:
-->
doc/src/sgml/reference.sgml
View file @
d3788c33
<!-- reference.sgml
$Header: /cvsroot/pgsql/doc/src/sgml/reference.sgml,v 1.2
3 2002/03/07 16:35:32
momjian Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/reference.sgml,v 1.2
4 2002/03/19 02:18:11
momjian Exp $
PostgreSQL Reference Manual
-->
...
...
@@ -61,6 +61,7 @@ PostgreSQL Reference Manual
&createAggregate;
&createConstraint;
&createDatabase;
&createDomain;
&createFunction;
&createGroup;
&createIndex;
...
...
@@ -78,6 +79,7 @@ PostgreSQL Reference Manual
&delete;
&dropAggregate;
&dropDatabase;
&dropDomain;
&dropFunction;
&dropGroup;
&dropIndex;
...
...
@@ -115,7 +117,7 @@ PostgreSQL Reference Manual
&unlisten;
&update;
&vacuum;
</reference>
<!--
...
...
src/backend/catalog/heap.c
View file @
d3788c33
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.18
6 2002/03/07 16:35:33
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.18
7 2002/03/19 02:18:14
momjian Exp $
*
*
* INTERFACE ROUTINES
...
...
@@ -49,6 +49,7 @@
#include "optimizer/planmain.h"
#include "optimizer/prep.h"
#include "optimizer/var.h"
#include "parser/parse_coerce.h"
#include "parser/parse_expr.h"
#include "parser/parse_relation.h"
#include "parser/parse_target.h"
...
...
@@ -698,10 +699,15 @@ AddNewRelationType(char *typeName, Oid new_rel_oid, Oid new_type_oid)
"oidin"
,
/* receive procedure */
"oidout"
,
/* send procedure */
NULL
,
/* array element type - irrelevant */
NULL
,
/* baseType Name -- typically for domains */
NULL
,
/* default type value - none */
NULL
,
/* default type binary representation */
true
,
/* passed by value */
'i'
,
/* default alignment - same as for OID */
'p'
);
/* Not TOASTable */
'p'
,
/* Not TOASTable */
-
1
,
/* Type mod length */
0
,
/* array dimensions for typBaseType */
false
);
/* Type NOT NULL */
}
/* --------------------------------
...
...
@@ -1584,6 +1590,10 @@ AddRelationRawConstraints(Relation rel,
int
numchecks
;
List
*
listptr
;
/* Probably shouldn't be null by default */
Node
*
expr
=
NULL
;
/*
* Get info about existing constraints.
*/
...
...
@@ -1614,68 +1624,13 @@ AddRelationRawConstraints(Relation rel,
foreach
(
listptr
,
rawColDefaults
)
{
RawColumnDefault
*
colDef
=
(
RawColumnDefault
*
)
lfirst
(
listptr
);
Node
*
expr
;
Oid
type_id
;
Assert
(
colDef
->
raw_default
!=
NULL
);
/*
* Transform raw parsetree to executable expression.
*/
expr
=
transformExpr
(
pstate
,
colDef
->
raw_default
,
EXPR_COLUMN_FIRST
);
/*
* Make sure default expr does not refer to any vars.
*/
if
(
contain_var_clause
(
expr
))
elog
(
ERROR
,
"cannot use column references in DEFAULT clause"
);
/*
* No subplans or aggregates, either...
*/
if
(
contain_subplans
(
expr
))
elog
(
ERROR
,
"cannot use subselects in DEFAULT clause"
);
if
(
contain_agg_clause
(
expr
))
elog
(
ERROR
,
"cannot use aggregate functions in DEFAULT clause"
);
/*
* Check that it will be possible to coerce the expression to the
* column's type. We store the expression without coercion,
* however, to avoid premature coercion in cases like
*
* CREATE TABLE tbl (fld datetime DEFAULT 'now'::text);
*
* NB: this should match the code in optimizer/prep/preptlist.c that
* will actually do the coercion, to ensure we don't accept an
* unusable default expression.
*/
type_id
=
exprType
(
expr
);
if
(
type_id
!=
InvalidOid
)
{
Form_pg_attribute
atp
=
rel
->
rd_att
->
attrs
[
colDef
->
attnum
-
1
];
if
(
type_id
!=
atp
->
atttypid
)
{
if
(
CoerceTargetExpr
(
NULL
,
expr
,
type_id
,
atp
->
atttypid
,
atp
->
atttypmod
)
==
NULL
)
elog
(
ERROR
,
"Column
\"
%s
\"
is of type %s"
" but default expression is of type %s"
"
\n\t
You will need to rewrite or cast the expression"
,
NameStr
(
atp
->
attname
),
format_type_be
(
atp
->
atttypid
),
format_type_be
(
type_id
));
}
}
Form_pg_attribute
atp
=
rel
->
rd_att
->
attrs
[
colDef
->
attnum
-
1
];
/*
* Might as well try to reduce any constant expressions.
*/
expr
=
eval_const_expressions
(
expr
);
/*
* Must fix opids, in case any operators remain...
*/
fix_opids
(
expr
);
expr
=
cookDefault
(
pstate
,
colDef
->
raw_default
,
atp
->
atttypid
,
atp
->
atttypmod
,
NameStr
(
atp
->
attname
));
/*
* OK, store it.
...
...
@@ -1892,6 +1847,88 @@ SetRelationNumChecks(Relation rel, int numchecks)
heap_close
(
relrel
,
RowExclusiveLock
);
}
/*
* Take a raw default and convert it to a cooked format ready for
* storage.
*
* Parse state, attypid, attypmod and attname are required for
* CoerceTargetExpr() and more importantly transformExpr().
*/
Node
*
cookDefault
(
ParseState
*
pstate
,
Node
*
raw_default
,
Oid
atttypid
,
int32
atttypmod
,
char
*
attname
)
{
Oid
type_id
;
Node
*
expr
;
Assert
(
raw_default
!=
NULL
);
/*
* Transform raw parsetree to executable expression.
*/
expr
=
transformExpr
(
pstate
,
raw_default
,
EXPR_COLUMN_FIRST
);
/*
* Make sure default expr does not refer to any vars.
*/
if
(
contain_var_clause
(
expr
))
elog
(
ERROR
,
"cannot use column references in DEFAULT clause"
);
/*
* No subplans or aggregates, either...
*/
if
(
contain_subplans
(
expr
))
elog
(
ERROR
,
"cannot use subselects in DEFAULT clause"
);
if
(
contain_agg_clause
(
expr
))
elog
(
ERROR
,
"cannot use aggregate functions in DEFAULT clause"
);
/*
* Check that it will be possible to coerce the expression to the
* column's type. We store the expression without coercion,
* however, to avoid premature coercion in cases like
*
* CREATE TABLE tbl (fld datetime DEFAULT 'now'::text);
*
* NB: this should match the code in optimizer/prep/preptlist.c that
* will actually do the coercion, to ensure we don't accept an
* unusable default expression.
*/
type_id
=
exprType
(
expr
);
if
(
type_id
!=
InvalidOid
&&
atttypid
!=
InvalidOid
)
{
if
(
type_id
!=
atttypid
)
{
/* Try coercing to the base type of the domain if available */
if
(
CoerceTargetExpr
(
pstate
,
expr
,
type_id
,
getBaseType
(
atttypid
),
atttypmod
)
==
NULL
)
{
elog
(
ERROR
,
"Column
\"
%s
\"
is of type %s"
" but default expression is of type %s"
"
\n\t
You will need to rewrite or cast the expression"
,
attname
,
format_type_be
(
atttypid
),
format_type_be
(
type_id
));
}
}
}
/*
* Might as well try to reduce any constant expressions.
*/
expr
=
eval_const_expressions
(
expr
);
/*
* Must fix opids, in case any operators remain...
*/
fix_opids
(
expr
);
return
(
expr
);
}
static
void
RemoveAttrDefaults
(
Relation
rel
)
{
...
...
src/backend/catalog/pg_type.c
View file @
d3788c33
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.6
7 2002/03/07 16:35:33
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.6
8 2002/03/19 02:18:14
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -176,10 +176,16 @@ TypeShellMakeWithOpenRelation(Relation pg_type_desc, char *typeName)
values
[
i
++
]
=
ObjectIdGetDatum
(
InvalidOid
);
/* 12 */
values
[
i
++
]
=
ObjectIdGetDatum
(
InvalidOid
);
/* 13 */
values
[
i
++
]
=
ObjectIdGetDatum
(
InvalidOid
);
/* 14 */
values
[
i
++
]
=
CharGetDatum
(
'i'
);
/* 15 */
values
[
i
++
]
=
CharGetDatum
(
'p'
);
/* 16 */
values
[
i
++
]
=
CharGetDatum
(
'i'
);
/* 15 */
values
[
i
++
]
=
CharGetDatum
(
'p'
);
/* 16 */
values
[
i
++
]
=
BoolGetDatum
(
false
);
/* 17 */
values
[
i
++
]
=
Int32GetDatum
(
-
1
);
/* 18 */
values
[
i
++
]
=
ObjectIdGetDatum
(
InvalidOid
);
/* 19 */
values
[
i
++
]
=
Int32GetDatum
(
0
);
/* 20 */
values
[
i
++
]
=
DirectFunctionCall1
(
textin
,
CStringGetDatum
(
typeName
));
/* 17 */
CStringGetDatum
(
typeName
));
/* 21 */
values
[
i
++
]
=
DirectFunctionCall1
(
textin
,
CStringGetDatum
(
typeName
));
/* 22 */
/*
* create a new type tuple with FormHeapTuple
...
...
@@ -264,7 +270,7 @@ TypeShellMake(char *typeName)
Oid
TypeCreate
(
char
*
typeName
,
Oid
assignedTypeOid
,
Oid
relationOid
,
/* only for 'c'atalog typeTypes */
Oid
relationOid
,
/* only for 'c'atalog typeTypes */
int16
internalSize
,
int16
externalSize
,
char
typeType
,
...
...
@@ -274,10 +280,15 @@ TypeCreate(char *typeName,
char
*
receiveProcedure
,
char
*
sendProcedure
,
char
*
elementTypeName
,
char
*
defaultTypeValue
,
/* internal rep */
char
*
baseTypeName
,
char
*
defaultTypeValue
,
/* human readable rep */
char
*
defaultTypeBin
,
/* cooked rep */
bool
passedByValue
,
char
alignment
,
char
storage
)
char
storage
,
int32
typeMod
,
int32
typNDims
,
/* Array dimensions for baseTypeName */
bool
typeNotNull
)
/* binary default representation (cooked) */
{
int
i
,
j
;
...
...
@@ -285,6 +296,7 @@ TypeCreate(char *typeName,
HeapScanDesc
pg_type_scan
;
Oid
typeObjectId
;
Oid
elementObjectId
=
InvalidOid
;
Oid
baseObjectId
=
InvalidOid
;
HeapTuple
tup
;
char
nulls
[
Natts_pg_type
];
char
replaces
[
Natts_pg_type
];
...
...
@@ -317,6 +329,17 @@ TypeCreate(char *typeName,
elog
(
ERROR
,
"type %s does not exist"
,
elementTypeName
);
}
/*
* if this type has an associated baseType, then we check that it
* is defined.
*/
if
(
baseTypeName
)
{
baseObjectId
=
TypeGet
(
baseTypeName
,
&
defined
);
if
(
!
defined
)
elog
(
ERROR
,
"type %s does not exist"
,
baseTypeName
);
}
/*
* validate size specifications: either positive (fixed-length) or -1
* (variable-length).
...
...
@@ -388,7 +411,7 @@ TypeCreate(char *typeName,
* signature is 0,OIDOID,INT4OID. The output procedures may
* take 2 args (data value, element OID).
*/
if
(
OidIsValid
(
elementObjectId
))
if
(
OidIsValid
(
elementObjectId
)
||
OidIsValid
(
baseObjectId
)
)
{
int
nargs
;
...
...
@@ -411,6 +434,7 @@ TypeCreate(char *typeName,
PointerGetDatum
(
argList
),
0
);
}
if
(
!
OidIsValid
(
procOid
))
func_error
(
"TypeCreate"
,
procname
,
1
,
argList
,
NULL
);
}
...
...
@@ -428,6 +452,34 @@ TypeCreate(char *typeName,
*/
values
[
i
++
]
=
CharGetDatum
(
storage
);
/* 16 */
/*
* set the typenotnull value
*/
values
[
i
++
]
=
BoolGetDatum
(
typeNotNull
);
/* 17 */
/*
* set the typemod value
*/
values
[
i
++
]
=
Int32GetDatum
(
typeMod
);
/* 18 */
values
[
i
++
]
=
ObjectIdGetDatum
(
baseObjectId
);
/* 19 */
/*
* Dimension number for an array base type
*/
values
[
i
++
]
=
Int32GetDatum
(
typNDims
);
/* 20 */
/*
* initialize the default binary value for this type. Check for
* nulls of course.
*/
if
(
defaultTypeBin
)
values
[
i
]
=
DirectFunctionCall1
(
textin
,
CStringGetDatum
(
defaultTypeBin
));
else
nulls
[
i
]
=
'n'
;
i
++
;
/* 21 */
/*
* initialize the default value for this type.
*/
...
...
@@ -436,7 +488,7 @@ TypeCreate(char *typeName,
CStringGetDatum
(
defaultTypeValue
));
else
nulls
[
i
]
=
'n'
;
i
++
;
/*
17
*/
i
++
;
/*
22
*/
/*
* open pg_type and begin a scan for the type name.
...
...
src/backend/commands/creatinh.c
View file @
d3788c33
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.8
5 2002/03/07 16:35:34
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.8
6 2002/03/19 02:18:15
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -39,7 +39,7 @@ static bool change_varattnos_of_a_node(Node *node, const AttrNumber *newattno);
static
void
StoreCatalogInheritance
(
Oid
relationId
,
List
*
supers
);
static
int
findAttrByName
(
const
char
*
attributeName
,
List
*
schema
);
static
void
setRelhassubclassInRelation
(
Oid
relationId
,
bool
relhassubclass
);
static
List
*
MergeDomainAttributes
(
List
*
schema
);
/* ----------------------------------------------------------------
* DefineRelation
...
...
@@ -69,6 +69,13 @@ DefineRelation(CreateStmt *stmt, char relkind)
*/
StrNCpy
(
relname
,
stmt
->
relname
,
NAMEDATALEN
);
/*
* Inherit domain attributes into the known columns before table inheritance
* applies it's changes otherwise we risk adding double constraints
* to a domain thats inherited.
*/
schema
=
MergeDomainAttributes
(
schema
);
/*
* Look up inheritance ancestors and generate relation schema,
* including inherited attributes.
...
...
@@ -237,6 +244,66 @@ TruncateRelation(char *name)
heap_truncate
(
name
);
}
/*
* MergeDomainAttributes
* Returns a new table schema with the constraints, types, and other
* attributes of the domain resolved for fields using the domain as
* their type.
*
* Defaults are pulled out by the table attribute as required, similar to
* how all types defaults are processed.
*/
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
);
}
return
schema
;
}
/*----------
* MergeAttributes
* Returns new schema given initial schema and superclasses.
...
...
src/backend/commands/define.c
View file @
d3788c33
This diff is collapsed.
Click to expand it.
src/backend/commands/remove.c
View file @
d3788c33
/*-------------------------------------------------------------------------
*
* remove.c
* POSTGRES remove (function | type | operator ) utilty code.
* POSTGRES remove (
domain |
function | type | operator ) utilty code.
*
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.6
8 2002/03/07 16:35:34
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.6
9 2002/03/19 02:18:16
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -22,6 +22,7 @@
#include "commands/comment.h"
#include "commands/defrem.h"
#include "miscadmin.h"
#include "parser/parse.h"
#include "parser/parse_agg.h"
#include "parser/parse_expr.h"
#include "parser/parse_func.h"
...
...
@@ -275,6 +276,60 @@ RemoveType(char *typeName) /* type name to be removed */
heap_close
(
relation
,
RowExclusiveLock
);
}
/*
* RemoveDomain
* Removes the domain 'typeName' and all attributes and relations that
* use it.
*/
void
RemoveDomain
(
char
*
domainName
,
int
behavior
)
/* domain name to be removed */
{
Relation
relation
;
HeapTuple
tup
;
TupleDesc
description
;
char
typtype
;
bool
isnull
;
/* Domains are stored as types. Check for permissions on the type */
if
(
!
pg_ownercheck
(
GetUserId
(),
domainName
,
TYPENAME
))
elog
(
ERROR
,
"RemoveDomain: type '%s': permission denied"
,
domainName
);
relation
=
heap_openr
(
TypeRelationName
,
RowExclusiveLock
);
description
=
RelationGetDescr
(
relation
);
tup
=
SearchSysCache
(
TYPENAME
,
PointerGetDatum
(
domainName
),
0
,
0
,
0
);
if
(
!
HeapTupleIsValid
(
tup
))
elog
(
ERROR
,
"RemoveType: type '%s' does not exist"
,
domainName
);
/* Check that this is actually a domain */
typtype
=
DatumGetChar
(
heap_getattr
(
tup
,
Anum_pg_type_typtype
,
description
,
&
isnull
));
Assert
(
!
isnull
);
if
(
typtype
!=
'd'
)
{
elog
(
ERROR
,
"%s is not a domain"
,
domainName
);
}
/* CASCADE unsupported */
if
(
behavior
==
CASCADE
)
{
elog
(
ERROR
,
"DROP DOMAIN does not support the CASCADE keyword"
);
}
/* Delete any comments associated with this type */
DeleteComments
(
tup
->
t_data
->
t_oid
,
RelationGetRelid
(
relation
));
simple_heap_delete
(
relation
,
&
tup
->
t_self
);
ReleaseSysCache
(
tup
);
heap_close
(
relation
,
RowExclusiveLock
);
}
/*
* RemoveFunction
* Deletes a function.
...
...
src/backend/nodes/copyfuncs.c
View file @
d3788c33
...
...
@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.1
69 2002/03/12 00:51:37 tgl
Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.1
70 2002/03/19 02:18:16 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -2231,6 +2231,20 @@ _copyLoadStmt(LoadStmt *from)
return
newnode
;
}
static
CreateDomainStmt
*
_copyCreateDomainStmt
(
CreateDomainStmt
*
from
)
{
CreateDomainStmt
*
newnode
=
makeNode
(
CreateDomainStmt
);
if
(
from
->
domainname
)
newnode
->
domainname
=
pstrdup
(
from
->
domainname
);
Node_Copy
(
from
,
newnode
,
typename
);
Node_Copy
(
from
,
newnode
,
constraints
);
return
newnode
;
}
static
CreatedbStmt
*
_copyCreatedbStmt
(
CreatedbStmt
*
from
)
{
...
...
@@ -3031,6 +3045,9 @@ copyObject(void *from)
case
T_FuncWithArgs
:
retval
=
_copyFuncWithArgs
(
from
);
break
;
case
T_CreateDomainStmt
:
retval
=
_copyCreateDomainStmt
(
from
);
break
;
default:
elog
(
ERROR
,
"copyObject: don't know how to copy node type %d"
,
...
...
src/backend/nodes/equalfuncs.c
View file @
d3788c33
...
...
@@ -20,7 +20,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.11
7 2002/03/12 00:51:37 tgl
Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.11
8 2002/03/19 02:18:16 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -1093,6 +1093,19 @@ _equalLoadStmt(LoadStmt *a, LoadStmt *b)
return
true
;
}
static
bool
_equalCreateDomainStmt
(
CreateDomainStmt
*
a
,
CreateDomainStmt
*
b
)
{
if
(
!
equalstr
(
a
->
domainname
,
b
->
domainname
))
return
false
;
if
(
!
equal
(
a
->
typename
,
b
->
typename
))
return
false
;
if
(
!
equal
(
a
->
constraints
,
b
->
constraints
))
return
false
;
return
true
;
}
static
bool
_equalCreatedbStmt
(
CreatedbStmt
*
a
,
CreatedbStmt
*
b
)
{
...
...
@@ -2021,6 +2034,9 @@ equal(void *a, void *b)
case
T_LoadStmt
:
retval
=
_equalLoadStmt
(
a
,
b
);
break
;
case
T_CreateDomainStmt
:
retval
=
_equalCreateDomainStmt
(
a
,
b
);
break
;
case
T_CreatedbStmt
:
retval
=
_equalCreatedbStmt
(
a
,
b
);
break
;
...
...
src/backend/optimizer/prep/preptlist.c
View file @
d3788c33
...
...
@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.4
8 2002/03/07 16:35:35
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.4
9 2002/03/19 02:18:17
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -355,8 +355,6 @@ build_column_default(Relation rel, int attrno)
Form_pg_attribute
att_tup
=
rd_att
->
attrs
[
attrno
-
1
];
Oid
atttype
=
att_tup
->
atttypid
;
int32
atttypmod
=
att_tup
->
atttypmod
;
bool
hasdefault
;
Datum
typedefault
;
int16
typlen
;
bool
typbyval
;
Node
*
expr
;
...
...
@@ -392,7 +390,7 @@ build_column_default(Relation rel, int attrno)
if
(
type_id
!=
atttype
)
{
expr
=
CoerceTargetExpr
(
NULL
,
expr
,
type_id
,
atttype
,
atttypmod
);
getBaseType
(
atttype
)
,
atttypmod
);
/*
* This really shouldn't fail; should have checked the
...
...
@@ -430,41 +428,53 @@ build_column_default(Relation rel, int attrno)
* element type is, and the element type's default is irrelevant
* too.
*/
hasdefault
=
false
;
typedefault
=
(
Datum
)
0
;
typlen
=
sizeof
(
Oid
);
typbyval
=
true
;
expr
=
(
Node
*
)
makeConst
(
atttype
,
typlen
,
(
Datum
)
0
,
true
,
typbyval
,
false
,
/* not a set */
false
);
}
else
{
#ifdef _DROP_COLUMN_HACK__
if
(
COLUMN_IS_DROPPED
(
att_tup
))
{
hasdefault
=
false
;
typedefault
=
(
Datum
)
0
;
expr
=
(
Node
*
)
makeConst
(
atttype
,
typlen
,
(
Datum
)
0
,
true
,
typbyval
,
false
,
/* not a set */
false
);
}
else
#endif
/* _DROP_COLUMN_HACK__ */
hasdefault
=
get_typdefault
(
atttype
,
&
typedefault
);
expr
=
get_typdefault
(
atttype
,
atttypmod
);
if
(
expr
==
NULL
)
{
expr
=
(
Node
*
)
makeConst
(
atttype
,
typlen
,
(
Datum
)
0
,
true
,
typbyval
,
false
,
/* not a set */
false
);
}
get_typlenbyval
(
atttype
,
&
typlen
,
&
typbyval
);
}
expr
=
(
Node
*
)
makeConst
(
atttype
,
typlen
,
typedefault
,
!
hasdefault
,
typbyval
,
false
,
/* not a set */
false
);
/*
* If the column is a fixed-length type, it may need a length coercion
* as well as a type coercion
. But NULLs don't need that
.
* as well as a type coercion
, as well as direction to the final type
.
*/
if
(
hasdefault
)
expr
=
coerce_type_typmod
(
NULL
,
expr
,
atttype
,
atttypmod
);
expr
=
coerce_type_typmod
(
NULL
,
expr
,
atttype
,
atttypmod
);
return
expr
;
}
src/backend/parser/gram.y
View file @
d3788c33
...
...
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.29
1 2002/03/10 06:02:23
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.29
2 2002/03/19 02:18:18
momjian Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
...
...
@@ -98,7 +98,6 @@ static void doNegateFloat(Value *v);
%}
%union
{
int ival;
...
...
@@ -134,9 +133,10 @@ static void doNegateFloat(Value *v);
AlterDatabaseSetStmt, AlterGroupStmt, AlterSchemaStmt, AlterTableStmt,
AlterUserStmt, AlterUserSetStmt, AnalyzeStmt,
ClosePortalStmt, ClusterStmt, CommentStmt, ConstraintsSetStmt,
CopyStmt, CreateAsStmt, CreateGroupStmt, CreatePLangStmt,
CopyStmt, CreateAsStmt, Create
DomainStmt, Create
GroupStmt, CreatePLangStmt,
CreateSchemaStmt, CreateSeqStmt, CreateStmt, CreateTrigStmt,
CreateUserStmt, CreatedbStmt, CursorStmt, DefineStmt, DeleteStmt,
CreateUserStmt, CreatedbStmt, CursorStmt,
DefineStmt, DeleteStmt,
DropGroupStmt, DropPLangStmt, DropSchemaStmt, DropStmt, DropTrigStmt,
DropUserStmt, DropdbStmt, ExplainStmt, FetchStmt,
GrantStmt, IndexStmt, InsertStmt, ListenStmt, LoadStmt, LockStmt,
...
...
@@ -289,6 +289,8 @@ static void doNegateFloat(Value *v);
%type <list> constraints_set_list
%type <boolean> constraints_set_mode
%type <boolean> opt_as
/*
* If you make any token changes, remember to:
* - use "yacc -d" and update parse.h
...
...
@@ -343,7 +345,7 @@ static void doNegateFloat(Value *v);
WITHOUT
/* Keywords (in SQL92 non-reserved words) */
%token COMMITTED, SERIALIZABLE, TYPE_P
%token COMMITTED, SERIALIZABLE, TYPE_P
, DOMAIN_P
/* Keywords for Postgres support (not in SQL92 reserved words)
*
...
...
@@ -446,6 +448,7 @@ stmt : AlterDatabaseSetStmt
| CopyStmt
| CreateStmt
| CreateAsStmt
| CreateDomainStmt
| CreateSchemaStmt
| CreateGroupStmt
| CreateSeqStmt
...
...
@@ -776,8 +779,11 @@ DropSchemaStmt: DROP SCHEMA UserId
n->dbname = $3;
$$ = (Node *)n;
}
;
/*****************************************************************************
*
* Set PG internal variable
...
...
@@ -1439,7 +1445,10 @@ ColConstraintElem:
n->name = NULL;
if (exprIsNullConstant($2))
{
/* DEFAULT NULL should be reported as empty expr */
/*
* DEFAULT NULL should be reported as empty expr
* Required for NOT NULL Domain overrides
*/
n->raw_expr = NULL;
}
else
...
...
@@ -2021,13 +2030,22 @@ def_list: def_elem { $$ = makeList1($1); }
| def_list ',' def_elem { $$ = lappend($1, $3); }
;
def_elem: ColLabel '=' def_arg
def_elem: DEFAULT '=' b_expr
{
$$ = makeNode(DefElem);
$$->defname = "default";
if (exprIsNullConstant($3))
$$->arg = (Node *)NULL;
else
$$->arg = $3;
}
| ColId '=' def_arg
{
$$ = makeNode(DefElem);
$$->defname = $1;
$$->arg = (Node *)$3;
}
| Col
Label
| Col
Id
{
$$ = makeNode(DefElem);
$$->defname = $1;
...
...
@@ -2056,6 +2074,15 @@ DropStmt: DROP drop_type name_list
DropStmt *n = makeNode(DropStmt);
n->removeType = $2;
n->names = $3;
n->behavior = RESTRICT; /* Restricted by default */
$$ = (Node *)n;
}
| DROP DOMAIN_P name_list drop_behavior
{
DropStmt *n = makeNode(DropStmt);
n->removeType = DROP_DOMAIN_P;
n->names = $3;
n->behavior = $4;
$$ = (Node *)n;
}
;
...
...
@@ -2088,7 +2115,7 @@ TruncateStmt: TRUNCATE opt_table relation_name
* The COMMENT ON statement can take different forms based upon the type of
* the object associated with the comment. The form of the statement is:
*
* COMMENT ON [ [ DATABASE | INDEX | RULE | SEQUENCE | TABLE | TYPE | VIEW ]
* COMMENT ON [ [ DATABASE |
DOMAIN |
INDEX | RULE | SEQUENCE | TABLE | TYPE | VIEW ]
* <objname> | AGGREGATE <aggname> (<aggtype>) | FUNCTION
* <funcname> (arg1, arg2, ...) | OPERATOR <op>
* (leftoperand_typ rightoperand_typ) | TRIGGER <triggername> ON
...
...
@@ -2174,6 +2201,7 @@ comment_type: DATABASE { $$ = DATABASE; }
| RULE { $$ = RULE; }
| SEQUENCE { $$ = SEQUENCE; }
| TABLE { $$ = TABLE; }
| DOMAIN_P { $$ = TYPE_P; }
| TYPE_P { $$ = TYPE_P; }
| VIEW { $$ = VIEW; }
;
...
...
@@ -3156,6 +3184,22 @@ createdb_opt_item: LOCATION opt_equal Sconst
{
$$ = lconsi(3, makeListi1(-1));
}
;
/*****************************************************************************
*
* DROP DATABASE
*
*
*****************************************************************************/
DropdbStmt: DROP DATABASE database_name
{
DropdbStmt *n = makeNode(DropdbStmt);
n->dbname = $3;
$$ = (Node *)n;
}
| OWNER opt_equal name
{
$$ = lconsi(4, makeList1($3));
...
...
@@ -3200,22 +3244,30 @@ AlterDatabaseSetStmt: ALTER DATABASE database_name VariableSetStmt
}
;
/*****************************************************************************
*
*
DROP DATABASE
*
Manipulate a domain
*
*
*****************************************************************************/
DropdbStmt: DROP DATABASE database_nam
e
CreateDomainStmt: CREATE DOMAIN_P name opt_as Typename ColQualList opt_collat
e
{
DropdbStmt *n = makeNode(DropdbStmt);
n->dbname = $3;
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; }
;
/*****************************************************************************
*
...
...
@@ -5857,6 +5909,7 @@ unreserved_keyword:
| DEFERRED { $$ = "deferred"; }
| DELETE { $$ = "delete"; }
| DELIMITERS { $$ = "delimiters"; }
| DOMAIN_P { $$ = "domain"; }
| DOUBLE { $$ = "double"; }
| DROP { $$ = "drop"; }
| EACH { $$ = "each"; }
...
...
src/backend/parser/keywords.c
View file @
d3788c33
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.10
3 2002/03/07 16:35:35
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.10
4 2002/03/19 02:18:19
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -97,6 +97,7 @@ static ScanKeyword ScanKeywords[] = {
{
"desc"
,
DESC
},
{
"distinct"
,
DISTINCT
},
{
"do"
,
DO
},
{
"domain"
,
DOMAIN_P
},
{
"double"
,
DOUBLE
},
{
"drop"
,
DROP
},
{
"each"
,
EACH
},
...
...
src/backend/parser/parse_coerce.c
View file @
d3788c33
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.6
6 2002/03/07 16:35:35
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.6
7 2002/03/19 02:18:20
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -605,3 +605,32 @@ PreferredType(CATEGORY category, Oid type)
}
return
result
;
}
/* PreferredType() */
/*
* If the targetTypeId is a domain, we really want to coerce
* the tuple to the domain type -- not the domain itself
*/
Oid
getBaseType
(
Oid
inType
)
{
HeapTuple
tup
;
Form_pg_type
typTup
;
tup
=
SearchSysCache
(
TYPEOID
,
ObjectIdGetDatum
(
inType
),
0
,
0
,
0
);
typTup
=
((
Form_pg_type
)
GETSTRUCT
(
tup
));
/*
* Assume that typbasetype exists and is a base type, where inType
* was a domain
*/
if
(
typTup
->
typtype
==
'd'
)
inType
=
typTup
->
typbasetype
;
ReleaseSysCache
(
tup
);
return
inType
;
}
src/backend/parser/parse_expr.c
View file @
d3788c33
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.10
8 2002/03/12 00:51:54 tgl
Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.10
9 2002/03/19 02:18:20 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -1027,7 +1027,8 @@ parser_typecast_expression(ParseState *pstate,
if
(
inputType
!=
targetType
)
{
expr
=
CoerceTargetExpr
(
pstate
,
expr
,
inputType
,
targetType
,
typename
->
typmod
);
getBaseType
(
targetType
),
typename
->
typmod
);
if
(
expr
==
NULL
)
elog
(
ERROR
,
"Cannot cast type '%s' to '%s'"
,
format_type_be
(
inputType
),
...
...
@@ -1039,7 +1040,7 @@ parser_typecast_expression(ParseState *pstate,
* as well as a type coercion.
*/
expr
=
coerce_type_typmod
(
pstate
,
expr
,
targetType
,
typename
->
typmod
);
getBaseType
(
targetType
)
,
typename
->
typmod
);
return
expr
;
}
...
...
src/backend/tcop/postgres.c
View file @
d3788c33
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.25
4 2002/03/06 06:10:09
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.25
5 2002/03/19 02:18:20
momjian Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
...
...
@@ -1722,7 +1722,7 @@ PostgresMain(int argc, char *argv[], const char *username)
if
(
!
IsUnderPostmaster
)
{
puts
(
"
\n
POSTGRES backend interactive interface "
);
puts
(
"$Revision: 1.25
4 $ $Date: 2002/03/06 06:10:09
$
\n
"
);
puts
(
"$Revision: 1.25
5 $ $Date: 2002/03/19 02:18:20
$
\n
"
);
}
/*
...
...
@@ -2212,8 +2212,9 @@ CreateCommandTag(Node *parsetree)
}
break
;
case
T_CreateDomainStmt
:
case
T_CreateStmt
:
tag
=
"CREATE"
;
tag
=
"CREATE
DOMAIN
"
;
break
;
case
T_DropStmt
:
...
...
src/backend/tcop/utility.c
View file @
d3788c33
...
...
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.13
2 2002/03/07 16:35:36
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.13
3 2002/03/19 02:18:20
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -282,6 +282,11 @@ ProcessUtility(Node *parsetree,
/* RemoveType does its own permissions checks */
RemoveType
(
relname
);
break
;
case
DROP_DOMAIN_P
:
/* RemoveDomain does its own permissions checks */
RemoveDomain
(
relname
,
stmt
->
behavior
);
break
;
}
/*
...
...
@@ -726,6 +731,19 @@ ProcessUtility(Node *parsetree,
DropProceduralLanguage
((
DropPLangStmt
*
)
parsetree
);
break
;
/*
* ******************************** DOMAIN statements ****
*
*/
case
T_CreateDomainStmt
:
DefineDomain
((
CreateDomainStmt
*
)
parsetree
);
break
;
/*
* ******************************** USER statements ****
*
*/
case
T_CreateUserStmt
:
CreateUser
((
CreateUserStmt
*
)
parsetree
);
break
;
...
...
src/backend/utils/adt/format_type.c
View file @
d3788c33
...
...
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/format_type.c,v 1.2
6 2002/03/07 16:35:36
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/format_type.c,v 1.2
7 2002/03/19 02:18:21
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -126,6 +126,7 @@ format_type_internal(Oid type_oid, int32 typemod,
bool
is_array
;
char
*
name
;
char
*
buf
;
char
typtype
;
if
(
type_oid
==
InvalidOid
&&
allow_invalid
)
return
pstrdup
(
"-"
);
...
...
@@ -144,6 +145,31 @@ format_type_internal(Oid type_oid, int32 typemod,
array_base_type
=
((
Form_pg_type
)
GETSTRUCT
(
tuple
))
->
typelem
;
typlen
=
((
Form_pg_type
)
GETSTRUCT
(
tuple
))
->
typlen
;
typtype
=
((
Form_pg_type
)
GETSTRUCT
(
tuple
))
->
typtype
;
/*
* Domains look alot like arrays, so lets process them first, and return
* back to avoid the array and 'standard' formatting procedures that are
* use for base types.
*/
if
(
typtype
==
'd'
)
{
name
=
NameStr
(((
Form_pg_type
)
GETSTRUCT
(
tuple
))
->
typname
);
/*
* Double-quote the name if it's not a standard identifier.
* Note this is *necessary* for ruleutils.c's use.
*/
if
(
strspn
(
name
,
"abcdefghijklmnopqrstuvwxyz0123456789_"
)
!=
strlen
(
name
)
||
isdigit
((
unsigned
char
)
name
[
0
]))
buf
=
psnprintf
(
strlen
(
name
)
+
3
,
"
\"
%s
\"
"
,
name
);
else
buf
=
pstrdup
(
name
);
ReleaseSysCache
(
tuple
);
return
buf
;
}
if
(
array_base_type
!=
InvalidOid
&&
typlen
<
0
)
{
/* Switch our attention to the array element type */
...
...
src/backend/utils/cache/lsyscache.c
View file @
d3788c33
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.6
2 2002/03/07 16:35:36
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.6
3 2002/03/19 02:18:21
momjian Exp $
*
* NOTES
* Eventually, the index information should go through here, too.
...
...
@@ -23,6 +23,7 @@
#include "catalog/pg_shadow.h"
#include "catalog/pg_statistic.h"
#include "catalog/pg_type.h"
#include "parser/parse_coerce.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
...
...
@@ -822,16 +823,17 @@ get_typstorage(Oid typid)
* Returns FALSE if there is no default (effectively, default is NULL).
* The result points to palloc'd storage for pass-by-reference types.
*/
bool
get_typdefault
(
Oid
typid
,
Datum
*
defaultValue
)
Node
*
get_typdefault
(
Oid
typid
,
int32
atttypmod
)
{
HeapTuple
typeTuple
;
Form_pg_type
type
;
Oid
typinput
,
typelem
;
Datum
textDefaultVal
;
Oid
typinput
;
Oid
typbasetype
;
char
typtype
;
Datum
datum
;
bool
isNull
;
char
*
strDefaultVal
;
Node
*
expr
;
typeTuple
=
SearchSysCache
(
TYPEOID
,
ObjectIdGetDatum
(
typid
),
...
...
@@ -843,38 +845,41 @@ get_typdefault(Oid typid, Datum *defaultValue)
type
=
(
Form_pg_type
)
GETSTRUCT
(
typeTuple
);
typinput
=
type
->
typinput
;
typelem
=
type
->
typelem
;
typbasetype
=
type
->
typbasetype
;
typtype
=
type
->
typtype
;
/*
* typdefault is potentially null, so don't try to access it as a
* typdefault
bin
is potentially null, so don't try to access it as a
* struct field. Must do it the hard way with SysCacheGetAttr.
*/
textDefaultVal
=
SysCacheGetAttr
(
TYPEOID
,
typeTuple
,
Anum_pg_type_typdefault
,
&
isNull
);
datum
=
SysCacheGetAttr
(
TYPEOID
,
typeTuple
,
Anum_pg_type_typdefaultbin
,
&
isNull
);
ReleaseSysCache
(
typeTuple
);
if
(
isNull
)
{
ReleaseSysCache
(
typeTuple
);
*
defaultValue
=
(
Datum
)
0
;
return
false
;
}
return
(
Node
*
)
NULL
;
/* Convert
text datum to C string
*/
strDefaultVal
=
DatumGetCString
(
DirectFunctionCall1
(
textout
,
textDefaultVal
));
/* Convert
Datum to a Node
*/
expr
=
stringToNode
(
DatumGetCString
(
DirectFunctionCall1
(
textout
,
datum
)
));
/* Convert C string to a value of the given type */
*
defaultValue
=
OidFunctionCall3
(
typinput
,
CStringGetDatum
(
strDefaultVal
),
ObjectIdGetDatum
(
typelem
),
Int32GetDatum
(
-
1
));
pfree
(
strDefaultVal
);
ReleaseSysCache
(
typeTuple
);
/*
* Ensure we goto the basetype before the domain type.
*
* Prevents scenarios like the below from failing:
* CREATE DOMAIN dom text DEFAULT random();
*
*/
if
(
typbasetype
!=
InvalidOid
)
{
expr
=
coerce_type
(
NULL
,
expr
,
typid
,
typbasetype
,
atttypmod
);
}
return
true
;
return
expr
;
}
/*
...
...
src/backend/utils/cache/relcache.c
View file @
d3788c33
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.15
6 2002/03/07 16:35:36
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.15
7 2002/03/19 02:18:22
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -512,8 +512,12 @@ RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
(
char
*
)
attp
,
ATTRIBUTE_TUPLE_SIZE
);
/* Update constraint/default info */
if
(
attp
->
attnotnull
)
/*
* Update constraint/default info
*/
if
(
attp
->
attnotnull
)
constr
->
has_not_null
=
true
;
if
(
attp
->
atthasdef
)
...
...
src/include/catalog/heap.h
View file @
d3788c33
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: heap.h,v 1.4
3 2002/03/07 16:35:38
momjian Exp $
* $Id: heap.h,v 1.4
4 2002/03/19 02:18:22
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -15,6 +15,8 @@
#define HEAP_H
#include "catalog/pg_attribute.h"
#include "nodes/parsenodes.h"
#include "parser/parse_node.h"
#include "utils/rel.h"
typedef
struct
RawColumnDefault
...
...
@@ -45,6 +47,12 @@ extern void AddRelationRawConstraints(Relation rel,
List
*
rawColDefaults
,
List
*
rawConstraints
);
extern
Node
*
cookDefault
(
ParseState
*
pstate
,
Node
*
raw_default
,
Oid
atttypid
,
int32
atttypmod
,
char
*
attname
);
extern
int
RemoveCheckConstraint
(
Relation
rel
,
const
char
*
constrName
,
bool
inh
);
extern
Form_pg_attribute
SystemAttributeDefinition
(
AttrNumber
attno
,
...
...
src/include/catalog/pg_attribute.h
View file @
d3788c33
...
...
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_attribute.h,v 1.8
3 2002/03/07 16:35:38
momjian Exp $
* $Id: pg_attribute.h,v 1.8
4 2002/03/19 02:18:22
momjian Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
...
...
@@ -240,7 +240,13 @@ typedef FormData_pg_attribute *Form_pg_attribute;
{ 1247, {"typsend"}, 24, 0, 4, 14, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1247, {"typalign"}, 18, 0, 1, 15, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1247, {"typstorage"}, 18, 0, 1, 16, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1247, {"typdefault"}, 25, 0, -1, 17, 0, -1, -1, false , 'x', false, 'i', false, false }
{ 1247, {"typnotnull"}, 16, 0, 1, 17, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1247, {"typmod"}, 23, 0, 4, 18, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1247, {"typbasetype"}, 26, 0, 4, 19, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1247, {"typndims"}, 23, 0, 4, 20, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1247, {"typdefaultbin"}, 25, 0, -1, 21, 0, -1, -1, false, 'x', false, 'i', false, false }, \
{ 1247, {"typdefault"}, 25, 0, -1, 22, 0, -1, -1, false, 'x', false, 'i', false, false }
DATA
(
insert
(
1247
typname
19
DEFAULT_ATTSTATTARGET
NAMEDATALEN
1
0
-
1
-
1
f
p
f
i
f
f
));
DATA
(
insert
(
1247
typowner
23
0
4
2
0
-
1
-
1
t
p
f
i
f
f
));
...
...
@@ -258,7 +264,12 @@ DATA(insert ( 1247 typreceive 24 0 4 13 0 -1 -1 t p f i f f));
DATA
(
insert
(
1247
typsend
24
0
4
14
0
-
1
-
1
t
p
f
i
f
f
));
DATA
(
insert
(
1247
typalign
18
0
1
15
0
-
1
-
1
t
p
f
c
f
f
));
DATA
(
insert
(
1247
typstorage
18
0
1
16
0
-
1
-
1
t
p
f
c
f
f
));
DATA
(
insert
(
1247
typdefault
25
0
-
1
17
0
-
1
-
1
f
x
f
i
f
f
));
DATA
(
insert
(
1247
typnotnull
16
0
1
17
0
-
1
-
1
t
p
f
c
f
f
));
DATA
(
insert
(
1247
typmod
23
0
4
18
0
-
1
-
1
t
p
f
i
f
f
));
DATA
(
insert
(
1247
typbasetype
26
0
4
19
0
-
1
-
1
t
p
f
i
f
f
));
DATA
(
insert
(
1247
typndims
23
0
4
20
0
-
1
-
1
t
p
f
i
f
f
));
DATA
(
insert
(
1247
typdefaultbin
25
0
-
1
21
0
-
1
-
1
f
x
f
i
f
f
));
DATA
(
insert
(
1247
typdefault
25
0
-
1
22
0
-
1
-
1
f
x
f
i
f
f
));
DATA
(
insert
(
1247
ctid
27
0
6
-
1
0
-
1
-
1
f
p
f
i
f
f
));
DATA
(
insert
(
1247
oid
26
0
4
-
2
0
-
1
-
1
t
p
f
i
f
f
));
DATA
(
insert
(
1247
xmin
28
0
4
-
3
0
-
1
-
1
t
p
f
i
f
f
));
...
...
src/include/catalog/pg_class.h
View file @
d3788c33
...
...
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_class.h,v 1.6
1 2002/03/07 16:35:38
momjian Exp $
* $Id: pg_class.h,v 1.6
2 2002/03/19 02:18:22
momjian Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
...
...
@@ -132,7 +132,7 @@ typedef FormData_pg_class *Form_pg_class;
* ----------------
*/
DATA
(
insert
OID
=
1247
(
pg_type
71
PGUID
0
1247
0
0
0
0
f
f
r
17
0
0
0
0
0
t
f
f
f
_null_
));
DATA
(
insert
OID
=
1247
(
pg_type
71
PGUID
0
1247
0
0
0
0
f
f
r
22
0
0
0
0
0
t
f
f
f
_null_
));
DESCR
(
""
);
DATA
(
insert
OID
=
1249
(
pg_attribute
75
PGUID
0
1249
0
0
0
0
f
f
r
15
0
0
0
0
0
f
f
f
f
_null_
));
DESCR
(
""
);
...
...
src/include/catalog/pg_type.h
View file @
d3788c33
This diff is collapsed.
Click to expand it.
src/include/commands/defrem.h
View file @
d3788c33
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: defrem.h,v 1.3
0 2002/03/07 16:35:38
momjian Exp $
* $Id: defrem.h,v 1.3
1 2002/03/19 02:18:23
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -39,10 +39,12 @@ extern void CreateFunction(ProcedureStmt *stmt);
extern
void
DefineOperator
(
char
*
name
,
List
*
parameters
);
extern
void
DefineAggregate
(
char
*
name
,
List
*
parameters
);
extern
void
DefineType
(
char
*
name
,
List
*
parameters
);
extern
void
DefineDomain
(
CreateDomainStmt
*
stmt
);
/*
* prototypes in remove.c
*/
extern
void
RemoveDomain
(
char
*
domainName
,
int
behavior
);
extern
void
RemoveFunction
(
char
*
functionName
,
List
*
argTypes
);
extern
void
RemoveOperator
(
char
*
operatorName
,
char
*
typeName1
,
char
*
typeName2
);
...
...
src/include/nodes/nodes.h
View file @
d3788c33
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: nodes.h,v 1.10
0 2002/03/07 16:35:40
momjian Exp $
* $Id: nodes.h,v 1.10
1 2002/03/19 02:18:23
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -172,6 +172,7 @@ typedef enum NodeTag
T_TransactionStmt
,
T_ViewStmt
,
T_LoadStmt
,
T_CreateDomainStmt
,
T_CreatedbStmt
,
T_DropdbStmt
,
T_VacuumStmt
,
...
...
src/include/nodes/parsenodes.h
View file @
d3788c33
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: parsenodes.h,v 1.16
0 2002/03/12 00:52:01 tgl
Exp $
* $Id: parsenodes.h,v 1.16
1 2002/03/19 02:18:24 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -407,6 +407,23 @@ typedef struct DefElem
}
DefElem
;
/****************************************************************************
* Nodes for a Domain Creation tree
****************************************************************************/
/* ----------------------
* CreateDomain Statement
* ----------------------
* Down here as it required TypeName to be defined first.
*/
typedef
struct
CreateDomainStmt
{
NodeTag
type
;
char
*
domainname
;
/* name of domain to create */
TypeName
*
typename
;
/* the typecast */
List
*
constraints
;
/* constraints (list of Constraint nodes) */
}
CreateDomainStmt
;
/****************************************************************************
* Nodes for a Query tree
****************************************************************************/
...
...
@@ -1055,12 +1072,14 @@ typedef struct DefineStmt
#define DROP_INDEX 4
#define DROP_RULE 5
#define DROP_TYPE_P 6
#define DROP_DOMAIN_P 7
typedef
struct
DropStmt
{
NodeTag
type
;
List
*
names
;
int
removeType
;
int
behavior
;
/* CASCADE or RESTRICT drop behavior */
}
DropStmt
;
/* ----------------------
...
...
@@ -1269,6 +1288,7 @@ typedef struct LoadStmt
char
*
filename
;
/* file to load */
}
LoadStmt
;
/* ----------------------
* Createdb Statement
* ----------------------
...
...
src/include/parser/parse_coerce.h
View file @
d3788c33
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: parse_coerce.h,v 1.
39 2002/03/07 16:35:40
momjian Exp $
* $Id: parse_coerce.h,v 1.
40 2002/03/19 02:18:24
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -81,5 +81,6 @@ extern Oid select_common_type(List *typeids, const char *context);
extern
Node
*
coerce_to_common_type
(
ParseState
*
pstate
,
Node
*
node
,
Oid
targetTypeId
,
const
char
*
context
);
extern
Oid
getBaseType
(
Oid
inType
);
#endif
/* PARSE_COERCE_H */
src/include/utils/lsyscache.h
View file @
d3788c33
...
...
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: lsyscache.h,v 1.4
2 2002/03/07 16:35:41
momjian Exp $
* $Id: lsyscache.h,v 1.4
3 2002/03/19 02:18:24
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -44,7 +44,7 @@ extern int16 get_typlen(Oid typid);
extern
bool
get_typbyval
(
Oid
typid
);
extern
void
get_typlenbyval
(
Oid
typid
,
int16
*
typlen
,
bool
*
typbyval
);
extern
char
get_typstorage
(
Oid
typid
);
extern
bool
get_typdefault
(
Oid
typid
,
Datum
*
defaultValue
);
extern
Node
*
get_typdefault
(
Oid
typid
,
int32
atttypmod
);
extern
int32
get_typavgwidth
(
Oid
typid
,
int32
typmod
);
extern
int32
get_attavgwidth
(
Oid
relid
,
AttrNumber
attnum
);
extern
bool
get_attstatsslot
(
HeapTuple
statstuple
,
...
...
src/test/regress/expected/domain.out
0 → 100644
View file @
d3788c33
-- Test Comment / Drop
create domain domaindroptest int4;
comment on domain domaindroptest is 'About to drop this..';
create domain basetypetest domaindroptest;
ERROR: DefineDomain: domaindroptest is not a basetype
drop domain domaindroptest;
ERROR: parser: parse error at or near ";"
drop domain domaindroptest restrict;
-- 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
ERROR: value too long for type character varying(5)
INSERT INTO basictest values ('88', 'haha', 'short', '123.1212'); -- Truncate numeric
select * from basictest;
testint4 | testtext | testvarchar | testnumeric
----------+----------+-------------+-------------
88 | haha | short | 123.12
88 | haha | short | 123.12
(2 rows)
drop table basictest;
drop domain domainvarchar restrict;
drop domain domainnumeric restrict;
drop domain domainint4 restrict;
drop domain domaintext restrict;
-- Array Test
create domain domainint4arr int4[1];
create domain domaintextarr text[2][3];
create table domarrtest
( testint4arr domainint4arr
, testtextarr domaintextarr
);
INSERT INTO domarrtest values ('{2,2}', '{{"a","b"}{"c","d"}}');
INSERT INTO domarrtest values ('{{2,2}{2,2}}', '{{"a","b"}}');
INSERT INTO domarrtest values ('{2,2}', '{{"a","b"}{"c","d"}{"e"}}');
INSERT INTO domarrtest values ('{2,2}', '{{"a"}{"c"}}');
INSERT INTO domarrtest values (NULL, '{{"a","b"}{"c","d","e"}}');
drop table domarrtest;
drop domain domainint4arr restrict;
drop domain domaintextarr restrict;
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;
ERROR: ExecAppend: Fail to add null value in not null attribute col1
INSERT INTO nulltest values ('a', 'b', 'c', 'd'); -- Good
INSERT INTO nulltest values (NULL, 'b', 'c', 'd');
ERROR: ExecAppend: Fail to add null value in not null attribute col1
INSERT INTO nulltest values ('a', NULL, 'c', 'd');
ERROR: ExecAppend: Fail to add null value in not null attribute col2
INSERT INTO nulltest values ('a', 'b', NULL, 'd');
ERROR: ExecAppend: Fail to add null value in not null attribute col3
INSERT INTO nulltest values ('a', 'b', 'c', NULL); -- Good
select * from nulltest;
col1 | col2 | col3 | col4
------+------+------+------
a | b | c | d
a | b | c |
(2 rows)
drop table nulltest;
drop domain dnotnull restrict;
drop domain dnull restrict;
create domain ddef1 int4 DEFAULT 3;
create domain ddef2 oid DEFAULT '12';
-- 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 domain ddef5 numeric(8,2) NOT NULL DEFAULT '12.12';
create table defaulttest
( col1 ddef1
, col2 ddef2
, col3 ddef3
, col4 ddef4
, col5 ddef1 NOT NULL DEFAULT NULL
, col6 ddef2 DEFAULT '88'
, col7 ddef4 DEFAULT 8000
, col8 ddef5
);
insert into defaulttest default values;
insert into defaulttest default values;
insert into defaulttest default values;
select * from defaulttest;
col1 | col2 | col3 | col4 | col5 | col6 | col7 | col8
------+------+------+------+------+------+------+-------
3 | 12 | 5 | 1 | 3 | 88 | 8000 | 12.12
3 | 12 | 5 | 2 | 3 | 88 | 8000 | 12.12
3 | 12 | 5 | 3 | 3 | 88 | 8000 | 12.12
(3 rows)
drop sequence ddef4_seq;
drop table defaulttest;
drop domain ddef1 restrict;
drop domain ddef2 restrict;
drop domain ddef3 restrict;
drop domain ddef4 restrict;
drop domain ddef5 restrict;
src/test/regress/parallel_schedule
View file @
d3788c33
...
...
@@ -73,4 +73,4 @@ test: select_views alter_table portals_p2 rules foreign_key
# The sixth group of parallel test
# ----------
# "plpgsql" cannot run concurrently with "rules"
test: limit plpgsql temp
test: limit plpgsql temp
domain
src/test/regress/serial_schedule
View file @
d3788c33
# $Header: /cvsroot/pgsql/src/test/regress/serial_schedule,v 1.
7 2001/09/28 07:59:38 thomas
Exp $
# $Header: /cvsroot/pgsql/src/test/regress/serial_schedule,v 1.
8 2002/03/19 02:18:24 momjian
Exp $
# This should probably be in an order similar to parallel_schedule.
test: boolean
test: char
...
...
@@ -80,3 +80,5 @@ test: foreign_key
test: limit
test: plpgsql
test: temp
test: domain
src/test/regress/sql/domain.sql
0 → 100644
View file @
d3788c33
-- Test Comment / Drop
create
domain
domaindroptest
int4
;
comment
on
domain
domaindroptest
is
'About to drop this..'
;
create
domain
basetypetest
domaindroptest
;
drop
domain
domaindroptest
;
drop
domain
domaindroptest
restrict
;
-- 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
;
drop
table
basictest
;
drop
domain
domainvarchar
restrict
;
drop
domain
domainnumeric
restrict
;
drop
domain
domainint4
restrict
;
drop
domain
domaintext
restrict
;
-- Array Test
create
domain
domainint4arr
int4
[
1
];
create
domain
domaintextarr
text
[
2
][
3
];
create
table
domarrtest
(
testint4arr
domainint4arr
,
testtextarr
domaintextarr
);
INSERT
INTO
domarrtest
values
(
'{2,2}'
,
'{{"a","b"}{"c","d"}}'
);
INSERT
INTO
domarrtest
values
(
'{{2,2}{2,2}}'
,
'{{"a","b"}}'
);
INSERT
INTO
domarrtest
values
(
'{2,2}'
,
'{{"a","b"}{"c","d"}{"e"}}'
);
INSERT
INTO
domarrtest
values
(
'{2,2}'
,
'{{"a"}{"c"}}'
);
INSERT
INTO
domarrtest
values
(
NULL
,
'{{"a","b"}{"c","d","e"}}'
);
drop
table
domarrtest
;
drop
domain
domainint4arr
restrict
;
drop
domain
domaintextarr
restrict
;
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
;
drop
table
nulltest
;
drop
domain
dnotnull
restrict
;
drop
domain
dnull
restrict
;
create
domain
ddef1
int4
DEFAULT
3
;
create
domain
ddef2
oid
DEFAULT
'12'
;
-- 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
domain
ddef5
numeric
(
8
,
2
)
NOT
NULL
DEFAULT
'12.12'
;
create
table
defaulttest
(
col1
ddef1
,
col2
ddef2
,
col3
ddef3
,
col4
ddef4
,
col5
ddef1
NOT
NULL
DEFAULT
NULL
,
col6
ddef2
DEFAULT
'88'
,
col7
ddef4
DEFAULT
8000
,
col8
ddef5
);
insert
into
defaulttest
default
values
;
insert
into
defaulttest
default
values
;
insert
into
defaulttest
default
values
;
select
*
from
defaulttest
;
drop
sequence
ddef4_seq
;
drop
table
defaulttest
;
drop
domain
ddef1
restrict
;
drop
domain
ddef2
restrict
;
drop
domain
ddef3
restrict
;
drop
domain
ddef4
restrict
;
drop
domain
ddef5
restrict
;
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment