Commit 7eca575d authored by Alvaro Herrera's avatar Alvaro Herrera

get_object_address: separate domain constraints from table constraints

Apart from enabling comments on domain constraints, this enables a
future project to replicate object dropping to remote servers: with the
current mechanism there's no way to distinguish between the two types of
constraints, so there's no way to know what to drop.

Also added support for the domain constraint comments in psql's \dd and
pg_dump.

Catalog version bumped due to the change in ObjectType enum.
parent 584e35d1
...@@ -28,6 +28,7 @@ COMMENT ON ...@@ -28,6 +28,7 @@ COMMENT ON
COLLATION <replaceable class="PARAMETER">object_name</replaceable> | COLLATION <replaceable class="PARAMETER">object_name</replaceable> |
COLUMN <replaceable class="PARAMETER">relation_name</replaceable>.<replaceable class="PARAMETER">column_name</replaceable> | COLUMN <replaceable class="PARAMETER">relation_name</replaceable>.<replaceable class="PARAMETER">column_name</replaceable> |
CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> ON <replaceable class="PARAMETER">table_name</replaceable> | CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> ON <replaceable class="PARAMETER">table_name</replaceable> |
CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> ON DOMAIN <replaceable class="PARAMETER">domain_name</replaceable> |
CONVERSION <replaceable class="PARAMETER">object_name</replaceable> | CONVERSION <replaceable class="PARAMETER">object_name</replaceable> |
DATABASE <replaceable class="PARAMETER">object_name</replaceable> | DATABASE <replaceable class="PARAMETER">object_name</replaceable> |
DOMAIN <replaceable class="PARAMETER">object_name</replaceable> | DOMAIN <replaceable class="PARAMETER">object_name</replaceable> |
...@@ -126,6 +127,18 @@ COMMENT ON ...@@ -126,6 +127,18 @@ COMMENT ON
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><replaceable class="parameter">table_name</replaceable></term>
<term><replaceable class="parameter">domain_name</replaceable></term>
<listitem>
<para>
When creating a comment on a constraint on a table or a domain, these
parameteres specify the name of the table or domain on which the
constraint is defined.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><replaceable>source_type</replaceable></term> <term><replaceable>source_type</replaceable></term>
<listitem> <listitem>
...@@ -266,6 +279,7 @@ COMMENT ON COLLATION "fr_CA" IS 'Canadian French'; ...@@ -266,6 +279,7 @@ COMMENT ON COLLATION "fr_CA" IS 'Canadian French';
COMMENT ON COLUMN my_table.my_column IS 'Employee ID number'; COMMENT ON COLUMN my_table.my_column IS 'Employee ID number';
COMMENT ON CONVERSION my_conv IS 'Conversion to UTF8'; COMMENT ON CONVERSION my_conv IS 'Conversion to UTF8';
COMMENT ON CONSTRAINT bar_col_cons ON bar IS 'Constrains column col'; COMMENT ON CONSTRAINT bar_col_cons ON bar IS 'Constrains column col';
COMMENT ON CONSTRAINT dom_col_constr ON DOMAIN dom IS 'Constrains col of domain';
COMMENT ON DATABASE my_database IS 'Development Database'; COMMENT ON DATABASE my_database IS 'Development Database';
COMMENT ON DOMAIN my_domain IS 'Email Address Domain'; COMMENT ON DOMAIN my_domain IS 'Email Address Domain';
COMMENT ON EXTENSION hstore IS 'implements the hstore data type'; COMMENT ON EXTENSION hstore IS 'implements the hstore data type';
......
...@@ -530,11 +530,28 @@ get_object_address(ObjectType objtype, List *objname, List *objargs, ...@@ -530,11 +530,28 @@ get_object_address(ObjectType objtype, List *objname, List *objargs,
break; break;
case OBJECT_RULE: case OBJECT_RULE:
case OBJECT_TRIGGER: case OBJECT_TRIGGER:
case OBJECT_CONSTRAINT: case OBJECT_TABCONSTRAINT:
case OBJECT_POLICY: case OBJECT_POLICY:
address = get_object_address_relobject(objtype, objname, address = get_object_address_relobject(objtype, objname,
&relation, missing_ok); &relation, missing_ok);
break; break;
case OBJECT_DOMCONSTRAINT:
{
List *domname;
ObjectAddress domaddr;
char *constrname;
domname = list_truncate(list_copy(objname), list_length(objname) - 1);
constrname = strVal(llast(objname));
domaddr = get_object_address_type(OBJECT_DOMAIN, domname, missing_ok);
address.classId = ConstraintRelationId;
address.objectId = get_domain_constraint_oid(domaddr.objectId,
constrname, missing_ok);
address.objectSubId = 0;
}
break;
case OBJECT_DATABASE: case OBJECT_DATABASE:
case OBJECT_EXTENSION: case OBJECT_EXTENSION:
case OBJECT_TABLESPACE: case OBJECT_TABLESPACE:
...@@ -934,7 +951,7 @@ get_object_address_relobject(ObjectType objtype, List *objname, ...@@ -934,7 +951,7 @@ get_object_address_relobject(ObjectType objtype, List *objname,
const char *depname; const char *depname;
/* Extract name of dependent object. */ /* Extract name of dependent object. */
depname = strVal(lfirst(list_tail(objname))); depname = strVal(llast(objname));
/* Separate relation name from dependent object name. */ /* Separate relation name from dependent object name. */
nnames = list_length(objname); nnames = list_length(objname);
...@@ -990,7 +1007,7 @@ get_object_address_relobject(ObjectType objtype, List *objname, ...@@ -990,7 +1007,7 @@ get_object_address_relobject(ObjectType objtype, List *objname,
get_trigger_oid(reloid, depname, missing_ok) : InvalidOid; get_trigger_oid(reloid, depname, missing_ok) : InvalidOid;
address.objectSubId = 0; address.objectSubId = 0;
break; break;
case OBJECT_CONSTRAINT: case OBJECT_TABCONSTRAINT:
address.classId = ConstraintRelationId; address.classId = ConstraintRelationId;
address.objectId = relation ? address.objectId = relation ?
get_relation_constraint_oid(reloid, depname, missing_ok) : get_relation_constraint_oid(reloid, depname, missing_ok) :
...@@ -1178,7 +1195,7 @@ check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address, ...@@ -1178,7 +1195,7 @@ check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address,
case OBJECT_RULE: case OBJECT_RULE:
case OBJECT_TRIGGER: case OBJECT_TRIGGER:
case OBJECT_POLICY: case OBJECT_POLICY:
case OBJECT_CONSTRAINT: case OBJECT_TABCONSTRAINT:
if (!pg_class_ownercheck(RelationGetRelid(relation), roleid)) if (!pg_class_ownercheck(RelationGetRelid(relation), roleid))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
RelationGetRelationName(relation)); RelationGetRelationName(relation));
...@@ -1191,6 +1208,7 @@ check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address, ...@@ -1191,6 +1208,7 @@ check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address,
case OBJECT_TYPE: case OBJECT_TYPE:
case OBJECT_DOMAIN: case OBJECT_DOMAIN:
case OBJECT_ATTRIBUTE: case OBJECT_ATTRIBUTE:
case OBJECT_DOMCONSTRAINT:
if (!pg_type_ownercheck(address.objectId, roleid)) if (!pg_type_ownercheck(address.objectId, roleid))
aclcheck_error_type(ACLCHECK_NOT_OWNER, address.objectId); aclcheck_error_type(ACLCHECK_NOT_OWNER, address.objectId);
break; break;
......
...@@ -305,7 +305,8 @@ ExecRenameStmt(RenameStmt *stmt) ...@@ -305,7 +305,8 @@ ExecRenameStmt(RenameStmt *stmt)
{ {
switch (stmt->renameType) switch (stmt->renameType)
{ {
case OBJECT_CONSTRAINT: case OBJECT_TABCONSTRAINT:
case OBJECT_DOMCONSTRAINT:
return RenameConstraint(stmt); return RenameConstraint(stmt);
case OBJECT_DATABASE: case OBJECT_DATABASE:
......
...@@ -1053,10 +1053,10 @@ EventTriggerSupportsObjectType(ObjectType obtype) ...@@ -1053,10 +1053,10 @@ EventTriggerSupportsObjectType(ObjectType obtype)
case OBJECT_ATTRIBUTE: case OBJECT_ATTRIBUTE:
case OBJECT_CAST: case OBJECT_CAST:
case OBJECT_COLUMN: case OBJECT_COLUMN:
case OBJECT_CONSTRAINT:
case OBJECT_COLLATION: case OBJECT_COLLATION:
case OBJECT_CONVERSION: case OBJECT_CONVERSION:
case OBJECT_DOMAIN: case OBJECT_DOMAIN:
case OBJECT_DOMCONSTRAINT:
case OBJECT_EXTENSION: case OBJECT_EXTENSION:
case OBJECT_FDW: case OBJECT_FDW:
case OBJECT_FOREIGN_SERVER: case OBJECT_FOREIGN_SERVER:
...@@ -1073,6 +1073,7 @@ EventTriggerSupportsObjectType(ObjectType obtype) ...@@ -1073,6 +1073,7 @@ EventTriggerSupportsObjectType(ObjectType obtype)
case OBJECT_RULE: case OBJECT_RULE:
case OBJECT_SCHEMA: case OBJECT_SCHEMA:
case OBJECT_SEQUENCE: case OBJECT_SEQUENCE:
case OBJECT_TABCONSTRAINT:
case OBJECT_TABLE: case OBJECT_TABLE:
case OBJECT_TRIGGER: case OBJECT_TRIGGER:
case OBJECT_TSCONFIGURATION: case OBJECT_TSCONFIGURATION:
......
...@@ -2457,7 +2457,7 @@ RenameConstraint(RenameStmt *stmt) ...@@ -2457,7 +2457,7 @@ RenameConstraint(RenameStmt *stmt)
Oid relid = InvalidOid; Oid relid = InvalidOid;
Oid typid = InvalidOid; Oid typid = InvalidOid;
if (stmt->relationType == OBJECT_DOMAIN) if (stmt->renameType == OBJECT_DOMCONSTRAINT)
{ {
Relation rel; Relation rel;
HeapTuple tup; HeapTuple tup;
......
...@@ -5572,6 +5572,7 @@ opt_restart_seqs: ...@@ -5572,6 +5572,7 @@ opt_restart_seqs:
* CAST (<src type> AS <dst type>) | * CAST (<src type> AS <dst type>) |
* COLUMN <relname>.<colname> | * COLUMN <relname>.<colname> |
* CONSTRAINT <constraintname> ON <relname> | * CONSTRAINT <constraintname> ON <relname> |
* CONSTRAINT <constraintname> ON DOMAIN <domainname> |
* FUNCTION <funcname> (arg1, arg2, ...) | * FUNCTION <funcname> (arg1, arg2, ...) |
* LARGE OBJECT <oid> | * LARGE OBJECT <oid> |
* OPERATOR <op> (leftoperand_typ, rightoperand_typ) | * OPERATOR <op> (leftoperand_typ, rightoperand_typ) |
...@@ -5623,12 +5624,21 @@ CommentStmt: ...@@ -5623,12 +5624,21 @@ CommentStmt:
| COMMENT ON CONSTRAINT name ON any_name IS comment_text | COMMENT ON CONSTRAINT name ON any_name IS comment_text
{ {
CommentStmt *n = makeNode(CommentStmt); CommentStmt *n = makeNode(CommentStmt);
n->objtype = OBJECT_CONSTRAINT; n->objtype = OBJECT_TABCONSTRAINT;
n->objname = lappend($6, makeString($4)); n->objname = lappend($6, makeString($4));
n->objargs = NIL; n->objargs = NIL;
n->comment = $8; n->comment = $8;
$$ = (Node *) n; $$ = (Node *) n;
} }
| COMMENT ON CONSTRAINT name ON DOMAIN_P any_name IS comment_text
{
CommentStmt *n = makeNode(CommentStmt);
n->objtype = OBJECT_DOMCONSTRAINT;
n->objname = lappend($7, makeString($4));
n->objargs = NIL;
n->comment = $9;
$$ = (Node *) n;
}
| COMMENT ON POLICY name ON any_name IS comment_text | COMMENT ON POLICY name ON any_name IS comment_text
{ {
CommentStmt *n = makeNode(CommentStmt); CommentStmt *n = makeNode(CommentStmt);
...@@ -7355,8 +7365,7 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name ...@@ -7355,8 +7365,7 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
| ALTER DOMAIN_P any_name RENAME CONSTRAINT name TO name | ALTER DOMAIN_P any_name RENAME CONSTRAINT name TO name
{ {
RenameStmt *n = makeNode(RenameStmt); RenameStmt *n = makeNode(RenameStmt);
n->renameType = OBJECT_CONSTRAINT; n->renameType = OBJECT_DOMCONSTRAINT;
n->relationType = OBJECT_DOMAIN;
n->object = $3; n->object = $3;
n->subname = $6; n->subname = $6;
n->newname = $8; n->newname = $8;
...@@ -7624,8 +7633,7 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name ...@@ -7624,8 +7633,7 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
| ALTER TABLE relation_expr RENAME CONSTRAINT name TO name | ALTER TABLE relation_expr RENAME CONSTRAINT name TO name
{ {
RenameStmt *n = makeNode(RenameStmt); RenameStmt *n = makeNode(RenameStmt);
n->renameType = OBJECT_CONSTRAINT; n->renameType = OBJECT_TABCONSTRAINT;
n->relationType = OBJECT_TABLE;
n->relation = $3; n->relation = $3;
n->subname = $6; n->subname = $6;
n->newname = $8; n->newname = $8;
......
...@@ -896,7 +896,7 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla ...@@ -896,7 +896,7 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
{ {
CommentStmt *stmt = makeNode(CommentStmt); CommentStmt *stmt = makeNode(CommentStmt);
stmt->objtype = OBJECT_CONSTRAINT; stmt->objtype = OBJECT_TABCONSTRAINT;
stmt->objname = list_make3(makeString(cxt->relation->schemaname), stmt->objname = list_make3(makeString(cxt->relation->schemaname),
makeString(cxt->relation->relname), makeString(cxt->relation->relname),
makeString(n->conname)); makeString(n->conname));
......
...@@ -1589,9 +1589,6 @@ AlterObjectTypeCommandTag(ObjectType objtype) ...@@ -1589,9 +1589,6 @@ AlterObjectTypeCommandTag(ObjectType objtype)
case OBJECT_COLUMN: case OBJECT_COLUMN:
tag = "ALTER TABLE"; tag = "ALTER TABLE";
break; break;
case OBJECT_CONSTRAINT:
tag = "ALTER TABLE";
break;
case OBJECT_CONVERSION: case OBJECT_CONVERSION:
tag = "ALTER CONVERSION"; tag = "ALTER CONVERSION";
break; break;
...@@ -1599,6 +1596,7 @@ AlterObjectTypeCommandTag(ObjectType objtype) ...@@ -1599,6 +1596,7 @@ AlterObjectTypeCommandTag(ObjectType objtype)
tag = "ALTER DATABASE"; tag = "ALTER DATABASE";
break; break;
case OBJECT_DOMAIN: case OBJECT_DOMAIN:
case OBJECT_DOMCONSTRAINT:
tag = "ALTER DOMAIN"; tag = "ALTER DOMAIN";
break; break;
case OBJECT_EXTENSION: case OBJECT_EXTENSION:
...@@ -1650,6 +1648,7 @@ AlterObjectTypeCommandTag(ObjectType objtype) ...@@ -1650,6 +1648,7 @@ AlterObjectTypeCommandTag(ObjectType objtype)
tag = "ALTER SEQUENCE"; tag = "ALTER SEQUENCE";
break; break;
case OBJECT_TABLE: case OBJECT_TABLE:
case OBJECT_TABCONSTRAINT:
tag = "ALTER TABLE"; tag = "ALTER TABLE";
break; break;
case OBJECT_TABLESPACE: case OBJECT_TABLESPACE:
......
...@@ -9261,6 +9261,23 @@ dumpDomain(Archive *fout, DumpOptions *dopt, TypeInfo *tyinfo) ...@@ -9261,6 +9261,23 @@ dumpDomain(Archive *fout, DumpOptions *dopt, TypeInfo *tyinfo)
tyinfo->dobj.namespace->dobj.name, tyinfo->dobj.namespace->dobj.name,
tyinfo->rolname, tyinfo->typacl); tyinfo->rolname, tyinfo->typacl);
/* Dump any per-constraint comments */
for (i = 0; i < tyinfo->nDomChecks; i++)
{
ConstraintInfo *domcheck = &(tyinfo->domChecks[i]);
PQExpBuffer labelq = createPQExpBuffer();
appendPQExpBuffer(labelq, "CONSTRAINT %s ",
fmtId(domcheck->dobj.name));
appendPQExpBuffer(labelq, "ON DOMAIN %s",
fmtId(qtypname));
dumpComment(fout, dopt, labelq->data,
tyinfo->dobj.namespace->dobj.name,
tyinfo->rolname,
domcheck->dobj.catId, 0, tyinfo->dobj.dumpId);
destroyPQExpBuffer(labelq);
}
destroyPQExpBuffer(q); destroyPQExpBuffer(q);
destroyPQExpBuffer(delq); destroyPQExpBuffer(delq);
destroyPQExpBuffer(labelq); destroyPQExpBuffer(labelq);
......
...@@ -952,7 +952,7 @@ objectDescription(const char *pattern, bool showSystem) ...@@ -952,7 +952,7 @@ objectDescription(const char *pattern, bool showSystem)
gettext_noop("Object"), gettext_noop("Object"),
gettext_noop("Description")); gettext_noop("Description"));
/* Constraint descriptions */ /* Table constraint descriptions */
appendPQExpBuffer(&buf, appendPQExpBuffer(&buf,
" SELECT pgc.oid as oid, pgc.tableoid AS tableoid,\n" " SELECT pgc.oid as oid, pgc.tableoid AS tableoid,\n"
" n.nspname as nspname,\n" " n.nspname as nspname,\n"
...@@ -963,7 +963,7 @@ objectDescription(const char *pattern, bool showSystem) ...@@ -963,7 +963,7 @@ objectDescription(const char *pattern, bool showSystem)
"ON c.oid = pgc.conrelid\n" "ON c.oid = pgc.conrelid\n"
" LEFT JOIN pg_catalog.pg_namespace n " " LEFT JOIN pg_catalog.pg_namespace n "
" ON n.oid = c.relnamespace\n", " ON n.oid = c.relnamespace\n",
gettext_noop("constraint")); gettext_noop("table constraint"));
if (!showSystem && !pattern) if (!showSystem && !pattern)
appendPQExpBufferStr(&buf, "WHERE n.nspname <> 'pg_catalog'\n" appendPQExpBufferStr(&buf, "WHERE n.nspname <> 'pg_catalog'\n"
...@@ -973,6 +973,29 @@ objectDescription(const char *pattern, bool showSystem) ...@@ -973,6 +973,29 @@ objectDescription(const char *pattern, bool showSystem)
false, "n.nspname", "pgc.conname", NULL, false, "n.nspname", "pgc.conname", NULL,
"pg_catalog.pg_table_is_visible(c.oid)"); "pg_catalog.pg_table_is_visible(c.oid)");
/* Domain constraint descriptions */
appendPQExpBuffer(&buf,
"UNION ALL\n"
" SELECT pgc.oid as oid, pgc.tableoid AS tableoid,\n"
" n.nspname as nspname,\n"
" CAST(pgc.conname AS pg_catalog.text) as name,"
" CAST('%s' AS pg_catalog.text) as object\n"
" FROM pg_catalog.pg_constraint pgc\n"
" JOIN pg_catalog.pg_type t "
"ON t.oid = pgc.contypid\n"
" LEFT JOIN pg_catalog.pg_namespace n "
" ON n.oid = t.typnamespace\n",
gettext_noop("domain constraint"));
if (!showSystem && !pattern)
appendPQExpBufferStr(&buf, "WHERE n.nspname <> 'pg_catalog'\n"
" AND n.nspname <> 'information_schema'\n");
processSQLNamePattern(pset.db, &buf, pattern, !showSystem && !pattern,
false, "n.nspname", "pgc.conname", NULL,
"pg_catalog.pg_type_is_visible(t.oid)");
/* /*
* pg_opclass.opcmethod only available in 8.3+ * pg_opclass.opcmethod only available in 8.3+
*/ */
......
...@@ -1208,11 +1208,11 @@ typedef enum ObjectType ...@@ -1208,11 +1208,11 @@ typedef enum ObjectType
OBJECT_ATTRIBUTE, /* type's attribute, when distinct from column */ OBJECT_ATTRIBUTE, /* type's attribute, when distinct from column */
OBJECT_CAST, OBJECT_CAST,
OBJECT_COLUMN, OBJECT_COLUMN,
OBJECT_CONSTRAINT,
OBJECT_COLLATION, OBJECT_COLLATION,
OBJECT_CONVERSION, OBJECT_CONVERSION,
OBJECT_DATABASE, OBJECT_DATABASE,
OBJECT_DOMAIN, OBJECT_DOMAIN,
OBJECT_DOMCONSTRAINT,
OBJECT_EVENT_TRIGGER, OBJECT_EVENT_TRIGGER,
OBJECT_EXTENSION, OBJECT_EXTENSION,
OBJECT_FDW, OBJECT_FDW,
...@@ -1231,6 +1231,7 @@ typedef enum ObjectType ...@@ -1231,6 +1231,7 @@ typedef enum ObjectType
OBJECT_RULE, OBJECT_RULE,
OBJECT_SCHEMA, OBJECT_SCHEMA,
OBJECT_SEQUENCE, OBJECT_SEQUENCE,
OBJECT_TABCONSTRAINT,
OBJECT_TABLE, OBJECT_TABLE,
OBJECT_TABLESPACE, OBJECT_TABLESPACE,
OBJECT_TRIGGER, OBJECT_TRIGGER,
......
...@@ -478,3 +478,24 @@ UPDATE deferred_excl SET f1 = 3; ...@@ -478,3 +478,24 @@ UPDATE deferred_excl SET f1 = 3;
ALTER TABLE deferred_excl ADD EXCLUDE (f1 WITH =); ALTER TABLE deferred_excl ADD EXCLUDE (f1 WITH =);
DROP TABLE deferred_excl; DROP TABLE deferred_excl;
-- Comments
CREATE TABLE constraint_comments_tbl (a int CONSTRAINT the_constraint CHECK (a > 0));
CREATE DOMAIN constraint_comments_dom AS int CONSTRAINT the_constraint CHECK (value > 0);
COMMENT ON CONSTRAINT the_constraint ON constraint_comments_tbl IS 'yes, the comment';
COMMENT ON CONSTRAINT the_constraint ON DOMAIN constraint_comments_dom IS 'yes, another comment';
-- no such constraint
COMMENT ON CONSTRAINT no_constraint ON constraint_comments_tbl IS 'yes, the comment';
COMMENT ON CONSTRAINT no_constraint ON DOMAIN constraint_comments_dom IS 'yes, another comment';
-- no such table/domain
COMMENT ON CONSTRAINT the_constraint ON no_comments_tbl IS 'bad comment';
COMMENT ON CONSTRAINT the_constraint ON DOMAIN no_comments_dom IS 'another bad comment';
COMMENT ON CONSTRAINT the_constraint ON constraint_comments_tbl IS NULL;
COMMENT ON CONSTRAINT the_constraint ON DOMAIN constraint_comments_dom IS NULL;
DROP TABLE constraint_comments_tbl;
DROP DOMAIN constraint_comments_dom;
...@@ -645,3 +645,22 @@ ALTER TABLE deferred_excl ADD EXCLUDE (f1 WITH =); ...@@ -645,3 +645,22 @@ ALTER TABLE deferred_excl ADD EXCLUDE (f1 WITH =);
ERROR: could not create exclusion constraint "deferred_excl_f1_excl" ERROR: could not create exclusion constraint "deferred_excl_f1_excl"
DETAIL: Key (f1)=(3) conflicts with key (f1)=(3). DETAIL: Key (f1)=(3) conflicts with key (f1)=(3).
DROP TABLE deferred_excl; DROP TABLE deferred_excl;
-- Comments
CREATE TABLE constraint_comments_tbl (a int CONSTRAINT the_constraint CHECK (a > 0));
CREATE DOMAIN constraint_comments_dom AS int CONSTRAINT the_constraint CHECK (value > 0);
COMMENT ON CONSTRAINT the_constraint ON constraint_comments_tbl IS 'yes, the comment';
COMMENT ON CONSTRAINT the_constraint ON DOMAIN constraint_comments_dom IS 'yes, another comment';
-- no such constraint
COMMENT ON CONSTRAINT no_constraint ON constraint_comments_tbl IS 'yes, the comment';
ERROR: constraint "no_constraint" for table "constraint_comments_tbl" does not exist
COMMENT ON CONSTRAINT no_constraint ON DOMAIN constraint_comments_dom IS 'yes, another comment';
ERROR: constraint "no_constraint" for domain "constraint_comments_dom" does not exist
-- no such table/domain
COMMENT ON CONSTRAINT the_constraint ON no_comments_tbl IS 'bad comment';
ERROR: relation "no_comments_tbl" does not exist
COMMENT ON CONSTRAINT the_constraint ON DOMAIN no_comments_dom IS 'another bad comment';
ERROR: type "no_comments_dom" does not exist
COMMENT ON CONSTRAINT the_constraint ON constraint_comments_tbl IS NULL;
COMMENT ON CONSTRAINT the_constraint ON DOMAIN constraint_comments_dom IS NULL;
DROP TABLE constraint_comments_tbl;
DROP DOMAIN constraint_comments_dom;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment