Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf69bc37

Browse files
committed
Make operators have their own comments separate from those of the
underlying function; but cause psql's \do to show the underlyingfunction's comment if the operator has no comment of its own, to preservethe useful functionality of the original behavior. Also, implementCOMMENT ON SCHEMA. Patch from Rod Taylor.
1 parent3389a11 commitf69bc37

File tree

5 files changed

+119
-62
lines changed

5 files changed

+119
-62
lines changed

‎doc/src/sgml/ref/comment.sgml

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/ref/comment.sgml,v 1.18 2002/04/23 02:07:15 tgl Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/ref/comment.sgml,v 1.19 2002/05/13 17:45:30 tgl Exp $
33
PostgreSQL documentation
44
-->
55

@@ -23,13 +23,20 @@ PostgreSQL documentation
2323
<synopsis>
2424
COMMENT ON
2525
[
26-
[ DATABASE | DOMAIN | INDEX | SEQUENCE |TABLE | TYPE | VIEW ] <replaceable class="PARAMETER">object_name</replaceable> |
26+
TABLE <replaceable class="PARAMETER">object_name</replaceable> |
2727
COLUMN <replaceable class="PARAMETER">table_name</replaceable>.<replaceable class="PARAMETER">column_name</replaceable> |
2828
AGGREGATE <replaceable class="PARAMETER">agg_name</replaceable> (<replaceable class="PARAMETER">agg_type</replaceable>) |
29-
FUNCTION <replaceable class="PARAMETER">func_name</replaceable> (<replaceable class="PARAMETER">arg1</replaceable>, <replaceable class="PARAMETER">arg2</replaceable>, ...) |
30-
OPERATOR <replaceable class="PARAMETER">op</replaceable> (<replaceable class="PARAMETER">leftoperand_type</replaceable> <replaceable class="PARAMETER">rightoperand_type</replaceable>) |
29+
DATABASE <replaceable class="PARAMETER">object_name</replaceable> |
30+
DOMAIN <replaceable class="PARAMETER">object_name</replaceable> |
31+
FUNCTION <replaceable class="PARAMETER">func_name</replaceable> (<replaceable class="PARAMETER">arg1_type</replaceable>, <replaceable class="PARAMETER">arg2_type</replaceable>, ...) |
32+
INDEX <replaceable class="PARAMETER">object_name</replaceable> |
33+
OPERATOR <replaceable class="PARAMETER">op</replaceable> (<replaceable class="PARAMETER">leftoperand_type</replaceable>, <replaceable class="PARAMETER">rightoperand_type</replaceable>) |
3134
RULE <replaceable class="PARAMETER">rule_name</replaceable> ON <replaceable class="PARAMETER">table_name</replaceable> |
32-
TRIGGER <replaceable class="PARAMETER">trigger_name</replaceable> ON <replaceable class="PARAMETER">table_name</replaceable>
35+
SCHEMA <replaceable class="PARAMETER">object_name</replaceable> |
36+
SEQUENCE <replaceable class="PARAMETER">object_name</replaceable> |
37+
TRIGGER <replaceable class="PARAMETER">trigger_name</replaceable> ON <replaceable class="PARAMETER">table_name</replaceable> |
38+
TYPE <replaceable class="PARAMETER">object_name</replaceable> |
39+
VIEW <replaceable class="PARAMETER">object_name</replaceable>
3340
] IS <replaceable class="PARAMETER">'text'</replaceable>
3441
</synopsis>
3542

@@ -49,8 +56,9 @@ COMMENT ON
4956
<listitem>
5057
<para>
5158
The name of the object to be be commented. Names of tables,
52-
indexes, sequences, views, types, domains, functions, aggregates,
53-
and operators may be schema-qualified.
59+
aggregates, domains, functions, indexes, operators, sequences, types,
60+
and views
61+
may be schema-qualified.
5462
</para>
5563
</listitem>
5664
</varlistentry>
@@ -116,44 +124,54 @@ COMMENT
116124
Comments are automatically dropped when the object is dropped.
117125
</para>
118126

127+
<note>
119128
<para>
120-
It should be noted that there is presently no security mechanism
129+
There is presently no security mechanism
121130
for comments: any user connected to a database can see all the comments
122131
for objects in that database (although only superusers can change
123132
comments for objects that they don't own). Therefore, don't put
124133
security-critical information in comments.
125134
</para>
135+
</note>
126136
</refsect1>
127137

128138
<refsect1 id="R1-SQL-COMMENT-2">
129139
<title>
130140
Usage
131141
</title>
132142
<para>
133-
Comment the table <literal>mytable</literal>:
143+
Attach a comment to the table <literal>mytable</literal>:
134144

135145
<programlisting>
136-
COMMENT ON mytable IS 'This is my table.';
146+
COMMENT ON TABLE mytable IS 'This is my table.';
147+
</programlisting>
148+
149+
Remove it again:
150+
151+
<programlisting>
152+
COMMENT ON TABLE mytable IS NULL;
137153
</programlisting>
138154
</para>
139155

140156
<para>
141157
Some more examples:
142158

143159
<programlisting>
160+
COMMENT ON AGGREGATE my_aggregate (double precision) IS 'Computes sample variance';
161+
COMMENT ON COLUMN my_table.my_field IS 'Employee ID number';
144162
COMMENT ON DATABASE my_database IS 'Development Database';
145163
COMMENT ON DOMAIN my_domain IS 'Email Address Domain';
146-
COMMENT ON INDEX my_index IS 'Enforces uniqueness on employee id';
147-
COMMENT ON SEQUENCE my_sequence IS 'Used to generate primary keys';
148-
COMMENT ON TABLE my_table IS 'Employee Information';
149-
COMMENT ON TYPE my_type IS 'Complex Number support';
150-
COMMENT ON VIEW my_view IS 'View of departmental costs';
151-
COMMENT ON COLUMN my_table.my_field IS 'Employee ID number';
152-
COMMENT ON AGGREGATE my_aggregate (double precision) IS 'Computes sample variance';
153164
COMMENT ON FUNCTION my_function (timestamp) IS 'Returns Roman Numeral';
154-
COMMENT ON OPERATOR ^ (text, text) IS 'Performs intersection of two text';
165+
COMMENT ON INDEX my_index IS 'Enforces uniqueness on employee id';
166+
COMMENT ON OPERATOR ^ (text, text) IS 'Performs intersection of two texts';
167+
COMMENT ON OPERATOR ^ (NONE, text) IS 'This is a prefix operator on text';
155168
COMMENT ON RULE my_rule ON my_table IS 'Logs UPDATES of employee records';
169+
COMMENT ON SCHEMA my_schema IS 'Departmental data';
170+
COMMENT ON SEQUENCE my_sequence IS 'Used to generate primary keys';
171+
COMMENT ON TABLE my_schema.my_table IS 'Employee Information';
156172
COMMENT ON TRIGGER my_trigger ON my_table IS 'Used for R.I.';
173+
COMMENT ON TYPE complex IS 'Complex Number datatype';
174+
COMMENT ON VIEW my_view IS 'View of departmental costs';
157175
</programlisting>
158176
</para>
159177
</refsect1>

‎src/backend/commands/comment.c

Lines changed: 67 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Copyright (c) 1999-2001, PostgreSQL Global Development Group
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.45 2002/04/27 03:45:00 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.46 2002/05/13 17:45:30 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -50,6 +50,7 @@
5050
staticvoidCommentRelation(intobjtype,List*relname,char*comment);
5151
staticvoidCommentAttribute(List*qualname,char*comment);
5252
staticvoidCommentDatabase(List*qualname,char*comment);
53+
staticvoidCommentNamespace(List*qualname,char*comment);
5354
staticvoidCommentRule(List*qualname,char*comment);
5455
staticvoidCommentType(List*typename,char*comment);
5556
staticvoidCommentAggregate(List*aggregate,List*arguments,char*comment);
@@ -99,6 +100,9 @@ CommentObject(CommentStmt *stmt)
99100
caseTRIGGER:
100101
CommentTrigger(stmt->objname,stmt->comment);
101102
break;
103+
caseSCHEMA:
104+
CommentNamespace(stmt->objname,stmt->comment);
105+
break;
102106
default:
103107
elog(ERROR,"An attempt was made to comment on a unknown type: %d",
104108
stmt->objtype);
@@ -332,22 +336,22 @@ CommentRelation(int objtype, List *relname, char *comment)
332336
{
333337
caseINDEX:
334338
if (relation->rd_rel->relkind!=RELKIND_INDEX)
335-
elog(ERROR,"relation'%s' is not an index",
339+
elog(ERROR,"relation\"%s\" is not an index",
336340
RelationGetRelationName(relation));
337341
break;
338342
caseTABLE:
339343
if (relation->rd_rel->relkind!=RELKIND_RELATION)
340-
elog(ERROR,"relation'%s' is not a table",
344+
elog(ERROR,"relation\"%s\" is not a table",
341345
RelationGetRelationName(relation));
342346
break;
343347
caseVIEW:
344348
if (relation->rd_rel->relkind!=RELKIND_VIEW)
345-
elog(ERROR,"relation'%s' is not a view",
349+
elog(ERROR,"relation\"%s\" is not a view",
346350
RelationGetRelationName(relation));
347351
break;
348352
caseSEQUENCE:
349353
if (relation->rd_rel->relkind!=RELKIND_SEQUENCE)
350-
elog(ERROR,"relation'%s' is not a sequence",
354+
elog(ERROR,"relation\"%s\" is not a sequence",
351355
RelationGetRelationName(relation));
352356
break;
353357
}
@@ -400,7 +404,7 @@ CommentAttribute(List *qualname, char *comment)
400404

401405
attnum=get_attnum(RelationGetRelid(relation),attrname);
402406
if (attnum==InvalidAttrNumber)
403-
elog(ERROR,"'%s' is not an attribute of class'%s'",
407+
elog(ERROR,"\"%s\" is not an attribute of class\"%s\"",
404408
attrname,RelationGetRelationName(relation));
405409

406410
/* Create the comment using the relation's oid */
@@ -451,13 +455,13 @@ CommentDatabase(List *qualname, char *comment)
451455
/* Validate database exists, and fetch the db oid */
452456

453457
if (!HeapTupleIsValid(dbtuple))
454-
elog(ERROR,"database'%s' does not exist",database);
458+
elog(ERROR,"database\"%s\" does not exist",database);
455459
oid=dbtuple->t_data->t_oid;
456460

457461
/* Allow if the user matches the database dba or is a superuser */
458462

459463
if (!(superuser()||is_dbadmin(oid)))
460-
elog(ERROR,"you are not permitted to comment on database'%s'",
464+
elog(ERROR,"you are not permitted to comment on database\"%s\"",
461465
database);
462466

463467
/* Create the comments with the pg_database oid */
@@ -470,6 +474,51 @@ CommentDatabase(List *qualname, char *comment)
470474
heap_close(pg_database,AccessShareLock);
471475
}
472476

477+
/*
478+
* CommentNamespace --
479+
*
480+
* This routine is used to add/drop any user-comments a user might
481+
* have regarding the specified namespace. The routine will check
482+
* security for owner permissions, and, if succesful, will then
483+
* attempt to find the oid of the namespace specified. Once found,
484+
* a comment is added/dropped using the CreateComments() routine.
485+
*/
486+
staticvoid
487+
CommentNamespace(List*qualname,char*comment)
488+
{
489+
Oidoid;
490+
Oidclassoid;
491+
HeapTupletp;
492+
char*namespace;
493+
494+
if (length(qualname)!=1)
495+
elog(ERROR,"CommentSchema: schema name may not be qualified");
496+
namespace=strVal(lfirst(qualname));
497+
498+
tp=SearchSysCache(NAMESPACENAME,
499+
CStringGetDatum(namespace),
500+
0,0,0);
501+
if (!HeapTupleIsValid(tp))
502+
elog(ERROR,"CommentSchema: Schema \"%s\" could not be found",
503+
namespace);
504+
505+
oid=tp->t_data->t_oid;
506+
507+
/* Check object security */
508+
if (!pg_namespace_ownercheck(oid,GetUserId()))
509+
aclcheck_error(ACLCHECK_NOT_OWNER,namespace);
510+
511+
/* pg_namespace doesn't have a hard-coded OID, so must look it up */
512+
classoid=get_relname_relid(NamespaceRelationName,PG_CATALOG_NAMESPACE);
513+
Assert(OidIsValid(classoid));
514+
515+
/* Call CreateComments() to create/drop the comments */
516+
CreateComments(oid,classoid,0,comment);
517+
518+
/* Cleanup */
519+
ReleaseSysCache(tp);
520+
}
521+
473522
/*
474523
* CommentRule --
475524
*
@@ -528,12 +577,12 @@ CommentRule(List *qualname, char *comment)
528577
}
529578
else
530579
{
531-
elog(ERROR,"rule'%s' does not exist",rulename);
580+
elog(ERROR,"rule\"%s\" does not exist",rulename);
532581
reloid=ruleoid=0;/* keep compiler quiet */
533582
}
534583

535584
if (HeapTupleIsValid(tuple=heap_getnext(scanDesc,0)))
536-
elog(ERROR,"There are multiple rules'%s'"
585+
elog(ERROR,"There are multiple rules\"%s\""
537586
"\n\tPlease specify a relation name as well as a rule name",
538587
rulename);
539588

@@ -561,7 +610,7 @@ CommentRule(List *qualname, char *comment)
561610
PointerGetDatum(rulename),
562611
0,0);
563612
if (!HeapTupleIsValid(tuple))
564-
elog(ERROR,"rule'%s' does not exist",rulename);
613+
elog(ERROR,"rule\"%s\" does not exist",rulename);
565614
Assert(reloid== ((Form_pg_rewrite)GETSTRUCT(tuple))->ev_class);
566615
ruleoid=tuple->t_data->t_oid;
567616
ReleaseSysCache(tuple);
@@ -574,7 +623,6 @@ CommentRule(List *qualname, char *comment)
574623
aclcheck_error(aclcheck,rulename);
575624

576625
/* pg_rewrite doesn't have a hard-coded OID, so must look it up */
577-
578626
classoid=get_relname_relid(RewriteRelationName,PG_CATALOG_NAMESPACE);
579627
Assert(OidIsValid(classoid));
580628

@@ -689,40 +737,30 @@ CommentProc(List *function, List *arguments, char *comment)
689737
* its name and its argument list which defines the left and right
690738
* hand types the operator will operate on. The argument list is
691739
* expected to be a couple of parse nodes pointed to be a List
692-
* object. If the comments string is empty, the associated comment
693-
* is dropped.
694-
*
695-
* NOTE: we actually attach the comment to the procedure that underlies
696-
* the operator. This is a feature, not a bug: we want the same comment
697-
* to be visible for both operator and function.
740+
* object.
698741
*/
699742
staticvoid
700743
CommentOperator(List*opername,List*arguments,char*comment)
701744
{
702745
TypeName*typenode1= (TypeName*)lfirst(arguments);
703746
TypeName*typenode2= (TypeName*)lsecond(arguments);
704747
Oidoid;
748+
Oidclassoid;
705749

706750
/* Look up the operator */
707-
708751
oid=LookupOperNameTypeNames(opername,typenode1,typenode2,
709752
"CommentOperator");
710753

711754
/* Valid user's ability to comment on this operator */
712-
713755
if (!pg_oper_ownercheck(oid,GetUserId()))
714756
aclcheck_error(ACLCHECK_NOT_OWNER,NameListToString(opername));
715757

716-
/* Get the procedure associated with the operator */
717-
718-
oid=get_opcode(oid);
719-
if (oid==InvalidOid)
720-
elog(ERROR,"operator '%s' does not have an underlying function",
721-
NameListToString(opername));
758+
/* pg_operator doesn't have a hard-coded OID, so must look it up */
759+
classoid=get_relname_relid(OperatorRelationName,PG_CATALOG_NAMESPACE);
760+
Assert(OidIsValid(classoid));
722761

723762
/* Call CreateComments() to create/drop the comments */
724-
725-
CreateComments(oid,RelOid_pg_proc,0,comment);
763+
CreateComments(oid,classoid,0,comment);
726764
}
727765

728766
/*
@@ -784,7 +822,7 @@ CommentTrigger(List *qualname, char *comment)
784822
/* If no trigger exists for the relation specified, notify user */
785823

786824
if (!HeapTupleIsValid(triggertuple))
787-
elog(ERROR,"trigger'%s' for relation'%s' does not exist",
825+
elog(ERROR,"trigger\"%s\" for relation\"%s\" does not exist",
788826
trigname,RelationGetRelationName(relation));
789827

790828
oid=triggertuple->t_data->t_oid;

‎src/backend/parser/gram.y

Lines changed: 2 additions & 1 deletion
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.314 2002/05/12 20:10:04 tgl Exp $
14+
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.315 2002/05/13 17:45:30 tgl Exp $
1515
*
1616
* HISTORY
1717
* AUTHORDATEMAJOR EVENT
@@ -2278,6 +2278,7 @@ CommentStmt:COMMENT ON comment_type any_name IS comment_text
22782278

22792279
comment_type:COLUMN {$$ = COLUMN; }
22802280
|DATABASE {$$ = DATABASE; }
2281+
|SCHEMA {$$ = SCHEMA; }
22812282
|INDEX {$$ = INDEX; }
22822283
|SEQUENCE {$$ = SEQUENCE; }
22832284
|TABLE {$$ = TABLE; }

‎src/bin/pg_dump/pg_dump.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
*
2323
*
2424
* IDENTIFICATION
25-
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.259 2002/05/10 22:36:26 tgl Exp $
25+
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.260 2002/05/13 17:45:30 tgl Exp $
2626
*
2727
*-------------------------------------------------------------------------
2828
*/
@@ -2686,15 +2686,13 @@ dumpNamespaces(Archive *fout, NamespaceInfo *nsinfo, int numNamespaces)
26862686
nsinfo[i].usename,"SCHEMA",NULL,
26872687
q->data,delq->data,NULL,NULL,NULL);
26882688

2689-
#ifdefNOTYET/* suppress till COMMENT ON SCHEMA works */
26902689
/*** Dump Schema Comments ***/
26912690
resetPQExpBuffer(q);
26922691
appendPQExpBuffer(q,"SCHEMA %s",
26932692
fmtId(nsinfo[i].nspname,force_quotes));
26942693
dumpComment(fout,q->data,
26952694
NULL,nsinfo[i].usename,
26962695
nsinfo[i].oid,"pg_namespace",0,NULL);
2697-
#endif
26982696
}
26992697

27002698
destroyPQExpBuffer(q);
@@ -3396,7 +3394,7 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
33963394
/*** Dump Function Comments ***/
33973395

33983396
resetPQExpBuffer(q);
3399-
appendPQExpBuffer(q,"FUNCTION %s",fn->data);
3397+
appendPQExpBuffer(q,"FUNCTION %s",fn->data);
34003398
dumpComment(fout,q->data,
34013399
finfo->pronamespace->nspname,finfo->usename,
34023400
finfo->oid,"pg_proc",0,NULL);
@@ -3655,11 +3653,13 @@ dumpOneOpr(Archive *fout, OprInfo *oprinfo,
36553653
q->data,delq->data,
36563654
NULL,NULL,NULL);
36573655

3658-
/*
3659-
* Note: no need to dump operator comment; we expect that the comment
3660-
* is attached to the underlying function instead. (If the function
3661-
* isn't getting dumped ... you lose.)
3662-
*/
3656+
/*** Dump Operator Comments ***/
3657+
3658+
resetPQExpBuffer(q);
3659+
appendPQExpBuffer(q,"OPERATOR %s",oprid->data);
3660+
dumpComment(fout,q->data,
3661+
oprinfo->oprnamespace->nspname,oprinfo->usename,
3662+
oprinfo->oid,"pg_operator",0,NULL);
36633663

36643664
PQclear(res);
36653665

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp