Re-addd Rod's ALTER DOMAIN patch.

This commit is contained in:
Bruce Momjian 2002-12-06 05:00:34 +00:00
parent 78705d0a19
commit 05a6b37912
23 changed files with 1556 additions and 264 deletions

3
configure vendored
View File

@ -15778,7 +15778,7 @@ fi
ac_config_files="$ac_config_files GNUmakefile src/Makefile.global"
ac_config_links="$ac_config_links src/backend/port/dynloader.c:src/backend/port/dynloader/${template}.c src/backend/port/pg_sema.c:${SEMA_IMPLEMENTATION} src/backend/port/pg_shmem.c:${SHMEM_IMPLEMENTATION} src/include/dynloader.h:src/backend/port/dynloader/${template}.h src/include/pg_config_os.h:src/include/port/${template}.h src/Makefile.port:src/makefiles/Makefile.${template} src/interfaces/libpq/v6util.c:src/backend/libpq/v6util.c"
ac_config_links="$ac_config_links src/backend/port/dynloader.c:src/backend/port/dynloader/${template}.c src/backend/port/pg_sema.c:${SEMA_IMPLEMENTATION} src/backend/port/pg_shmem.c:${SHMEM_IMPLEMENTATION} src/include/dynloader.h:src/backend/port/dynloader/${template}.h src/include/pg_config_os.h:src/include/port/${template}.h src/Makefile.port:src/makefiles/Makefile.${template}"
ac_config_headers="$ac_config_headers src/include/pg_config.h"
@ -16266,7 +16266,6 @@ do
"src/include/dynloader.h" ) CONFIG_LINKS="$CONFIG_LINKS src/include/dynloader.h:src/backend/port/dynloader/${template}.h" ;;
"src/include/pg_config_os.h" ) CONFIG_LINKS="$CONFIG_LINKS src/include/pg_config_os.h:src/include/port/${template}.h" ;;
"src/Makefile.port" ) CONFIG_LINKS="$CONFIG_LINKS src/Makefile.port:src/makefiles/Makefile.${template}" ;;
"src/interfaces/libpq/v6util.c" ) CONFIG_LINKS="$CONFIG_LINKS src/interfaces/libpq/v6util.c:src/backend/libpq/v6util.c" ;;
"src/include/pg_config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS src/include/pg_config.h" ;;
*) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
echo "$as_me: error: invalid argument: $ac_config_target" >&2;}

View File

@ -0,0 +1,237 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/alter_domain.sgml,v 1.4 2002/12/06 05:00:10 momjian Exp $
PostgreSQL documentation
-->
<refentry id="SQL-ALTERDOMAIN">
<refmeta>
<refentrytitle id="sql-alterdomain-title">ALTER DOMAIN</refentrytitle>
<refmiscinfo>SQL - Language Statements</refmiscinfo>
</refmeta>
<refnamediv>
<refname>
ALTER DOMAIN
</refname>
<refpurpose>
change the definition of a table
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<refsynopsisdivinfo>
<date>2002-11-27</date>
</refsynopsisdivinfo>
<synopsis>
ALTER DOMAIN <replaceable class="PARAMETER">domain</replaceable>
{ SET DEFAULT <replaceable class="PARAMETER">value</replaceable> | DROP DEFAULT }
ALTER DOMAIN <replaceable class="PARAMETER">domain</replaceable>
{ SET | DROP } NOT NULL
ALTER DOMAIN <replaceable class="PARAMETER">domain</replaceable>
ADD <replaceable class="PARAMETER">domain_constraint</replaceable>
ALTER DOMAIN <replaceable class="PARAMETER">domain</replaceable>
DROP CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> [ RESTRICT | CASCADE ]
</synopsis>
<refsect2 id="R2-SQL-ALTERDOMAIN-1">
<refsect2info>
<date>2002-11-27</date>
</refsect2info>
<title>
Inputs
</title>
<para>
<variablelist>
<varlistentry>
<term><replaceable class="PARAMETER"> domain </replaceable></term>
<listitem>
<para>
The name (possibly schema-qualified) of an existing domain to
alter.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="PARAMETER"> domain_constraint </replaceable></term>
<listitem>
<para>
New domain constraint for the domain.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="PARAMETER"> constraint_name </replaceable></term>
<listitem>
<para>
Name of an existing constraint to drop.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>CASCADE</term>
<listitem>
<para>
Automatically drop objects that depend constraint.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>RESTRICT</term>
<listitem>
<para>
Refuse to drop the constraint if there are any dependent
objects. This is the default behavior.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect2>
<refsect2 id="R2-SQL-ALTERDOMAIN-2">
<refsect2info>
<date>1998-04-15</date>
</refsect2info>
<title>
Outputs
</title>
<para>
<variablelist>
<varlistentry>
<term><computeroutput>ALTER DOMAIN</computeroutput></term>
<listitem>
<para>
Message returned from domain alteration.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><computeroutput>ERROR</computeroutput></term>
<listitem>
<para>
Message returned if domain is not available.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect2>
</refsynopsisdiv>
<refsect1 id="R1-SQL-ALTERDOMAIN-1">
<refsect1info>
<date>2002-11-27</date>
</refsect1info>
<title>
Description
</title>
<para>
<command>ALTER DOMAIN</command> changes the definition of an existing domain.
There are several sub-forms:
</para>
<variablelist>
<varlistentry>
<term>SET/DROP DEFAULT</term>
<listitem>
<para>
These forms set or remove the default value for a column. Note
that defaults only apply to subsequent <command>INSERT</command>
commands; they do not cause rows already in a table using the domain.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>SET/DROP NOT NULL</term>
<listitem>
<para>
These forms change whether a domain is marked to allow NULL
values or to reject NULL values. You may only <literal>SET NOT NULL</>
when the tables using the domain contain no null values in the domain
based column.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>ADD <replaceable class="PARAMETER">domain_constraint</replaceable></term>
<listitem>
<para>
This form adds a new constraint to a table using the same syntax as
<xref linkend="SQL-CREATEDOMAIN" endterm="SQL-CREATEDOMAIN-TITLE">.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>DROP CONSTRAINT</term>
<listitem>
<para>
This form drops constraints on a domain.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
You must own the domain to use <command>ALTER DOMAIN</>; except for
<command>ALTER TABLE OWNER</>, which may only be executed by a superuser.
</para>
</refsect1>
<refsect1 id="R1-SQL-ALTERDOMAIN-2">
<title>
Usage
</title>
<para>
To add a NOT NULL constraint to a column:
<programlisting>
ALTER DOMAIN zipcode SET NOT NULL;
</programlisting>
To remove a NOT NULL constraint from a column:
<programlisting>
ALTER DOMAIN zipcode DROP NOT NULL;
</programlisting>
</para>
<para>
To add a check constraint to a table:
<programlisting>
ALTER DOMAIN zipcode ADD CONSTRAINT zipchk CHECK (char_length(VALUE) = 5);
</programlisting>
</para>
<para>
To remove a check constraint from a table and all its children:
<programlisting>
ALTER DOMAIN zipcode DROP CONSTRAINT zipchk;
</programlisting>
</para>
</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:
-->

View File

