COLLATION <replaceable class="PARAMETER">object_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 DOMAIN <replaceable class="PARAMETER">domain_name</replaceable> |
CONVERSION <replaceable class="PARAMETER">object_name</replaceable> |
DATABASE <replaceable class="PARAMETER">object_name</replaceable> |
DOMAIN <replaceable class="PARAMETER">object_name</replaceable> |
</listitem>
</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>
<term><replaceable>source_type</replaceable></term>
<listitem>
COMMENT ON COLUMN my_table.my_column IS 'Employee ID number';
COMMENT ON CONVERSION my_conv IS 'Conversion to UTF8';
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 DOMAIN my_domain IS 'Email Address Domain';
COMMENT ON EXTENSION hstore IS 'implements the hstore data type';
break;
case OBJECT_RULE:
case OBJECT_TRIGGER:
- case OBJECT_CONSTRAINT:
+ case OBJECT_TABCONSTRAINT:
case OBJECT_POLICY:
address = get_object_address_relobject(objtype, objname,
&relation, missing_ok);
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_EXTENSION:
case OBJECT_TABLESPACE:
const char *depname;
/* Extract name of dependent object. */
- depname = strVal(lfirst(list_tail(objname)));
+ depname = strVal(llast(objname));
/* Separate relation name from dependent object name. */
nnames = list_length(objname);
get_trigger_oid(reloid, depname, missing_ok) : InvalidOid;
address.objectSubId = 0;
break;
- case OBJECT_CONSTRAINT:
+ case OBJECT_TABCONSTRAINT:
address.classId = ConstraintRelationId;
address.objectId = relation ?
get_relation_constraint_oid(reloid, depname, missing_ok) :
case OBJECT_RULE:
case OBJECT_TRIGGER:
case OBJECT_POLICY:
- case OBJECT_CONSTRAINT:
+ case OBJECT_TABCONSTRAINT:
if (!pg_class_ownercheck(RelationGetRelid(relation), roleid))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
RelationGetRelationName(relation));
case OBJECT_TYPE:
case OBJECT_DOMAIN:
case OBJECT_ATTRIBUTE:
+ case OBJECT_DOMCONSTRAINT:
if (!pg_type_ownercheck(address.objectId, roleid))
aclcheck_error_type(ACLCHECK_NOT_OWNER, address.objectId);
break;
{
switch (stmt->renameType)
{
- case OBJECT_CONSTRAINT:
+ case OBJECT_TABCONSTRAINT:
+ case OBJECT_DOMCONSTRAINT:
return RenameConstraint(stmt);
case OBJECT_DATABASE:
case OBJECT_ATTRIBUTE:
case OBJECT_CAST:
case OBJECT_COLUMN:
- case OBJECT_CONSTRAINT:
case OBJECT_COLLATION:
case OBJECT_CONVERSION:
case OBJECT_DOMAIN:
+ case OBJECT_DOMCONSTRAINT:
case OBJECT_EXTENSION:
case OBJECT_FDW:
case OBJECT_FOREIGN_SERVER:
case OBJECT_RULE:
case OBJECT_SCHEMA:
case OBJECT_SEQUENCE:
+ case OBJECT_TABCONSTRAINT:
case OBJECT_TABLE:
case OBJECT_TRIGGER:
case OBJECT_TSCONFIGURATION:
Oid relid = InvalidOid;
Oid typid = InvalidOid;
- if (stmt->relationType == OBJECT_DOMAIN)
+ if (stmt->renameType == OBJECT_DOMCONSTRAINT)
{
Relation rel;
HeapTuple tup;
* CAST (<src type> AS <dst type>) |
* COLUMN <relname>.<colname> |
* CONSTRAINT <constraintname> ON <relname> |
+ * CONSTRAINT <constraintname> ON DOMAIN <domainname> |
* FUNCTION <funcname> (arg1, arg2, ...) |
* LARGE OBJECT <oid> |
* OPERATOR <op> (leftoperand_typ, rightoperand_typ) |
| COMMENT ON CONSTRAINT name ON any_name IS comment_text
{
CommentStmt *n = makeNode(CommentStmt);
- n->objtype = OBJECT_CONSTRAINT;
+ n->objtype = OBJECT_TABCONSTRAINT;
n->objname = lappend($6, makeString($4));
n->objargs = NIL;
n->comment = $8;
$$ = (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
{
CommentStmt *n = makeNode(CommentStmt);
| ALTER DOMAIN_P any_name RENAME CONSTRAINT name TO name
{
RenameStmt *n = makeNode(RenameStmt);
- n->renameType = OBJECT_CONSTRAINT;
- n->relationType = OBJECT_DOMAIN;
+ n->renameType = OBJECT_DOMCONSTRAINT;
n->object = $3;
n->subname = $6;
n->newname = $8;
| ALTER TABLE relation_expr RENAME CONSTRAINT name TO name
{
RenameStmt *n = makeNode(RenameStmt);
- n->renameType = OBJECT_CONSTRAINT;
- n->relationType = OBJECT_TABLE;
+ n->renameType = OBJECT_TABCONSTRAINT;
n->relation = $3;
n->subname = $6;
n->newname = $8;
{
CommentStmt *stmt = makeNode(CommentStmt);
- stmt->objtype = OBJECT_CONSTRAINT;
+ stmt->objtype = OBJECT_TABCONSTRAINT;
stmt->objname = list_make3(makeString(cxt->relation->schemaname),
makeString(cxt->relation->relname),
makeString(n->conname));
case OBJECT_COLUMN:
tag = "ALTER TABLE";
break;
- case OBJECT_CONSTRAINT:
- tag = "ALTER TABLE";
- break;
case OBJECT_CONVERSION:
tag = "ALTER CONVERSION";
break;
tag = "ALTER DATABASE";
break;
case OBJECT_DOMAIN:
+ case OBJECT_DOMCONSTRAINT:
tag = "ALTER DOMAIN";
break;
case OBJECT_EXTENSION:
tag = "ALTER SEQUENCE";
break;
case OBJECT_TABLE:
+ case OBJECT_TABCONSTRAINT:
tag = "ALTER TABLE";
break;
case OBJECT_TABLESPACE:
tyinfo->dobj.namespace->dobj.name,
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(delq);
destroyPQExpBuffer(labelq);
gettext_noop("Object"),
gettext_noop("Description"));
- /* Constraint descriptions */
+ /* Table constraint descriptions */
appendPQExpBuffer(&buf,
" SELECT pgc.oid as oid, pgc.tableoid AS tableoid,\n"
" n.nspname as nspname,\n"
"ON c.oid = pgc.conrelid\n"
" LEFT JOIN pg_catalog.pg_namespace n "
" ON n.oid = c.relnamespace\n",
- gettext_noop("constraint"));
+ gettext_noop("table constraint"));
if (!showSystem && !pattern)
appendPQExpBufferStr(&buf, "WHERE n.nspname <> 'pg_catalog'\n"
false, "n.nspname", "pgc.conname", NULL,
"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+
*/
OBJECT_ATTRIBUTE, /* type's attribute, when distinct from column */
OBJECT_CAST,
OBJECT_COLUMN,
- OBJECT_CONSTRAINT,
OBJECT_COLLATION,
OBJECT_CONVERSION,
OBJECT_DATABASE,
OBJECT_DOMAIN,
+ OBJECT_DOMCONSTRAINT,
OBJECT_EVENT_TRIGGER,
OBJECT_EXTENSION,
OBJECT_FDW,
OBJECT_RULE,
OBJECT_SCHEMA,
OBJECT_SEQUENCE,
+ OBJECT_TABCONSTRAINT,
OBJECT_TABLE,
OBJECT_TABLESPACE,
OBJECT_TRIGGER,
ALTER TABLE deferred_excl ADD EXCLUDE (f1 WITH =);
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;
ERROR: could not create exclusion constraint "deferred_excl_f1_excl"
DETAIL: Key (f1)=(3) conflicts with key (f1)=(3).
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;