Skip to content

Commit d5fa19c

Browse files
committed
Add COMMENT ON CONSTRAINT facility (from Rod Taylor's pg_constraint patch).
Fix comment.c to not depend on parser token values, per discussion awhile back.
1 parent c4fb2b4 commit d5fa19c

File tree

3 files changed

+154
-46
lines changed

3 files changed

+154
-46
lines changed

src/backend/commands/comment.c

Lines changed: 109 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Copyright (c) 1996-2001, PostgreSQL Global Development Group
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.50 2002/07/12 18:43:15 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.51 2002/07/14 23:38:13 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -19,6 +19,7 @@
1919
#include "catalog/catname.h"
2020
#include "catalog/indexing.h"
2121
#include "catalog/namespace.h"
22+
#include "catalog/pg_constraint.h"
2223
#include "catalog/pg_database.h"
2324
#include "catalog/pg_description.h"
2425
#include "catalog/pg_namespace.h"
@@ -30,7 +31,6 @@
3031
#include "parser/parse_func.h"
3132
#include "parser/parse_oper.h"
3233
#include "parser/parse_type.h"
33-
#include "parser/parse.h"
3434
#include "utils/acl.h"
3535
#include "utils/builtins.h"
3636
#include "utils/fmgroids.h"
@@ -57,6 +57,7 @@ static void CommentAggregate(List *aggregate, List *arguments, char *comment);
5757
static void CommentProc(List *function, List *arguments, char *comment);
5858
static void CommentOperator(List *opername, List *arguments, char *comment);
5959
static void CommentTrigger(List *qualname, char *comment);
60+
static void CommentConstraint(List *qualname, char *comment);
6061

6162

6263
/*
@@ -70,39 +71,42 @@ CommentObject(CommentStmt *stmt)
7071
{
7172
switch (stmt->objtype)
7273
{
73-
case INDEX:
74-
case SEQUENCE:
75-
case TABLE:
76-
case VIEW:
74+
case COMMENT_ON_INDEX:
75+
case COMMENT_ON_SEQUENCE:
76+
case COMMENT_ON_TABLE:
77+
case COMMENT_ON_VIEW:
7778
CommentRelation(stmt->objtype, stmt->objname, stmt->comment);
7879
break;
79-
case COLUMN:
80+
case COMMENT_ON_COLUMN:
8081
CommentAttribute(stmt->objname, stmt->comment);
8182
break;
82-
case DATABASE:
83+
case COMMENT_ON_DATABASE:
8384
CommentDatabase(stmt->objname, stmt->comment);
8485
break;
85-
case RULE:
86+
case COMMENT_ON_RULE:
8687
CommentRule(stmt->objname, stmt->comment);
8788
break;
88-
case TYPE_P:
89+
case COMMENT_ON_TYPE:
8990
CommentType(stmt->objname, stmt->comment);
9091
break;
91-
case AGGREGATE:
92+
case COMMENT_ON_AGGREGATE:
9293
CommentAggregate(stmt->objname, stmt->objargs, stmt->comment);
9394
break;
94-
case FUNCTION:
95+
case COMMENT_ON_FUNCTION:
9596
CommentProc(stmt->objname, stmt->objargs, stmt->comment);
9697
break;
97-
case OPERATOR:
98+
case COMMENT_ON_OPERATOR:
9899
CommentOperator(stmt->objname, stmt->objargs, stmt->comment);
99100
break;
100-
case TRIGGER:
101+
case COMMENT_ON_TRIGGER:
101102
CommentTrigger(stmt->objname, stmt->comment);
102103
break;
103-
case SCHEMA:
104+
case COMMENT_ON_SCHEMA:
104105
CommentNamespace(stmt->objname, stmt->comment);
105106
break;
107+
case COMMENT_ON_CONSTRAINT:
108+
CommentConstraint(stmt->objname, stmt->comment);
109+
break;
106110
default:
107111
elog(ERROR, "An attempt was made to comment on a unknown type: %d",
108112
stmt->objtype);
@@ -309,26 +313,26 @@ CommentRelation(int objtype, List *relname, char *comment)
309313

310314
switch (objtype)
311315
{
312-
case INDEX:
316+
case COMMENT_ON_INDEX:
313317
if (relation->rd_rel->relkind != RELKIND_INDEX)
314318
elog(ERROR, "relation \"%s\" is not an index",
315319
RelationGetRelationName(relation));
316320
break;
317-
case TABLE:
321+
case COMMENT_ON_SEQUENCE:
322+
if (relation->rd_rel->relkind != RELKIND_SEQUENCE)
323+
elog(ERROR, "relation \"%s\" is not a sequence",
324+
RelationGetRelationName(relation));
325+
break;
326+
case COMMENT_ON_TABLE:
318327
if (relation->rd_rel->relkind != RELKIND_RELATION)
319328
elog(ERROR, "relation \"%s\" is not a table",
320329
RelationGetRelationName(relation));
321330
break;
322-
case VIEW:
331+
case COMMENT_ON_VIEW:
323332
if (relation->rd_rel->relkind != RELKIND_VIEW)
324333
elog(ERROR, "relation \"%s\" is not a view",
325334
RelationGetRelationName(relation));
326335
break;
327-
case SEQUENCE:
328-
if (relation->rd_rel->relkind != RELKIND_SEQUENCE)
329-
elog(ERROR, "relation \"%s\" is not a sequence",
330-
RelationGetRelationName(relation));
331-
break;
332336
}
333337

334338
/* Create the comment using the relation's oid */
@@ -439,7 +443,7 @@ CommentDatabase(List *qualname, char *comment)
439443
elog(ERROR, "you are not permitted to comment on database \"%s\"",
440444
database);
441445

442-
/* Create the comments with the pg_database oid */
446+
/* Create the comment with the pg_database oid */
443447

444448
CreateComments(oid, RelOid_pg_database, 0, comment);
445449

@@ -805,7 +809,7 @@ CommentTrigger(List *qualname, char *comment)
805809

806810
systable_endscan(scan);
807811

808-
/* Create the comments with the pg_trigger oid */
812+
/* Create the comment with the pg_trigger oid */
809813

810814
CreateComments(oid, RelationGetRelid(pg_trigger), 0, comment);
811815

@@ -814,3 +818,83 @@ CommentTrigger(List *qualname, char *comment)
814818
heap_close(pg_trigger, AccessShareLock);
815819
heap_close(relation, NoLock);
816820
}
821+
822+
823+
/*
824+
* CommentConstraint --
825+
*
826+
* Enable commenting on constraints held within the pg_constraint
827+
* table. A qualified name is required as constraint names are
828+
* unique per relation.
829+
*/
830+
static void
831+
CommentConstraint(List *qualname, char *comment)
832+
{
833+
int nnames;
834+
List *relName;
835+
char *conName;
836+
RangeVar *rel;
837+
Relation pg_constraint,
838+
relation;
839+
HeapTuple tuple;
840+
SysScanDesc scan;
841+
ScanKeyData skey[1];
842+
Oid conOid = InvalidOid;
843+
844+
/* Separate relname and constraint name */
845+
nnames = length(qualname);
846+
if (nnames < 2)
847+
elog(ERROR, "CommentConstraint: must specify relation and constraint");
848+
relName = ltruncate(nnames-1, listCopy(qualname));
849+
conName = strVal(nth(nnames-1, qualname));
850+
851+
/* Open the owning relation to ensure it won't go away meanwhile */
852+
rel = makeRangeVarFromNameList(relName);
853+
relation = heap_openrv(rel, AccessShareLock);
854+
855+
/* Check object security */
856+
857+
if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
858+
aclcheck_error(ACLCHECK_NOT_OWNER, RelationGetRelationName(relation));
859+
860+
/*
861+
* Fetch the constraint tuple from pg_constraint. There may be more than
862+
* one match, because constraints are not required to have unique names;
863+
* if so, error out.
864+
*/
865+
pg_constraint = heap_openr(ConstraintRelationName, AccessShareLock);
866+
867+
ScanKeyEntryInitialize(&skey[0], 0x0,
868+
Anum_pg_constraint_conrelid, F_OIDEQ,
869+
ObjectIdGetDatum(RelationGetRelid(relation)));
870+
871+
scan = systable_beginscan(pg_constraint, ConstraintRelidIndex, true,
872+
SnapshotNow, 1, skey);
873+
874+
while (HeapTupleIsValid(tuple = systable_getnext(scan)))
875+
{
876+
Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tuple);
877+
878+
if (strcmp(NameStr(con->conname), conName) == 0)
879+
{
880+
if (OidIsValid(conOid))
881+
elog(ERROR, "Relation \"%s\" has multiple constraints named \"%s\"",
882+
RelationGetRelationName(relation), conName);
883+
conOid = tuple->t_data->t_oid;
884+
}
885+
}
886+
887+
systable_endscan(scan);
888+
889+
/* If no constraint exists for the relation specified, notify user */
890+
if (!OidIsValid(conOid))
891+
elog(ERROR, "constraint \"%s\" for relation \"%s\" does not exist",
892+
conName, RelationGetRelationName(relation));
893+
894+
/* Create the comment with the pg_constraint oid */
895+
CreateComments(conOid, RelationGetRelid(pg_constraint), 0, comment);
896+
897+
/* Done, but hold lock on relation */
898+
heap_close(pg_constraint, AccessShareLock);
899+
heap_close(relation, NoLock);
900+
}