@ -1,5 +1,5 @@
<!-- reference.sgml
$Header: /cvsroot/pgsql/doc/src/sgml/reference.sgml,v 1.40 2002/12/06 03:42:48 momjian Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/reference.sgml,v 1.41 2002/12/06 05:00:10 momjian Exp $
PostgreSQL Reference Manual
-->
@ -47,6 +47,7 @@ PostgreSQL Reference Manual
&abort;
&alterDatabase;
&alterDomain;
&alterGroup;
&alterTable;
&alterTrigger;

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.16 2002/12/06 03:42:54 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.17 2002/12/06 05:00:10 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -36,6 +36,7 @@
#include "commands/proclang.h"
#include "commands/schemacmds.h"
#include "commands/trigger.h"
#include "commands/typecmds.h"
#include "lib/stringinfo.h"
#include "miscadmin.h"
#include "optimizer/clauses.h"

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_constraint.c,v 1.10 2002/12/06 03:42:57 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_constraint.c,v 1.11 2002/12/06 05:00:10 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -199,6 +199,7 @@ CreateConstraintEntry(const char *constraintName,
domobject.classId = RelOid_pg_type;
domobject.objectId = domainId;
domobject.objectSubId = 0;
recordDependencyOn(&conobject, &domobject, DEPENDENCY_AUTO);
}
@ -496,15 +497,16 @@ RemoveConstraintById(Oid conId)
HeapTuple typTup;
ScanKeyData typKey[1];
SysScanDesc typScan;
int nkeys = 0;
typRel = heap_openr(TypeRelationName, RowExclusiveLock);
ScanKeyEntryInitialize(&typKey[0], 0x0,
Anum_pg_constraint_contypid, F_OIDEQ,
ScanKeyEntryInitialize(&typKey[nkeys++], 0x0,
ObjectIdAttributeNumber, F_OIDEQ,
ObjectIdGetDatum(con->contypid));
typScan = systable_beginscan(typRel, TypeOidIndex, true,
SnapshotNow, 1, typKey);
SnapshotNow, nkeys, typKey);
typTup = systable_getnext(typScan);
@ -517,6 +519,11 @@ RemoveConstraintById(Oid conId)
/* Keep lock on domain type until end of xact */
heap_close(typRel, NoLock);
}
else
{
elog(ERROR, "RemoveConstraintById: Constraint %u is not a known type",
conId);
}
/* Fry the constraint itself */
simple_heap_delete(conDesc, &tup->t_self);

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.84 2002/12/06 03:42:57 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.85 2002/12/06 05:00:10 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -139,7 +139,7 @@ TypeCreate(const char *typeName,
Oid elementType,
Oid baseType,
const char *defaultTypeValue, /* human readable rep */
const char *defaultTypeBin, /* cooked rep */
char *defaultTypeBin, /* cooked rep */
bool passedByValue,
char alignment,
char storage,
@ -291,79 +291,16 @@ TypeCreate(const char *typeName,
*/
if (!IsBootstrapProcessingMode())
{
ObjectAddress myself,
referenced;
myself.classId = RelOid_pg_type;
myself.objectId = typeObjectId;
myself.objectSubId = 0;
/* dependency on namespace */
/* skip for relation rowtype, since we have indirect dependency */
if (!OidIsValid(relationOid))
{
referenced.classId = get_system_catalog_relid(NamespaceRelationName);
referenced.objectId = typeNamespace;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
/* Normal dependencies on the I/O functions */
referenced.classId = RelOid_pg_proc;
referenced.objectId = inputProcedure;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
referenced.classId = RelOid_pg_proc;
referenced.objectId = outputProcedure;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
/*
* If the type is a rowtype for a relation, mark it as internally
* dependent on the relation, *unless* it is a stand-alone
* composite type relation. For the latter case, we have to
* reverse the dependency.
*
* In the former case, this allows the type to be auto-dropped when
* the relation is, and not otherwise. And in the latter, of
* course we get the opposite effect.
*/
if (OidIsValid(relationOid))
{
referenced.classId = RelOid_pg_class;
referenced.objectId = relationOid;
referenced.objectSubId = 0;
if (relationKind != RELKIND_COMPOSITE_TYPE)
recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL);
else
recordDependencyOn(&referenced, &myself, DEPENDENCY_INTERNAL);
}
/*
* If the type is an array type, mark it auto-dependent on the
* base type. (This is a compromise between the typical case
* where the array type is automatically generated and the case
* where it is manually created: we'd prefer INTERNAL for the
* former case and NORMAL for the latter.)
*/
if (OidIsValid(elementType))
{
referenced.classId = RelOid_pg_type;
referenced.objectId = elementType;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
}
/* Normal dependency from a domain to its base type. */
if (OidIsValid(baseType))
{
referenced.classId = RelOid_pg_type;
referenced.objectId = baseType;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
GenerateTypeDependencies(typeNamespace,
typeObjectId,
relationOid,
relationKind,
inputProcedure,
outputProcedure,
elementType,
baseType,
defaultTypeBin,
false);
}
/*
@ -374,6 +311,107 @@ TypeCreate(const char *typeName,
return typeObjectId;
}
void
GenerateTypeDependencies(Oid typeNamespace,
Oid typeObjectId,
Oid relationOid, /* only for 'c'atalog typeType */
char relationKind,
Oid inputProcedure,
Oid outputProcedure,
Oid elementType,
Oid baseType,
char *defaultTypeBin, /* cooked rep */
bool rebuild)
{
ObjectAddress myself,
referenced;
/*
* If true, we need to remove all current dependencies that the type
* holds, and rebuild them from scratch. This allows us to easily
* implement alter type, and alter domain statements.
*/
if (rebuild)
deleteDependencyRecordsFor(RelOid_pg_type,
typeObjectId);
myself.classId = RelOid_pg_type;
myself.objectId = typeObjectId;
myself.objectSubId = 0;
/* dependency on namespace */
/* skip for relation rowtype, since we have indirect dependency */
if (!OidIsValid(relationOid))
{
referenced.classId = get_system_catalog_relid(NamespaceRelationName);
referenced.objectId = typeNamespace;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
/* Normal dependencies on the I/O functions */
referenced.classId = RelOid_pg_proc;
referenced.objectId = inputProcedure;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
referenced.classId = RelOid_pg_proc;
referenced.objectId = outputProcedure;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
/*
* If the type is a rowtype for a relation, mark it as internally
* dependent on the relation, *unless* it is a stand-alone
* composite type relation. For the latter case, we have to
* reverse the dependency.
*
* In the former case, this allows the type to be auto-dropped when
* the relation is, and not otherwise. And in the latter, of
* course we get the opposite effect.
*/
if (OidIsValid(relationOid))
{
referenced.classId = RelOid_pg_class;
referenced.objectId = relationOid;
referenced.objectSubId = 0;
if (relationKind != RELKIND_COMPOSITE_TYPE)
recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL);
else
recordDependencyOn(&referenced, &myself, DEPENDENCY_INTERNAL);
}
/*
* If the type is an array type, mark it auto-dependent on the
* base type. (This is a compromise between the typical case
* where the array type is automatically generated and the case
* where it is manually created: we'd prefer INTERNAL for the
* former case and NORMAL for the latter.)
*/
if (OidIsValid(elementType))
{
referenced.classId = RelOid_pg_type;
referenced.objectId = elementType;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
}
/* Normal dependency from a domain to its base type. */
if (OidIsValid(baseType))
{
referenced.classId = RelOid_pg_type;
referenced.objectId = baseType;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
/* Dependency on the default expression */
if (defaultTypeBin)
recordDependencyOnExpr(&myself, stringToNode(defaultTypeBin),
NIL, DEPENDENCY_NORMAL);
}
/*
* TypeRename
* This renames a type

View File

@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.101 2002/12/06 03:42:57 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.102 2002/12/06 05:00:10 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -667,7 +667,7 @@ cluster(ClusterStmt *stmt)
tableOid = RangeVarGetRelid(stmt->relation, false);
if (!check_cluster_ownership(tableOid))
elog(ERROR, "CLUSTER: You do not own relation %s",
stmt->relation->relname);
stmt->relation->relname);
tuple = SearchSysCache(RELOID,
ObjectIdGetDatum(tableOid),
@ -706,7 +706,7 @@ cluster(ClusterStmt *stmt)
}
if (indexOid == InvalidOid)
elog(ERROR, "CLUSTER: No previously clustered index found on table %s",
stmt->relation->relname);
stmt->relation->relname);
RelationClose(rel);
ReleaseSysCache(ituple);
ReleaseSysCache(idxtuple);
@ -721,7 +721,7 @@ cluster(ClusterStmt *stmt)
/* XXX Maybe the namespace should be reported as well */
if (!OidIsValid(indexOid))
elog(ERROR, "CLUSTER: cannot find index \"%s\" for table \"%s\"",
stmt->indexname, stmt->relation->relname);
stmt->indexname, stmt->relation->relname);
rvtc.tableOid = tableOid;
rvtc.indexOid = indexOid;
rvtc.isPrevious = false;
@ -819,7 +819,7 @@ get_tables_to_cluster(AclId owner)
List *rvs = NIL;
/*
* Get all indexes that have indisclustered set. System
* Get all indexes that have indisclustered set. System
* relations or nailed-in relations cannot ever have
* indisclustered set, because CLUSTER will refuse to
* set it when called with one of them as argument.

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.115 2002/12/06 03:42:57 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.116 2002/12/06 05:00:16 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -1610,8 +1610,8 @@ ExecEvalConstraintTest(ConstraintTest *constraint, ExprContext *econtext,
conResult = ExecEvalExpr(constraint->check_expr, econtext, isNull, isDone);
if (!DatumGetBool(conResult))
elog(ERROR, "Domain %s constraint %s failed",
constraint->name, constraint->domname);
elog(ERROR, "ExecEvalConstraintTest: Domain %s constraint %s failed",
constraint->domname, constraint->name);
}
break;
default:

View File

@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.228 2002/12/06 03:42:59 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.229 2002/12/06 05:00:18 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -1479,6 +1479,20 @@ _copyAlterTableStmt(AlterTableStmt *from)
return newnode;
}
static AlterDomainStmt *
_copyAlterDomainStmt(AlterDomainStmt *from)
{
AlterDomainStmt *newnode = makeNode(AlterDomainStmt);
COPY_SCALAR_FIELD(subtype);
COPY_NODE_FIELD(typename);
COPY_STRING_FIELD(name);
COPY_NODE_FIELD(def);
COPY_SCALAR_FIELD(behavior);
return newnode;
}
static GrantStmt *
_copyGrantStmt(GrantStmt *from)
{
@ -2464,6 +2478,9 @@ copyObject(void *from)
case T_AlterTableStmt:
retval = _copyAlterTableStmt(from);
break;
case T_AlterDomainStmt:
retval = _copyAlterDomainStmt(from);
break;
case T_GrantStmt:
retval = _copyGrantStmt(from);
break;

View File

@ -18,7 +18,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.173 2002/12/06 03:43:08 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.174 2002/12/06 05:00:18 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -525,6 +525,18 @@ _equalAlterTableStmt(AlterTableStmt *a, AlterTableStmt *b)
return true;
}
static bool
_equalAlterDomainStmt(AlterDomainStmt *a, AlterDomainStmt *b)
{
COMPARE_SCALAR_FIELD(subtype);
COMPARE_NODE_FIELD(typename);
COMPARE_STRING_FIELD(name);
COMPARE_NODE_FIELD(def);
COMPARE_SCALAR_FIELD(behavior);
return true;
}
static bool
_equalGrantStmt(GrantStmt *a, GrantStmt *b)
{
@ -1621,6 +1633,9 @@ equal(void *a, void *b)
case T_AlterTableStmt:
retval = _equalAlterTableStmt(a, b);
break;
case T_AlterDomainStmt:
retval = _equalAlterDomainStmt(a, b);
break;
case T_GrantStmt:
retval = _equalGrantStmt(a, b);
break;

View File

@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.385 2002/12/06 03:43:08 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.386 2002/12/06 05:00:22 momjian Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@ -128,7 +128,7 @@ static void doNegateFloat(Value *v);
}
%type <node> stmt schema_stmt
AlterDatabaseSetStmt AlterGroupStmt
AlterDatabaseSetStmt AlterDomainStmt AlterGroupStmt
AlterTableStmt AlterUserStmt AlterUserSetStmt
AnalyzeStmt ClosePortalStmt ClusterStmt CommentStmt
ConstraintsSetStmt CopyStmt CreateAsStmt CreateCastStmt
@ -479,6 +479,7 @@ stmtmulti: stmtmulti ';' stmt
stmt :
AlterDatabaseSetStmt
| AlterDomainStmt
| AlterGroupStmt
| AlterTableStmt
| AlterUserStmt
@ -3729,6 +3730,53 @@ CreateDomainStmt:
}
;
AlterDomainStmt:
/* ALTER DOMAIN <domain> {SET DEFAULT <expr>|DROP DEFAULT} */
ALTER DOMAIN_P any_name alter_column_default
{
AlterDomainStmt *n = makeNode(AlterDomainStmt);
n->subtype = 'T';
n->typename = $3;
n->def = $4;
$$ = (Node *)n;
}
/* ALTER DOMAIN <domain> DROP NOT NULL */
| ALTER DOMAIN_P any_name DROP NOT NULL_P
{
AlterDomainStmt *n = makeNode(AlterDomainStmt);
n->subtype = 'N';
n->typename = $3;
$$ = (Node *)n;
}
/* ALTER DOMAIN <domain> SET NOT NULL */
| ALTER DOMAIN_P any_name SET NOT NULL_P
{
AlterDomainStmt *n = makeNode(AlterDomainStmt);
n->subtype = 'O';
n->typename = $3;
$$ = (Node *)n;
}
/* ALTER DOMAIN <domain> ADD CONSTRAINT ... */
| ALTER DOMAIN_P any_name ADD TableConstraint
{
AlterDomainStmt *n = makeNode(AlterDomainStmt);
n->subtype = 'C';
n->typename = $3;
n->def = $5;
$$ = (Node *)n;
}
/* ALTER DOMAIN <domain> DROP CONSTRAINT <name> [RESTRICT|CASCADE] */
| ALTER DOMAIN_P any_name DROP CONSTRAINT name opt_drop_behavior
{
AlterDomainStmt *n = makeNode(AlterDomainStmt);
n->subtype = 'X';
n->typename = $3;
n->name = $6;
n->behavior = $7;
$$ = (Node *)n;
}
;
opt_as: AS {}
| /* EMPTY */ {}
;

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.134 2002/12/06 03:43:12 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.135 2002/12/06 05:00:26 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -629,6 +629,14 @@ transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal)
case T_DomainConstraintValue:
{
/*
* If domVal is NULL, we are not translating an expression that
* can use it
*/
if (domVal == NULL)
elog(ERROR, "VALUE is not allowed in expression for node %d",
nodeTag(expr));
result = (Node *) copyObject(domVal);
break;

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.312 2002/12/06 03:43:13 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.313 2002/12/06 05:00:26 momjian Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
@ -1781,7 +1781,7 @@ PostgresMain(int argc, char *argv[], const char *username)
if (!IsUnderPostmaster)
{
puts("\nPOSTGRES backend interactive interface ");
puts("$Revision: 1.312 $ $Date: 2002/12/06 03:43:13 $\n");
puts("$Revision: 1.313 $ $Date: 2002/12/06 05:00:26 $\n");
}
/*
@ -2319,6 +2319,10 @@ CreateCommandTag(Node *parsetree)
tag = "ALTER TABLE";
break;
case T_AlterDomainStmt:
tag = "ALTER DOMAIN";
break;
case T_GrantStmt:
{
GrantStmt *stmt = (GrantStmt *) parsetree;

View File

@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.184 2002/12/06 03:43:16 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.185 2002/12/06 05:00:31 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -36,6 +36,7 @@
#include "commands/sequence.h"
#include "commands/tablecmds.h"
#include "commands/trigger.h"
#include "commands/typecmds.h"
#include "commands/user.h"
#include "commands/vacuum.h"
#include "commands/view.h"
@ -560,6 +561,49 @@ ProcessUtility(Node *parsetree,
}
break;
case T_AlterDomainStmt:
{
AlterDomainStmt *stmt = (AlterDomainStmt *) parsetree;
/*
* Some or all of these functions are recursive to cover
* inherited things, so permission checks are done there.
*/
switch (stmt->subtype)
{
case 'T': /* ALTER COLUMN DEFAULT */
/*
* Recursively alter column default for table and,
* if requested, for descendants
*/
AlterDomainDefault(stmt->typename,
stmt->def);
break;
case 'N': /* ALTER COLUMN DROP NOT NULL */
AlterDomainNotNull(stmt->typename,
false);
break;
case 'O': /* ALTER COLUMN SET NOT NULL */
AlterDomainNotNull(stmt->typename,
true);
break;
case 'C': /* ADD CONSTRAINT */
AlterDomainAddConstraint(stmt->typename,
stmt->def);
break;
case 'X': /* DROP CONSTRAINT */
AlterDomainDropConstraint(stmt->typename,
stmt->name,
stmt->behavior);
break;
default: /* oops */
elog(ERROR, "T_AlterDomainStmt: unknown subtype");
break;
}
}
break;
case T_GrantStmt:
ExecuteGrantStmt((GrantStmt *) parsetree);

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_type.h,v 1.136 2002/12/06 03:43:18 momjian Exp $
* $Id: pg_type.h,v 1.137 2002/12/06 05:00:31 momjian Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@ -550,7 +550,7 @@ extern Oid TypeCreate(const char *typeName,
Oid elementType,
Oid baseType,
const char *defaultTypeValue,
const char *defaultTypeBin,
char *defaultTypeBin,
bool passedByValue,
char alignment,
char storage,
@ -558,6 +558,18 @@ extern Oid TypeCreate(const char *typeName,
int32 typNDims,
bool typeNotNull);
extern void
GenerateTypeDependencies(Oid typeNamespace,
Oid typeObjectId,
Oid relationOid, /* only for 'c'atalog typeType */
char relationKind,
Oid inputProcedure,
Oid outputProcedure,
Oid elementType,
Oid baseType,
char *defaultTypeBin, /* cooked rep */
bool rebuild);
extern void TypeRename(const char *oldTypeName, Oid typeNamespace,
const char *newTypeName);

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: defrem.h,v 1.48 2002/12/06 03:43:28 momjian Exp $
* $Id: defrem.h,v 1.49 2002/12/06 05:00:31 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -52,14 +52,6 @@ extern void RemoveOperatorById(Oid operOid);
extern void DefineAggregate(List *names, List *parameters);
extern void RemoveAggregate(RemoveAggrStmt *stmt);
/* commands/typecmds.c */
extern void DefineType(List *names, List *parameters);
extern void RemoveType(List *names, DropBehavior behavior);
extern void RemoveTypeById(Oid typeOid);
extern void DefineDomain(CreateDomainStmt *stmt);
extern void RemoveDomain(List *names, DropBehavior behavior);
extern Oid DefineCompositeType(const RangeVar *typevar, List *coldeflist);
/* commands/opclasscmds.c */
extern void DefineOpClass(CreateOpClassStmt *stmt);
extern void RemoveOpClass(RemoveOpClassStmt *stmt);

View File

@ -0,0 +1,30 @@
/*-------------------------------------------------------------------------
*
* tablecmds.h
* prototypes for tablecmds.c.
*
*
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: typecmds.h,v 1.1 2002/12/06 05:00:31 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef TYPECMDS_H
#define TYPECMDS_H
extern void DefineType(List *names, List *parameters);
extern void RemoveType(List *names, DropBehavior behavior);
extern void RemoveTypeById(Oid typeOid);
extern void DefineDomain(CreateDomainStmt *stmt);
extern void RemoveDomain(List *names, DropBehavior behavior);
extern Oid DefineCompositeType(const RangeVar *typevar, List *coldeflist);
extern void AlterDomainDefault(List *names, Node *defaultRaw);
extern void AlterDomainNotNull(List *names, bool notNull);
extern void AlterDomainAddConstraint(List *names, Node *constr);
extern void AlterDomainDropConstraint(List *names, const char *constrName,
DropBehavior behavior);
#endif /* TYPECMDS_H */

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: nodes.h,v 1.128 2002/12/06 03:43:28 momjian Exp $
* $Id: nodes.h,v 1.129 2002/12/06 05:00:31 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -157,6 +157,7 @@ typedef enum NodeTag
T_UpdateStmt,
T_SelectStmt,
T_AlterTableStmt,
T_AlterDomainStmt,
T_SetOperationStmt,
T_GrantStmt,
T_ClosePortalStmt,

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: parsenodes.h,v 1.220 2002/12/06 03:43:28 momjian Exp $
* $Id: parsenodes.h,v 1.221 2002/12/06 05:00:32 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -827,6 +827,33 @@ typedef struct AlterTableStmt
DropBehavior behavior; /* RESTRICT or CASCADE for DROP cases */
} AlterTableStmt;
/* ----------------------
* Alter Domain
*
* The fields are used in different ways by the different variants of
* this command. Subtypes should match AlterTable subtypes
* ----------------------
*/
typedef struct AlterDomainStmt
{
NodeTag type;
char subtype; /*------------
* T = alter column default
* N = alter column drop not null
* O = alter column set not null
* C = add constraint
* X = drop constraint
* U = change owner
*------------
*/
List *typename; /* table to work on */
char *name; /* column or constraint name to act on, or
* new owner */
Node *def; /* definition of default or constraint */
DropBehavior behavior; /* RESTRICT or CASCADE for DROP cases */
} AlterDomainStmt;
/* ----------------------
* Grant|Revoke Statement
* ----------------------

View File

@ -115,7 +115,7 @@ INSERT INTO nulltest DEFAULT VALUES;
ERROR: Domain dnotnull does not allow NULL values
INSERT INTO nulltest values ('a', 'b', 'c', 'd', 'c'); -- Good
insert into nulltest values ('a', 'b', 'c', 'd', NULL);
ERROR: Domain $1 constraint dcheck failed
ERROR: ExecEvalConstraintTest: Domain dcheck constraint $1 failed
insert into nulltest values ('a', 'b', 'c', 'd', 'a');
ERROR: ExecInsert: rejected due to CHECK constraint "nulltest_col5" on "nulltest"
INSERT INTO nulltest values (NULL, 'b', 'c', 'd', 'd');
@ -127,7 +127,7 @@ ERROR: ExecInsert: Fail to add null value in not null attribute col3
INSERT INTO nulltest values ('a', 'b', 'c', NULL, 'd'); -- Good
-- Test copy
COPY nulltest FROM stdin; --fail
ERROR: copy: line 1, Domain $1 constraint dcheck failed
ERROR: copy: line 1, ExecEvalConstraintTest: Domain dcheck constraint $1 failed
lost synchronization with server, resetting connection
SET autocommit TO 'on';
-- Last row is bad
@ -158,6 +158,7 @@ ERROR: Domain dnotnull does not allow NULL values
drop table nulltest;
drop domain dnotnull restrict;
drop domain dnull restrict;
drop domain dcheck restrict;
create domain ddef1 int4 DEFAULT 3;
create domain ddef2 oid DEFAULT '12';
-- Type mixing, function returns int8
@ -191,7 +192,80 @@ select * from defaulttest;
(4 rows)
drop sequence ddef4_seq;
drop table defaulttest;
drop table defaulttest cascade;
-- Test ALTER DOMAIN .. NOT NULL
create domain dnotnulltest integer;
create table domnotnull
( col1 dnotnulltest
, col2 dnotnulltest
);
insert into domnotnull default values;
alter domain dnotnulltest set not null; -- fails
ERROR: ALTER DOMAIN: Relation "domnotnull" Attribute "col1" contains NULL values
update domnotnull set col1 = 5;
alter domain dnotnulltest set not null; -- fails
ERROR: ALTER DOMAIN: Relation "domnotnull" Attribute "col2" contains NULL values
update domnotnull set col2 = 6;
alter domain dnotnulltest set not null;
alter domain dnotnulltest set not null; -- fails
ERROR: AlterDomain: dnotnulltest is already set to NOT NULL
update domnotnull set col1 = null; -- fails
ERROR: Domain dnotnulltest does not allow NULL values
alter domain dnotnulltest drop not null;
alter domain dnotnulltest drop not null; -- fails
ERROR: AlterDomain: dnotnulltest is already set to NULL
update domnotnull set col1 = null;
drop domain dnotnulltest cascade;
NOTICE: Drop cascades to table domnotnull column col2
NOTICE: Drop cascades to table domnotnull column col1
-- Test ALTER DOMAIN .. DEFAULT ..
create table domdeftest (col1 ddef1);
insert into domdeftest default values;
select * from domdeftest;
col1
------
3
(1 row)
alter domain ddef1 set default '42';
insert into domdeftest default values;
select * from domdeftest;
col1
------
3
42
(2 rows)
alter domain ddef1 drop default;
insert into domdeftest default values;
select * from domdeftest;
col1
------
3
42
(3 rows)
drop table domdeftest;
-- Test ALTER DOMAIN .. CONSTRAINT ..
create domain con as integer;
create table domcontest (col1 con);
insert into domcontest values (1);
insert into domcontest values (2);
alter domain con add constraint t check (VALUE < 1); -- fails
ERROR: AlterDomainAddConstraint: Domain con constraint t failed
alter domain con add constraint t check (VALUE < 34);
alter domain con add check (VALUE > 0);
insert into domcontest values (-5); -- fails
ERROR: ExecEvalConstraintTest: Domain con constraint $1 failed
insert into domcontest values (42); -- fails
ERROR: ExecEvalConstraintTest: Domain con constraint t failed
insert into domcontest values (5);
alter domain con drop constraint t;
insert into domcontest values (-5); --fails
ERROR: ExecEvalConstraintTest: Domain con constraint $1 failed
insert into domcontest values (42);
-- cleanup
drop domain ddef1 restrict;
drop domain ddef2 restrict;
drop domain ddef3 restrict;

View File

@ -14,8 +14,8 @@ float8/.*-qnx=float8-exp-three-digits
float8/alpha.*-dec-osf.*:cc=float8-fp-exception
float8/i.86-pc-cygwin=float8-small-is-zero
geometry/.*-darwin=geometry-positive-zeros
geometry/i.86-.*-freebsd4.[0-5]=geometry-positive-zeros
geometry/alpha.*-freebsd4.[0-5]=geometry-positive-zeros
geometry/i.86-.*-freebsd4.[0-7]=geometry-positive-zeros
geometry/alpha.*-freebsd4.[0-7]=geometry-positive-zeros
geometry/i.86-.*-openbsd=geometry-positive-zeros
geometry/sparc-.*-openbsd=geometry-positive-zeros
geometry/.*-netbsd1.[0-5]=geometry-positive-zeros

View File

@ -127,6 +127,7 @@ SELECT cast(col4 as dnotnull) from nulltest; -- fail
drop table nulltest;
drop domain dnotnull restrict;
drop domain dnull restrict;
drop domain dcheck restrict;
create domain ddef1 int4 DEFAULT 3;
@ -159,7 +160,71 @@ COPY defaulttest(col5) FROM stdin;
select * from defaulttest;
drop sequence ddef4_seq;
drop table defaulttest;
drop table defaulttest cascade;
-- Test ALTER DOMAIN .. NOT NULL
create domain dnotnulltest integer;
create table domnotnull
( col1 dnotnulltest
, col2 dnotnulltest
);
insert into domnotnull default values;
alter domain dnotnulltest set not null; -- fails
update domnotnull set col1 = 5;
alter domain dnotnulltest set not null; -- fails
update domnotnull set col2 = 6;
alter domain dnotnulltest set not null;
alter domain dnotnulltest set not null; -- fails
update domnotnull set col1 = null; -- fails
alter domain dnotnulltest drop not null;
alter domain dnotnulltest drop not null; -- fails
update domnotnull set col1 = null;
drop domain dnotnulltest cascade;
-- Test ALTER DOMAIN .. DEFAULT ..
create table domdeftest (col1 ddef1);
insert into domdeftest default values;
select * from domdeftest;
alter domain ddef1 set default '42';
insert into domdeftest default values;
select * from domdeftest;
alter domain ddef1 drop default;
insert into domdeftest default values;
select * from domdeftest;
drop table domdeftest;
-- Test ALTER DOMAIN .. CONSTRAINT ..
create domain con as integer;
create table domcontest (col1 con);
insert into domcontest values (1);
insert into domcontest values (2);
alter domain con add constraint t check (VALUE < 1); -- fails
alter domain con add constraint t check (VALUE < 34);
alter domain con add check (VALUE > 0);
insert into domcontest values (-5); -- fails
insert into domcontest values (42); -- fails
insert into domcontest values (5);
alter domain con drop constraint t;
insert into domcontest values (-5); --fails
insert into domcontest values (42);
-- cleanup
drop domain ddef1 restrict;
drop domain ddef2 restrict;
drop domain ddef3 restrict;