src/backend/parser/gram.y

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.339 2002/07/12 18:43:17 tgl Exp $
14+
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.340 2002/07/14 23:38:13 tgl Exp $
1515
*
1616
* HISTORY
1717
* AUTHOR DATE MAJOR EVENT
@@ -2364,7 +2364,7 @@ CommentStmt:
23642364
IS comment_text
23652365
{
23662366
CommentStmt *n = makeNode(CommentStmt);
2367-
n->objtype = AGGREGATE;
2367+
n->objtype = COMMENT_ON_AGGREGATE;
23682368
n->objname = $4;
23692369
n->objargs = makeList1($6);
23702370
n->comment = $9;
@@ -2373,7 +2373,7 @@ CommentStmt:
23732373
| COMMENT ON FUNCTION func_name func_args IS comment_text
23742374
{
23752375
CommentStmt *n = makeNode(CommentStmt);
2376-
n->objtype = FUNCTION;
2376+
n->objtype = COMMENT_ON_FUNCTION;
23772377
n->objname = $4;
23782378
n->objargs = $5;
23792379
n->comment = $7;
@@ -2383,16 +2383,16 @@ CommentStmt:
23832383
IS comment_text
23842384
{
23852385
CommentStmt *n = makeNode(CommentStmt);
2386-
n->objtype = OPERATOR;
2386+
n->objtype = COMMENT_ON_OPERATOR;
23872387
n->objname = $4;
23882388
n->objargs = $6;
23892389
n->comment = $9;
23902390
$$ = (Node *) n;
23912391
}
2392-
| COMMENT ON TRIGGER name ON any_name IS comment_text
2392+
| COMMENT ON CONSTRAINT name ON any_name IS comment_text
23932393
{
23942394
CommentStmt *n = makeNode(CommentStmt);
2395-
n->objtype = TRIGGER;
2395+
n->objtype = COMMENT_ON_CONSTRAINT;
23962396
n->objname = lappend($6, makeString($4));
23972397
n->objargs = NIL;
23982398
n->comment = $8;
@@ -2401,7 +2401,7 @@ CommentStmt:
24012401
| COMMENT ON RULE name ON any_name IS comment_text
24022402
{
24032403
CommentStmt *n = makeNode(CommentStmt);
2404-
n->objtype = RULE;
2404+
n->objtype = COMMENT_ON_RULE;
24052405
n->objname = lappend($6, makeString($4));
24062406
n->objargs = NIL;
24072407
n->comment = $8;
@@ -2411,29 +2411,38 @@ CommentStmt:
24112411
{
24122412
/* Obsolete syntax supported for awhile for compatibility */
24132413
CommentStmt *n = makeNode(CommentStmt);
2414-
n->objtype = RULE;
2414+
n->objtype = COMMENT_ON_RULE;
24152415
n->objname = makeList1(makeString($4));
24162416
n->objargs = NIL;
24172417
n->comment = $6;
24182418
$$ = (Node *) n;
24192419
}
2420+
| COMMENT ON TRIGGER name ON any_name IS comment_text
2421+
{
2422+
CommentStmt *n = makeNode(CommentStmt);
2423+
n->objtype = COMMENT_ON_TRIGGER;
2424+
n->objname = lappend($6, makeString($4));
2425+
n->objargs = NIL;
2426+
n->comment = $8;
2427+
$$ = (Node *) n;
2428+
}
24202429
;
24212430

24222431
comment_type:
2423-
COLUMN { $$ = COLUMN; }
2424-
| DATABASE { $$ = DATABASE; }
2425-
| SCHEMA { $$ = SCHEMA; }
2426-
| INDEX { $$ = INDEX; }
2427-
| SEQUENCE { $$ = SEQUENCE; }
2428-
| TABLE { $$ = TABLE; }
2429-
| DOMAIN_P { $$ = TYPE_P; }
2430-
| TYPE_P { $$ = TYPE_P; }
2431-
| VIEW { $$ = VIEW; }
2432+
COLUMN { $$ = COMMENT_ON_COLUMN; }
2433+
| DATABASE { $$ = COMMENT_ON_DATABASE; }
2434+
| SCHEMA { $$ = COMMENT_ON_SCHEMA; }
2435+
| INDEX { $$ = COMMENT_ON_INDEX; }
2436+
| SEQUENCE { $$ = COMMENT_ON_SEQUENCE; }
2437+
| TABLE { $$ = COMMENT_ON_TABLE; }
2438+
| DOMAIN_P { $$ = COMMENT_ON_TYPE; }
2439+
| TYPE_P { $$ = COMMENT_ON_TYPE; }
2440+
| VIEW { $$ = COMMENT_ON_VIEW; }
24322441
;
24332442

24342443
comment_text:
2435-
Sconst { $$ = $1; }
2436-
| NULL_P { $$ = NULL; }
2444+
Sconst { $$ = $1; }
2445+
| NULL_P { $$ = NULL; }
24372446
;
24382447

24392448
/*****************************************************************************

src/include/nodes/parsenodes.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: parsenodes.h,v 1.185 2002/07/12 18:43:19 tgl Exp $
10+
* $Id: parsenodes.h,v 1.186 2002/07/14 23:38:13 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -1165,10 +1165,25 @@ typedef struct TruncateStmt
11651165
* Comment On Statement
11661166
* ----------------------
11671167
*/
1168+
#define COMMENT_ON_AGGREGATE 100
1169+
#define COMMENT_ON_COLUMN 101
1170+
#define COMMENT_ON_CONSTRAINT 102
1171+
#define COMMENT_ON_DATABASE 103
1172+
#define COMMENT_ON_FUNCTION 104
1173+
#define COMMENT_ON_INDEX 105
1174+
#define COMMENT_ON_OPERATOR 106
1175+
#define COMMENT_ON_RULE 107
1176+
#define COMMENT_ON_SCHEMA 108
1177+
#define COMMENT_ON_SEQUENCE 109
1178+
#define COMMENT_ON_TABLE 110
1179+
#define COMMENT_ON_TRIGGER 111
1180+
#define COMMENT_ON_TYPE 112
1181+
#define COMMENT_ON_VIEW 113
1182+
11681183
typedef struct CommentStmt
11691184
{
11701185
NodeTag type;
1171-
int objtype; /* Object's type */
1186+
int objtype; /* Object's type, see codes above */
11721187
List *objname; /* Qualified name of the object */
11731188
List *objargs; /* Arguments if needed (eg, for functions) */
11741189
char *comment; /* Comment to insert, or NULL to remove */

0 commit comments

Comments
 (0)