? src/include/catalog/pg_shdescription.h Index: doc/src/sgml/catalogs.sgml =================================================================== RCS file: /projects/cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v retrieving revision 2.115 diff -c -r2.115 catalogs.sgml *** doc/src/sgml/catalogs.sgml 4 Nov 2005 23:13:59 -0000 2.115 --- doc/src/sgml/catalogs.sgml 14 Dec 2005 21:47:35 -0000 *************** *** 189,194 **** --- 189,199 ---- + pg_shdescription + comments on shared objects + + + pg_statistic planner statistics *************** *** 2229,2234 **** --- 2234,2245 ---- contents of pg_description. + + See also pg_shdescription, + which performs a similar function for descriptions involving objects that + are shared across a database cluster. + + <structname>pg_description</> Columns *************** *** 3610,3615 **** --- 3621,3693 ---- + + <structname>pg_shdescription</structname> + + + pg_shdescription + + + + The catalog pg_shdescription stores optional + descriptions (comments) for shared database objects. Descriptions can + be manipulated with the COMMENT command and viewed + with psql's \d commands. + + + + See also pg_description, + which performs a similar function for descriptions involving objects + within a single database. + + + + Unlike most system catalogs, pg_shdescription + is shared across all databases of a cluster: there is only one + copy of pg_shdescription per cluster, not + one per database. + + +
+ <structname>pg_shdescription</> Columns + + + + + Name + Type + References + Description + + + + + + objoid + oid + any OID column + The OID of the object this description pertains to + + + + classoid + oid + pg_class.oid + The OID of the system catalog this object appears in + + + + description + text + + Arbitrary text that servers as the description of this object. + + + +
+ + + <structname>pg_statistic</structname> Index: doc/src/sgml/func.sgml =================================================================== RCS file: /projects/cvsroot/pgsql/doc/src/sgml/func.sgml,v retrieving revision 1.298 diff -c -r1.298 func.sgml *** doc/src/sgml/func.sgml 11 Dec 2005 10:54:27 -0000 1.298 --- doc/src/sgml/func.sgml 14 Dec 2005 21:47:36 -0000 *************** *** 9316,9321 **** --- 9316,9325 ---- + shobj_description + + + comment about database objects *************** *** 9351,9356 **** --- 9355,9365 ---- text get comment for a table column + + shobj_description(object_oid, catalog_name) + text + get comment for a shared database object + *************** *** 9373,9378 **** --- 9382,9395 ---- obj_description cannot be used for table columns since columns do not have OIDs of their own. + + + shobj_description is used just like + obj_description only that it is used for retrieving + comments on shared objects. Some system catalogs are global to all + databases within each cluster and their descriptions are stored globally + as well. + Index: doc/src/sgml/ref/comment.sgml =================================================================== RCS file: /projects/cvsroot/pgsql/doc/src/sgml/ref/comment.sgml,v retrieving revision 1.29 diff -c -r1.29 comment.sgml *** doc/src/sgml/ref/comment.sgml 8 Jun 2005 21:15:27 -0000 1.29 --- doc/src/sgml/ref/comment.sgml 14 Dec 2005 21:47:36 -0000 *************** *** 36,44 **** --- 36,46 ---- OPERATOR op (leftoperand_type, rightoperand_type) | OPERATOR CLASS object_name USING index_method | [ PROCEDURAL ] LANGUAGE object_name | + ROLE object_name | RULE rule_name ON table_name | SCHEMA object_name | SEQUENCE object_name | + TABLESPACE object_name | TRIGGER trigger_name ON table_name | TYPE object_name | VIEW object_name *************** *** 67,73 **** \dd, \d+, and \l+. Other user interfaces to retrieve comments can be built atop the same built-in functions that psql uses, namely ! obj_description and col_description (see ). --- 69,76 ---- \dd, \d+, and \l+. Other user interfaces to retrieve comments can be built atop the same built-in functions that psql uses, namely ! obj_description, col_description, ! and shobj_description (see ). *************** *** 198,213 **** Notes - A comment for a database can only be created in that database, - and will only be visible in that database, not in other databases. - - - There is presently no security mechanism for comments: any user connected to a database can see all the comments for objects in that database (although only superusers can change comments for ! objects that they don't own). Therefore, don't put ! security-critical information in comments. --- 201,214 ---- Notes There is presently no security mechanism for comments: any user connected to a database can see all the comments for objects in that database (although only superusers can change comments for ! objects that they don't own). For shared objects such as ! databases, roles, and tablespaces comments are stored gloablly ! and any user connected to any database can see all the comments ! for shared objects. Therefore, don't put security-critical ! information in comments. *************** *** 245,254 **** --- 246,257 ---- COMMENT ON OPERATOR ^ (text, text) IS 'Performs intersection of two texts'; COMMENT ON OPERATOR - (NONE, text) IS 'This is a prefix operator on text'; COMMENT ON OPERATOR CLASS int4ops USING btree IS '4 byte integer operators for btrees'; + COMMENT ON ROLE my_role IS 'Administration group for finance tables'; COMMENT ON RULE my_rule ON my_table IS 'Logs updates of employee records'; COMMENT ON SCHEMA my_schema IS 'Departmental data'; COMMENT ON SEQUENCE my_sequence IS 'Used to generate primary keys'; COMMENT ON TABLE my_schema.my_table IS 'Employee Information'; + COMMENT ON TABLESPACE my_tablespace IS 'Tablespace for indexes'; COMMENT ON TRIGGER my_trigger ON my_table IS 'Used for RI'; COMMENT ON TYPE complex IS 'Complex number data type'; COMMENT ON VIEW my_view IS 'View of departmental costs'; Index: src/backend/catalog/Makefile =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/catalog/Makefile,v retrieving revision 1.58 diff -c -r1.58 Makefile *** src/backend/catalog/Makefile 9 Dec 2005 21:19:35 -0000 1.58 --- src/backend/catalog/Makefile 14 Dec 2005 21:47:36 -0000 *************** *** 15,21 **** pg_largeobject.o pg_namespace.o pg_operator.o pg_proc.o pg_shdepend.o \ pg_type.o ! BKIFILES = postgres.bki postgres.description all: SUBSYS.o $(BKIFILES) --- 15,21 ---- pg_largeobject.o pg_namespace.o pg_operator.o pg_proc.o pg_shdepend.o \ pg_type.o ! BKIFILES = postgres.bki postgres.description postgres.shdescription all: SUBSYS.o $(BKIFILES) *************** *** 34,40 **** pg_rewrite.h pg_trigger.h pg_listener.h pg_description.h pg_cast.h \ pg_namespace.h pg_conversion.h pg_depend.h \ pg_database.h pg_tablespace.h pg_pltemplate.h \ ! pg_authid.h pg_auth_members.h pg_shdepend.h \ indexing.h \ ) --- 34,40 ---- pg_rewrite.h pg_trigger.h pg_listener.h pg_description.h pg_cast.h \ pg_namespace.h pg_conversion.h pg_depend.h \ pg_database.h pg_tablespace.h pg_pltemplate.h \ ! pg_authid.h pg_auth_members.h pg_shdepend.h pg_shdescription.h \ indexing.h \ ) *************** *** 43,48 **** --- 43,50 ---- # see explanation in ../parser/Makefile postgres.description: postgres.bki ; + postgres.shdescription: postgres.bki ; + postgres.bki: genbki.sh $(POSTGRES_BKI_SRCS) \ $(top_srcdir)/src/include/postgres_ext.h $(top_builddir)/src/include/pg_config_manual.h AWK='$(AWK)' $(SHELL) $< $(pg_includes) --set-version=$(VERSION) -o postgres $(POSTGRES_BKI_SRCS) *************** *** 51,56 **** --- 53,59 ---- install-data: $(BKIFILES) installdirs $(INSTALL_DATA) postgres.bki '$(DESTDIR)$(datadir)/postgres.bki' $(INSTALL_DATA) postgres.description '$(DESTDIR)$(datadir)/postgres.description' + $(INSTALL_DATA) postgres.shdescription '$(DESTDIR)$(datadir)/postgres.shdescription' $(INSTALL_DATA) $(srcdir)/system_views.sql '$(DESTDIR)$(datadir)/system_views.sql' $(INSTALL_DATA) $(srcdir)/information_schema.sql '$(DESTDIR)$(datadir)/information_schema.sql' $(INSTALL_DATA) $(srcdir)/sql_features.txt '$(DESTDIR)$(datadir)/sql_features.txt' Index: src/backend/catalog/genbki.sh =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/catalog/genbki.sh,v retrieving revision 1.37 diff -c -r1.37 genbki.sh *** src/backend/catalog/genbki.sh 28 Jun 2005 05:08:52 -0000 1.37 --- src/backend/catalog/genbki.sh 14 Dec 2005 21:47:36 -0000 *************** *** 103,109 **** TMPFILE="genbkitmp$$.c" ! trap "rm -f $TMPFILE ${OUTPUT_PREFIX}.bki.$$ ${OUTPUT_PREFIX}.description.$$" 0 1 2 3 15 # Get NAMEDATALEN from postgres_ext.h --- 103,109 ---- TMPFILE="genbkitmp$$.c" ! trap "rm -f $TMPFILE ${OUTPUT_PREFIX}.bki.$$ ${OUTPUT_PREFIX}.description.$$ ${OUTPUT_PREFIX}.shdescription.$$" 0 1 2 3 15 # Get NAMEDATALEN from postgres_ext.h *************** *** 131,136 **** --- 131,137 ---- done touch ${OUTPUT_PREFIX}.description.$$ + touch ${OUTPUT_PREFIX}.shdescription.$$ # ---------------- # Strip comments and other trash from .h *************** *** 201,207 **** # ---------------- # DATA() statements are basically passed right through after # stripping off the DATA( and the ) on the end. ! # Remember the OID for use by DESCR(). # ---------------- /^DATA\(/ { data = substr($0, 6, length($0) - 6); --- 202,208 ---- # ---------------- # DATA() statements are basically passed right through after # stripping off the DATA( and the ) on the end. ! # Remember the OID for use by DESCR() and SHDESCR(). # ---------------- /^DATA\(/ { data = substr($0, 6, length($0) - 6); *************** *** 225,230 **** --- 226,241 ---- next; } + /^SHDESCR\(/ { + if (oid != 0) + { + data = substr($0, 10, length($0) - 11); + if (data != "") + printf "%d\t%s\t%s\n", oid, catalog, data >>shdescriptionfile; + } + next; + } + /^DECLARE_INDEX\(/ { # ---- # end any prior catalog data insertions before starting a define index *************** *** 365,371 **** reln_open = 0; } } ! ' "descriptionfile=${OUTPUT_PREFIX}.description.$$" > $TMPFILE || exit echo "# PostgreSQL $major_version" >${OUTPUT_PREFIX}.bki.$$ --- 376,382 ---- reln_open = 0; } } ! ' "descriptionfile=${OUTPUT_PREFIX}.description.$$" "shdescriptionfile=${OUTPUT_PREFIX}.shdescription.$$" > $TMPFILE || exit echo "# PostgreSQL $major_version" >${OUTPUT_PREFIX}.bki.$$ *************** *** 386,395 **** --- 397,411 ---- echo "$CMDNAME: something seems to be wrong with the .description file" >&2 exit 1 fi + if [ `wc -c < ${OUTPUT_PREFIX}.shdescription.$$` -lt 10 ]; then + echo "$CMDNAME: something seems to be wrong with the .shdescription file" >&2 + exit 1 + fi # Looks good, commit ... mv ${OUTPUT_PREFIX}.bki.$$ ${OUTPUT_PREFIX}.bki || exit mv ${OUTPUT_PREFIX}.description.$$ ${OUTPUT_PREFIX}.description || exit + mv ${OUTPUT_PREFIX}.shdescription.$$ ${OUTPUT_PREFIX}.shdescription || exit exit 0 Index: src/backend/commands/comment.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/comment.c,v retrieving revision 1.85 diff -c -r1.85 comment.c *** src/backend/commands/comment.c 22 Nov 2005 18:17:08 -0000 1.85 --- src/backend/commands/comment.c 14 Dec 2005 21:47:36 -0000 *************** *** 18,23 **** --- 18,24 ---- #include "access/heapam.h" #include "catalog/indexing.h" #include "catalog/namespace.h" + #include "catalog/pg_authid.h" #include "catalog/pg_cast.h" #include "catalog/pg_constraint.h" #include "catalog/pg_conversion.h" *************** *** 30,39 **** --- 31,43 ---- #include "catalog/pg_operator.h" #include "catalog/pg_proc.h" #include "catalog/pg_rewrite.h" + #include "catalog/pg_shdescription.h" + #include "catalog/pg_tablespace.h" #include "catalog/pg_trigger.h" #include "catalog/pg_type.h" #include "commands/comment.h" #include "commands/dbcommands.h" + #include "commands/tablespace.h" #include "miscadmin.h" #include "parser/parse_func.h" #include "parser/parse_oper.h" *************** *** 70,75 **** --- 74,81 ---- static void CommentOpClass(List *qualname, List *arguments, char *comment); static void CommentLargeObject(List *qualname, char *comment); static void CommentCast(List *qualname, List *arguments, char *comment); + static void CommentTablespace(List *qualname, char *comment); + static void CommentRole(List *qualname, char *comment); /* *************** *** 134,139 **** --- 140,151 ---- case OBJECT_CAST: CommentCast(stmt->objname, stmt->objargs, stmt->comment); break; + case OBJECT_TABLESPACE: + CommentTablespace(stmt->objname, stmt->comment); + break; + case OBJECT_ROLE: + CommentRole(stmt->objname, stmt->comment); + break; default: elog(ERROR, "unrecognized object type: %d", (int) stmt->objtype); *************** *** 241,246 **** --- 253,352 ---- } /* + * CreateSharedComments -- + * + * Create a comment for the specified shared object descriptor. Inserts a + * new pg_shdescription tuple, or replaces an existing one with the same key. + * + * If the comment given is null or an empty string, instead delete any + * existing comment for the specified key. + */ + void CreateSharedComments(Oid oid, Oid classoid, char *comment) + { + Relation shdescription; + ScanKeyData skey[2]; + SysScanDesc sd; + HeapTuple oldtuple; + HeapTuple newtuple = NULL; + Datum values[Natts_pg_shdescription]; + char nulls[Natts_pg_shdescription]; + char replaces[Natts_pg_shdescription]; + int i; + + /* Reduce empty-string to NULL case */ + if (comment != NULL && strlen(comment) == 0) + comment = NULL; + + /* Prepare to form or update a tuple, if necessary */ + if (comment != NULL) + { + for (i = 0; i < Natts_pg_shdescription; i++) + { + nulls[i] = ' '; + replaces[i] = 'r'; + } + i = 0; + values[i++] = ObjectIdGetDatum(oid); + values[i++] = ObjectIdGetDatum(classoid); + values[i++] = DirectFunctionCall1(textin, CStringGetDatum(comment)); + } + + /* Use the index to search for a matching old tuple */ + + ScanKeyInit(&skey[0], + Anum_pg_shdescription_objoid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(oid)); + ScanKeyInit(&skey[1], + Anum_pg_shdescription_classoid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(classoid)); + + shdescription = heap_open(SharedDescriptionRelationId, RowExclusiveLock); + + sd = systable_beginscan(shdescription, SharedDescriptionObjIndexId, true, + SnapshotNow, 2, skey); + + while ((oldtuple = systable_getnext(sd)) != NULL) + { + /* Found the old tuple, so delete or update it */ + + if (comment == NULL) + simple_heap_delete(shdescription, &oldtuple->t_self); + else + { + newtuple = heap_modifytuple(oldtuple, RelationGetDescr(shdescription), + values, nulls, replaces); + simple_heap_update(shdescription, &oldtuple->t_self, newtuple); + } + + break; /* Assume there can be only one match */ + } + + systable_endscan(sd); + + /* If we didn't find an old tuple, insert a new one */ + + if (newtuple == NULL && comment != NULL) + { + newtuple = heap_formtuple(RelationGetDescr(shdescription), + values, nulls); + simple_heap_insert(shdescription, newtuple); + } + + /* Update indexes, if necessary */ + if (newtuple != NULL) + { + CatalogUpdateIndexes(shdescription, newtuple); + heap_freetuple(newtuple); + } + + /* Done */ + + heap_close(shdescription, NoLock); + } + + /* * DeleteComments -- remove comments for an object * * If subid is nonzero then only comments matching it will be removed. *************** *** 293,298 **** --- 399,440 ---- } /* + * DeleteSharedComments -- remove comments for a shared object + */ + void + DeleteSharedComments(Oid oid, Oid classoid) + { + Relation shdescription; + ScanKeyData skey[2]; + SysScanDesc sd; + HeapTuple oldtuple; + + /* Use the index to search for all matching old tuples */ + + ScanKeyInit(&skey[0], + Anum_pg_shdescription_objoid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(oid)); + ScanKeyInit(&skey[1], + Anum_pg_shdescription_classoid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(classoid)); + + shdescription = heap_open(SharedDescriptionRelationId, RowExclusiveLock); + + sd = systable_beginscan(shdescription, SharedDescriptionObjIndexId, true, + SnapshotNow, 2, skey); + + while ((oldtuple = systable_getnext(sd)) != NULL) + simple_heap_delete(shdescription, &oldtuple->t_self); + + /* Done */ + + systable_endscan(sd); + heap_close(shdescription, RowExclusiveLock); + } + + /* * CommentRelation -- * * This routine is used to add/drop a comment from a relation, where *************** *** 425,431 **** * have regarding the specified database. The routine will check * security for owner permissions, and, if successful, will then * attempt to find the oid of the database specified. Once found, ! * a comment is added/dropped using the CreateComments() routine. */ static void CommentDatabase(List *qualname, char *comment) --- 567,573 ---- * have regarding the specified database. The routine will check * security for owner permissions, and, if successful, will then * attempt to find the oid of the database specified. Once found, ! * a comment is added/dropped using the CreateSharedComments() routine. */ static void CommentDatabase(List *qualname, char *comment) *************** *** 440,450 **** database = strVal(linitial(qualname)); /* - * We cannot currently support cross-database comments (since other DBs - * cannot see pg_description of this database). So, we reject attempts to - * comment on a database other than the current one. Someday this might be - * improved, but it would take a redesigned infrastructure. - * * When loading a dump, we may see a COMMENT ON DATABASE for the old name * of the database. Erroring out would prevent pg_restore from completing * (which is really pg_restore's fault, but for now we will work around --- 582,587 ---- *************** *** 462,484 **** return; } ! /* Only allow comments on the current database */ ! if (oid != MyDatabaseId) { ! ereport(WARNING, /* throw just a warning so pg_restore doesn't ! * fail */ ! (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), ! errmsg("database comments may only be applied to the current database"))); return; } /* Check object security */ ! if (!pg_database_ownercheck(oid, GetUserId())) ! aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE, ! database); ! /* Call CreateComments() to create/drop the comments */ ! CreateComments(oid, DatabaseRelationId, 0, comment); } /* --- 599,681 ---- return; } ! /* Check object security */ ! if (!pg_database_ownercheck(oid, GetUserId())) ! aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE, ! database); ! ! /* Call CreateSharedComments() to create/drop the comments */ ! CreateSharedComments(oid, DatabaseRelationId, comment); ! } ! ! /* ! * CommentTablespace -- ! * ! * This routine is used to add/drop any user-comments a user might ! * have regarding a tablespace. The tablepace is specified by name ! * and, if found, and the user has appropriate permissions, a ! * comment will be added/dropped using the CreateSharedComments() routine. ! * ! */ ! static void ! CommentTablespace(List *qualname, char *comment) ! { ! char *tablespace; ! Oid oid; ! ! if (list_length(qualname) != 1) ! ereport(ERROR, ! (errcode(ERRCODE_SYNTAX_ERROR), ! errmsg("tablespace name may not be qualified"))); ! tablespace = strVal(linitial(qualname)); ! ! oid = get_tablespace_oid(tablespace); ! if (!OidIsValid(oid)) { ! ereport(ERROR, ! (errcode(ERRCODE_UNDEFINED_OBJECT), ! errmsg("tablespace \"%s\" does not exist", tablespace))); return; } /* Check object security */ ! if (!pg_tablespace_ownercheck(oid, GetUserId())) ! aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TABLESPACE, tablespace); ! /* Call CreateSharedComments() to create/drop the comments */ ! CreateSharedComments(oid, TableSpaceRelationId, comment); ! } ! ! /* ! * CommentRole -- ! * ! * This routine is used to add/drop any user-comments a user might ! * have regarding a role. The role is specified by name ! * and, if found, and the user has appropriate permissions, a ! * comment will be added/dropped using the CreateSharedComments() routine. ! */ ! static void ! CommentRole(List *qualname, char *comment) ! { ! char *role; ! Oid oid; ! ! if (list_length(qualname) != 1) ! ereport(ERROR, ! (errcode(ERRCODE_SYNTAX_ERROR), ! errmsg("role name may not be qualified"))); ! role = strVal(linitial(qualname)); ! ! oid = get_roleid_checked(role); ! ! /* Check object security */ ! if (!has_privs_of_role(GetUserId(), oid)) ! ereport(ERROR, ! (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), ! errmsg("must be member of role \"%s\" to comment upon it", role))); ! ! /* Call CreateSharedComments() to create/drop the comments */ ! CreateSharedComments(oid, AuthIdRelationId, comment); } /* Index: src/backend/commands/dbcommands.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/dbcommands.c,v retrieving revision 1.175 diff -c -r1.175 dbcommands.c *** src/backend/commands/dbcommands.c 22 Nov 2005 18:17:08 -0000 1.175 --- src/backend/commands/dbcommands.c 14 Dec 2005 21:47:36 -0000 *************** *** 658,667 **** /* * Delete any comments associated with the database * - * NOTE: this is probably dead code since any such comments should have - * been in that database, not mine. */ ! DeleteComments(db_id, DatabaseRelationId, 0); /* * Remove shared dependency references for the database. --- 658,665 ---- /* * Delete any comments associated with the database * */ ! DeleteSharedComments(db_id, DatabaseRelationId); /* * Remove shared dependency references for the database. Index: src/backend/commands/tablespace.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/tablespace.c,v retrieving revision 1.28 diff -c -r1.28 tablespace.c *** src/backend/commands/tablespace.c 15 Oct 2005 02:49:15 -0000 1.28 --- src/backend/commands/tablespace.c 14 Dec 2005 21:47:36 -0000 *************** *** 444,449 **** --- 444,454 ---- heap_endscan(scandesc); /* + * Remove any comments on this tablespace. + */ + DeleteSharedComments(tablespaceoid, TableSpaceRelationId); + + /* * Remove dependency on owner. */ deleteSharedDependencyRecordsFor(TableSpaceRelationId, tablespaceoid); Index: src/backend/commands/user.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/user.c,v retrieving revision 1.166 diff -c -r1.166 user.c *** src/backend/commands/user.c 22 Nov 2005 18:17:09 -0000 1.166 --- src/backend/commands/user.c 14 Dec 2005 21:47:36 -0000 *************** *** 18,23 **** --- 18,24 ---- #include "catalog/indexing.h" #include "catalog/pg_auth_members.h" #include "catalog/pg_authid.h" + #include "commands/comment.h" #include "commands/user.h" #include "libpq/crypt.h" #include "miscadmin.h" *************** *** 921,926 **** --- 922,932 ---- systable_endscan(sscan); /* + * Remove any comments on this role. + */ + DeleteSharedComments(roleid, AuthIdRelationId); + + /* * Advance command counter so that later iterations of this loop will * see the changes already made. This is essential if, for example, * we are trying to drop both a role and one of its direct members --- Index: src/backend/parser/gram.y =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/parser/gram.y,v retrieving revision 2.517 diff -c -r2.517 gram.y *** src/backend/parser/gram.y 11 Dec 2005 10:54:27 -0000 2.517 --- src/backend/parser/gram.y 14 Dec 2005 21:47:36 -0000 *************** *** 2923,2933 **** * * COMMENT ON [ [ DATABASE | DOMAIN | INDEX | SEQUENCE | TABLE | TYPE | VIEW | * CONVERSION | LANGUAGE | OPERATOR CLASS | LARGE OBJECT | ! * CAST ] | * AGGREGATE () | * FUNCTION (arg1, arg2, ...) | * OPERATOR (leftoperand_typ, rightoperand_typ) | * TRIGGER ON | * RULE ON ] * IS 'text' * --- 2923,2934 ---- * * COMMENT ON [ [ DATABASE | DOMAIN | INDEX | SEQUENCE | TABLE | TYPE | VIEW | * CONVERSION | LANGUAGE | OPERATOR CLASS | LARGE OBJECT | ! * CAST | COLUMN | SCHEMA | TABLESPACE | ROLE ] | * AGGREGATE () | * FUNCTION (arg1, arg2, ...) | * OPERATOR (leftoperand_typ, rightoperand_typ) | * TRIGGER ON | + * CONSTRAINT ON | * RULE ON ] * IS 'text' * *************** *** 3058,3063 **** --- 3059,3066 ---- | TYPE_P { $$ = OBJECT_TYPE; } | VIEW { $$ = OBJECT_VIEW; } | CONVERSION_P { $$ = OBJECT_CONVERSION; } + | TABLESPACE { $$ = OBJECT_TABLESPACE; } + | ROLE { $$ = OBJECT_ROLE; } ; comment_text: Index: src/bin/initdb/initdb.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/bin/initdb/initdb.c,v retrieving revision 1.101 diff -c -r1.101 initdb.c *** src/bin/initdb/initdb.c 9 Dec 2005 15:51:14 -0000 1.101 --- src/bin/initdb/initdb.c 14 Dec 2005 21:47:36 -0000 *************** *** 102,107 **** --- 102,108 ---- static char *encodingid = "0"; static char *bki_file; static char *desc_file; + static char *shdesc_file; static char *hba_file; static char *ident_file; static char *conf_file; *************** *** 178,183 **** --- 179,185 ---- static void setup_depend(void); static void setup_sysviews(void); static void setup_description(void); + static void setup_shared_description(void); static void setup_conversion(void); static void setup_privileges(void); static void set_info_version(void); *************** *** 1535,1540 **** --- 1537,1543 ---- "ALTER TABLE pg_description CREATE TOAST TABLE;\n", "ALTER TABLE pg_proc CREATE TOAST TABLE;\n", "ALTER TABLE pg_rewrite CREATE TOAST TABLE;\n", + "ALTER TABLE pg_shdescription CREATE TOAST TABLE;\n", "ALTER TABLE pg_statistic CREATE TOAST TABLE;\n", NULL }; *************** *** 1713,1718 **** --- 1716,1757 ---- } /* + * load shared description data + */ + static void + setup_shared_description(void) + { + PG_CMD_DECL; + + fputs(_("loading pg_shdescription ... "), stdout); + fflush(stdout); + + snprintf(cmd, sizeof(cmd), + "\"%s\" %s template1 >%s", + backend_exec, backend_options, + DEVNULL); + + PG_CMD_OPEN; + + PG_CMD_PUTS("CREATE TEMP TABLE tmp_pg_shdescription ( " + " objoid oid, " + " classname name, " + " description text) WITHOUT OIDS;\n"); + + PG_CMD_PRINTF1("COPY tmp_pg_shdescription FROM '%s';\n", + shdesc_file); + + PG_CMD_PUTS("INSERT INTO pg_shdescription " + " SELECT t.objoid, c.oid, t.description " + " FROM tmp_pg_shdescription t, pg_class c " + " WHERE c.relname = t.classname;\n"); + + PG_CMD_CLOSE; + + check_ok(); + } + + /* * load conversion functions */ static void *************** *** 2532,2537 **** --- 2571,2577 ---- set_input(&bki_file, "postgres.bki"); set_input(&desc_file, "postgres.description"); + set_input(&shdesc_file, "postgres.shdescription"); set_input(&hba_file, "pg_hba.conf.sample"); set_input(&ident_file, "pg_ident.conf.sample"); set_input(&conf_file, "postgresql.conf.sample"); *************** *** 2548,2559 **** "VERSION=%s\n" "PGDATA=%s\nshare_path=%s\nPGPATH=%s\n" "POSTGRES_SUPERUSERNAME=%s\nPOSTGRES_BKI=%s\n" ! "POSTGRES_DESCR=%s\nPOSTGRESQL_CONF_SAMPLE=%s\n" "PG_HBA_SAMPLE=%s\nPG_IDENT_SAMPLE=%s\n", PG_VERSION, pg_data, share_path, bin_path, effective_user, bki_file, ! desc_file, conf_file, hba_file, ident_file); if (show_setting) exit(0); --- 2588,2601 ---- "VERSION=%s\n" "PGDATA=%s\nshare_path=%s\nPGPATH=%s\n" "POSTGRES_SUPERUSERNAME=%s\nPOSTGRES_BKI=%s\n" ! "POSTGRES_DESCR=%s\nPOSTGRES_SHDESCR=%s\n" ! "POSTGRESQL_CONF_SAMPLE=%s\n" "PG_HBA_SAMPLE=%s\nPG_IDENT_SAMPLE=%s\n", PG_VERSION, pg_data, share_path, bin_path, effective_user, bki_file, ! desc_file, shdesc_file, ! conf_file, hba_file, ident_file); if (show_setting) exit(0); *************** *** 2561,2566 **** --- 2603,2609 ---- check_input(bki_file); check_input(desc_file); + check_input(shdesc_file); check_input(hba_file); check_input(ident_file); check_input(conf_file); *************** *** 2758,2763 **** --- 2801,2808 ---- setup_description(); + setup_shared_description(); + setup_conversion(); setup_privileges(); Index: src/bin/pg_dump/pg_dump.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v retrieving revision 1.424 diff -c -r1.424 pg_dump.c *** src/bin/pg_dump/pg_dump.c 3 Dec 2005 21:06:18 -0000 1.424 --- src/bin/pg_dump/pg_dump.c 14 Dec 2005 21:47:36 -0000 *************** *** 1185,1191 **** selectSourceSchema("pg_catalog"); /* Get the database owner and parameters from pg_database */ ! if (g_fout->remoteVersion >= 80000) { appendPQExpBuffer(dbQry, "SELECT tableoid, oid, " "(%s datdba) as dba, " --- 1185,1204 ---- selectSourceSchema("pg_catalog"); /* Get the database owner and parameters from pg_database */ ! if (g_fout->remoteVersion >= 80200) ! { ! appendPQExpBuffer(dbQry, "SELECT tableoid, oid, " ! "(%s datdba) as dba, " ! "pg_encoding_to_char(encoding) as encoding, " ! "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) as tablespace, " ! "shobj_description(oid, 'pg_database') as description " ! ! "FROM pg_database " ! "WHERE datname = ", ! username_subquery); ! appendStringLiteral(dbQry, datname, true); ! } ! else if (g_fout->remoteVersion >= 80000) { appendPQExpBuffer(dbQry, "SELECT tableoid, oid, " "(%s datdba) as dba, " *************** *** 1287,1296 **** NULL); /* Dumper Arg */ /* Dump DB comment if any */ ! resetPQExpBuffer(dbQry); ! appendPQExpBuffer(dbQry, "DATABASE %s", fmtId(datname)); ! dumpComment(AH, dbQry->data, NULL, "", dbCatId, 0, dbDumpId); PQclear(res); --- 1300,1327 ---- NULL); /* Dumper Arg */ /* Dump DB comment if any */ ! if (g_fout->remoteVersion >= 80200) ! { ! /* 8.2 keeps comments on shared objects in a shared table, so ! * we cannot use the dumpComment used for other database objects. ! */ ! char *comment = PQgetvalue(res, 0, PQfnumber(res, "description")); ! if (comment && strlen(comment)) { ! resetPQExpBuffer(dbQry); ! appendPQExpBuffer(dbQry, "COMMENT ON DATABASE %s IS ", fmtId(datname)); ! appendStringLiteral(dbQry, comment, false); ! appendPQExpBuffer(dbQry, ";\n"); ! ! ArchiveEntry(AH, dbCatId, createDumpId(), datname, NULL, NULL, ! dba, false, "COMMENT", dbQry->data, "", NULL, ! &dbDumpId, 1, NULL, NULL); ! } ! } else { ! resetPQExpBuffer(dbQry); ! appendPQExpBuffer(dbQry, "DATABASE %s", fmtId(datname)); ! dumpComment(AH, dbQry->data, NULL, "", dbCatId, 0, dbDumpId); + } PQclear(res); Index: src/bin/pg_dump/pg_dumpall.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/bin/pg_dump/pg_dumpall.c,v retrieving revision 1.69 diff -c -r1.69 pg_dumpall.c *** src/bin/pg_dump/pg_dumpall.c 15 Oct 2005 02:49:39 -0000 1.69 --- src/bin/pg_dump/pg_dumpall.c 14 Dec 2005 21:47:36 -0000 *************** *** 409,424 **** i_rolcanlogin, i_rolconnlimit, i_rolpassword, ! i_rolvaliduntil; int i; /* note: rolconfig is dumped later */ ! if (server_version >= 80100) printfPQExpBuffer(buf, "SELECT rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, rolcatupdate, " "rolcanlogin, rolconnlimit, rolpassword, " ! "rolvaliduntil " "FROM pg_authid"); else printfPQExpBuffer(buf, --- 409,433 ---- i_rolcanlogin, i_rolconnlimit, i_rolpassword, ! i_rolvaliduntil, ! i_rolcomment; int i; /* note: rolconfig is dumped later */ ! if (server_version >= 80200) ! printfPQExpBuffer(buf, ! "SELECT rolname, rolsuper, rolinherit, " ! "rolcreaterole, rolcreatedb, rolcatupdate, " ! "rolcanlogin, rolconnlimit, rolpassword, " ! "rolvaliduntil, " ! "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment " ! "FROM pg_authid"); ! else if (server_version >= 80100) printfPQExpBuffer(buf, "SELECT rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, rolcatupdate, " "rolcanlogin, rolconnlimit, rolpassword, " ! "rolvaliduntil, null as rolcomment " "FROM pg_authid"); else printfPQExpBuffer(buf, *************** *** 432,437 **** --- 441,447 ---- "-1 as rolconnlimit, " "passwd as rolpassword, " "valuntil as rolvaliduntil " + "null as rolcomment " "FROM pg_shadow " "UNION ALL " "SELECT groname as rolname, " *************** *** 444,449 **** --- 454,460 ---- "-1 as rolconnlimit, " "null::text as rolpassword, " "null::abstime as rolvaliduntil " + "null " "FROM pg_group"); res = executeQuery(conn, buf->data); *************** *** 458,463 **** --- 469,475 ---- i_rolconnlimit = PQfnumber(res, "rolconnlimit"); i_rolpassword = PQfnumber(res, "rolpassword"); i_rolvaliduntil = PQfnumber(res, "rolvaliduntil"); + i_rolcomment = PQfnumber(res, "rolcomment"); if (PQntuples(res) > 0) printf("--\n-- Roles\n--\n\n"); *************** *** 523,528 **** --- 535,546 ---- appendPQExpBuffer(buf, ";\n"); + if (!PQgetisnull(res, i, i_rolcomment)) { + appendPQExpBuffer(buf, "COMMENT ON ROLE %s IS ", fmtId(rolename)); + appendStringLiteral(buf, PQgetvalue(res, i, i_rolcomment), true); + appendPQExpBuffer(buf, ";\n"); + } + printf("%s", buf->data); if (server_version >= 70300) *************** *** 652,660 **** * Get all tablespaces except built-in ones (which we assume are named * pg_xxx) */ ! res = executeQuery(conn, "SELECT spcname, " "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, " ! "spclocation, spcacl " "FROM pg_catalog.pg_tablespace " "WHERE spcname NOT LIKE 'pg!_%' ESCAPE '!'"); --- 670,687 ---- * Get all tablespaces except built-in ones (which we assume are named * pg_xxx) */ ! if (server_version >= 80200) ! res = executeQuery(conn, "SELECT spcname, " ! "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, " ! "spclocation, spcacl, " ! "pg_catalog.shobj_description(oid, 'pg_tablespace') " ! "FROM pg_catalog.pg_tablespace " ! "WHERE spcname NOT LIKE 'pg!_%' ESCAPE '!'"); ! else ! res = executeQuery(conn, "SELECT spcname, " "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, " ! "spclocation, spcacl, " ! "null " "FROM pg_catalog.pg_tablespace " "WHERE spcname NOT LIKE 'pg!_%' ESCAPE '!'"); *************** *** 668,673 **** --- 695,701 ---- char *spcowner = PQgetvalue(res, i, 1); char *spclocation = PQgetvalue(res, i, 2); char *spcacl = PQgetvalue(res, i, 3); + char *spccomment = PQgetvalue(res, i, 4); char *fspcname; /* needed for buildACLCommands() */ *************** *** 693,698 **** --- 721,732 ---- exit(1); } + if (spccomment && strlen(spccomment)) { + appendPQExpBuffer(buf, "COMMENT ON TABLESPACE %s IS ", fspcname); + appendStringLiteral(buf, spccomment, true); + appendPQExpBuffer(buf, ";\n"); + } + printf("%s", buf->data); free(fspcname); Index: src/bin/psql/command.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/bin/psql/command.c,v retrieving revision 1.155 diff -c -r1.155 command.c *** src/bin/psql/command.c 8 Dec 2005 21:18:22 -0000 1.155 --- src/bin/psql/command.c 14 Dec 2005 21:47:37 -0000 *************** *** 339,345 **** break; case 'g': /* no longer distinct from \du */ ! success = describeRoles(pattern); break; case 'l': success = do_lo_list(); --- 339,345 ---- break; case 'g': /* no longer distinct from \du */ ! success = describeRoles(pattern, show_verbose); break; case 'l': success = do_lo_list(); *************** *** 364,370 **** success = listTables(&cmd[1], pattern, show_verbose); break; case 'u': ! success = describeRoles(pattern); break; default: --- 364,370 ---- success = listTables(&cmd[1], pattern, show_verbose); break; case 'u': ! success = describeRoles(pattern, show_verbose); break; default: Index: src/bin/psql/describe.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/bin/psql/describe.c,v retrieving revision 1.130 diff -c -r1.130 describe.c *** src/bin/psql/describe.c 22 Nov 2005 18:17:29 -0000 1.130 --- src/bin/psql/describe.c 14 Dec 2005 21:47:37 -0000 *************** *** 127,134 **** if (verbose) appendPQExpBuffer(&buf, ! ",\n spcacl as \"%s\"", ! _("Access privileges")); appendPQExpBuffer(&buf, "\nFROM pg_catalog.pg_tablespace\n"); --- 127,135 ---- if (verbose) appendPQExpBuffer(&buf, ! ",\n spcacl as \"%s\"" ! ",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"", ! _("Access privileges"), _("Description")); appendPQExpBuffer(&buf, "\nFROM pg_catalog.pg_tablespace\n"); *************** *** 362,368 **** _("Encoding")); if (verbose) appendPQExpBuffer(&buf, ! ",\n pg_catalog.obj_description(d.oid, 'pg_database') as \"%s\"", _("Description")); appendPQExpBuffer(&buf, "\nFROM pg_catalog.pg_database d" --- 363,369 ---- _("Encoding")); if (verbose) appendPQExpBuffer(&buf, ! ",\n pg_catalog.shobj_description(d.oid, 'pg_database') as \"%s\"", _("Description")); appendPQExpBuffer(&buf, "\nFROM pg_catalog.pg_database d" *************** *** 1382,1388 **** * Describes roles. Any schema portion of the pattern is ignored. */ bool ! describeRoles(const char *pattern) { PQExpBufferData buf; PGresult *res; --- 1383,1389 ---- * Describes roles. Any schema portion of the pattern is ignored. */ bool ! describeRoles(const char *pattern, bool verbose) { PQExpBufferData buf; PGresult *res; *************** *** 1398,1405 **** " CASE WHEN r.rolconnlimit < 0 THEN CAST('%s' AS pg_catalog.text)\n" " ELSE CAST(r.rolconnlimit AS pg_catalog.text)\n" " END AS \"%s\", \n" ! " ARRAY(SELECT b.rolname FROM pg_catalog.pg_auth_members m JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid) WHERE m.member = r.oid) as \"%s\"\n" ! "FROM pg_catalog.pg_roles r\n", _("Role name"), _("yes"), _("no"), _("Superuser"), _("yes"), _("no"), _("Create role"), --- 1399,1405 ---- " CASE WHEN r.rolconnlimit < 0 THEN CAST('%s' AS pg_catalog.text)\n" " ELSE CAST(r.rolconnlimit AS pg_catalog.text)\n" " END AS \"%s\", \n" ! " ARRAY(SELECT b.rolname FROM pg_catalog.pg_auth_members m JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid) WHERE m.member = r.oid) as \"%s\"", _("Role name"), _("yes"), _("no"), _("Superuser"), _("yes"), _("no"), _("Create role"), *************** *** 1407,1412 **** --- 1407,1418 ---- _("no limit"), _("Connections"), _("Member of")); + if (verbose) + appendPQExpBuffer(&buf, "\n, pg_catalog.shobj_description(r.oid, 'pg_authid') AS \"%s\"", + _("Description")); + + appendPQExpBuffer(&buf, "\nFROM pg_catalog.pg_roles r\n"); + processNamePattern(&buf, pattern, false, false, NULL, "r.rolname", NULL, NULL); Index: src/bin/psql/describe.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/bin/psql/describe.h,v retrieving revision 1.29 diff -c -r1.29 describe.h *** src/bin/psql/describe.h 14 Aug 2005 18:49:30 -0000 1.29 --- src/bin/psql/describe.h 14 Dec 2005 21:47:37 -0000 *************** *** 26,32 **** extern bool describeOperators(const char *pattern); /* \du, \dg */ ! extern bool describeRoles(const char *pattern); /* \z (or \dp) */ extern bool permissionsList(const char *pattern); --- 26,32 ---- extern bool describeOperators(const char *pattern); /* \du, \dg */ ! extern bool describeRoles(const char *pattern, bool verbose); /* \z (or \dp) */ extern bool permissionsList(const char *pattern); Index: src/bin/psql/tab-complete.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/bin/psql/tab-complete.c,v retrieving revision 1.142 diff -c -r1.142 tab-complete.c *** src/bin/psql/tab-complete.c 8 Dec 2005 21:33:58 -0000 1.142 --- src/bin/psql/tab-complete.c 14 Dec 2005 21:47:37 -0000 *************** *** 925,931 **** static const char *const list_COMMENT[] = {"CAST", "CONVERSION", "DATABASE", "INDEX", "LANGUAGE", "RULE", "SCHEMA", "SEQUENCE", "TABLE", "TYPE", "VIEW", "COLUMN", "AGGREGATE", "FUNCTION", ! "OPERATOR", "TRIGGER", "CONSTRAINT", "DOMAIN", "LARGE OBJECT", NULL}; COMPLETE_WITH_LIST(list_COMMENT); } --- 925,932 ---- static const char *const list_COMMENT[] = {"CAST", "CONVERSION", "DATABASE", "INDEX", "LANGUAGE", "RULE", "SCHEMA", "SEQUENCE", "TABLE", "TYPE", "VIEW", "COLUMN", "AGGREGATE", "FUNCTION", ! "OPERATOR", "TRIGGER", "CONSTRAINT", "DOMAIN", "LARGE OBJECT", ! "TABLESPACE", "ROLE", NULL}; COMPLETE_WITH_LIST(list_COMMENT); } Index: src/include/postgres.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/postgres.h,v retrieving revision 1.71 diff -c -r1.71 postgres.h *** src/include/postgres.h 14 Apr 2005 01:38:21 -0000 1.71 --- src/include/postgres.h 14 Dec 2005 21:47:37 -0000 *************** *** 541,546 **** --- 541,547 ---- /* these need to expand into some harmless, repeatable declaration */ #define DATA(x) extern int no_such_variable #define DESCR(x) extern int no_such_variable + #define SHDESCR(x) extern int no_such_variable typedef int4 aclitem; /* PHONY definition for catalog use only */ Index: src/include/catalog/indexing.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/catalog/indexing.h,v retrieving revision 1.92 diff -c -r1.92 indexing.h *** src/include/catalog/indexing.h 15 Oct 2005 02:49:42 -0000 1.92 --- src/include/catalog/indexing.h 14 Dec 2005 21:47:37 -0000 *************** *** 139,144 **** --- 139,146 ---- DECLARE_UNIQUE_INDEX(pg_description_o_c_o_index, 2675, on pg_description using btree(objoid oid_ops, classoid oid_ops, objsubid int4_ops)); #define DescriptionObjIndexId 2675 + DECLARE_UNIQUE_INDEX(pg_shdescription_o_c_index, 2627, on pg_shdescription using btree(objoid oid_ops, classoid oid_ops)); + #define SharedDescriptionObjIndexId 2627 /* This following index is not used for a cache and is not unique */ DECLARE_INDEX(pg_index_indrelid_index, 2678, on pg_index using btree(indrelid oid_ops)); Index: src/include/catalog/pg_database.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/catalog/pg_database.h,v retrieving revision 1.38 diff -c -r1.38 pg_database.h *** src/include/catalog/pg_database.h 15 Oct 2005 02:49:42 -0000 1.38 --- src/include/catalog/pg_database.h 14 Dec 2005 21:47:37 -0000 *************** *** 75,81 **** #define Anum_pg_database_datacl 12 DATA(insert OID = 1 ( template1 PGUID ENCODING t t -1 0 0 0 1663 _null_ _null_ )); ! DESCR("Default template database"); #define TemplateDbOid 1 #endif /* PG_DATABASE_H */ --- 75,81 ---- #define Anum_pg_database_datacl 12 DATA(insert OID = 1 ( template1 PGUID ENCODING t t -1 0 0 0 1663 _null_ _null_ )); ! SHDESCR("Default template database"); #define TemplateDbOid 1 #endif /* PG_DATABASE_H */ Index: src/include/catalog/pg_proc.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/catalog/pg_proc.h,v retrieving revision 1.389 diff -c -r1.389 pg_proc.h *** src/include/catalog/pg_proc.h 17 Nov 2005 22:14:54 -0000 1.389 --- src/include/catalog/pg_proc.h 14 Dec 2005 21:47:37 -0000 *************** *** 1513,1518 **** --- 1513,1520 ---- DESCR("get description for object id and catalog name"); DATA(insert OID = 1216 ( col_description PGNSP PGUID 14 f f t f s 2 25 "26 23" _null_ _null_ _null_ "select description from pg_catalog.pg_description where objoid = $1 and classoid = ''pg_catalog.pg_class''::regclass and objsubid = $2" - _null_ )); DESCR("get description for table column"); + DATA(insert OID = 1993 ( shobj_description PGNSP PGUID 14 f f t f s 2 25 "26 19" _null_ _null_ _null_ "select description from pg_catalog.pg_shdescription where objoid = $1 and classoid = (select oid from pg_catalog.pg_class where relname = $2 and relnamespace = PGNSP)" - _null_ )); + DESCR("get description for object id and shared catalog name"); DATA(insert OID = 1217 ( date_trunc PGNSP PGUID 12 f f t f s 2 1184 "25 1184" _null_ _null_ _null_ timestamptz_trunc - _null_ )); DESCR("truncate timestamp with time zone to specified units"); Index: src/include/commands/comment.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/commands/comment.h,v retrieving revision 1.16 diff -c -r1.16 comment.h *** src/include/commands/comment.h 1 Jan 2005 05:43:09 -0000 1.16 --- src/include/commands/comment.h 14 Dec 2005 21:47:37 -0000 *************** *** 21,27 **** * related routines. CommentObject() implements the SQL "COMMENT ON" * command. DeleteComments() deletes all comments for an object. * CreateComments creates (or deletes, if comment is NULL) a comment ! * for a specific key. *------------------------------------------------------------------ */ --- 21,28 ---- * related routines. CommentObject() implements the SQL "COMMENT ON" * command. DeleteComments() deletes all comments for an object. * CreateComments creates (or deletes, if comment is NULL) a comment ! * for a specific key. There are versions of these two methods for ! * both normal and shared objects. *------------------------------------------------------------------ */ *************** *** 31,34 **** --- 32,39 ---- extern void CreateComments(Oid oid, Oid classoid, int32 subid, char *comment); + extern void DeleteSharedComments(Oid oid, Oid classoid); + + extern void CreateSharedComments(Oid oid, Oid classoid, char *comment); + #endif /* COMMENT_H */ Index: src/test/regress/expected/sanity_check.out =================================================================== RCS file: /projects/cvsroot/pgsql/src/test/regress/expected/sanity_check.out,v retrieving revision 1.29 diff -c -r1.29 sanity_check.out *** src/test/regress/expected/sanity_check.out 8 Sep 2005 20:07:42 -0000 1.29 --- src/test/regress/expected/sanity_check.out 14 Dec 2005 21:47:37 -0000 *************** *** 59,64 **** --- 59,65 ---- pg_proc | t pg_rewrite | t pg_shdepend | t + pg_shdescription | t pg_statistic | t pg_tablespace | t pg_trigger | t *************** *** 68,74 **** shighway | t tenk1 | t tenk2 | t ! (58 rows) -- -- another sanity check: every system catalog that has OIDs should have --- 69,75 ---- shighway | t tenk1 | t tenk2 | t ! (59 rows) -- -- another sanity check: every system catalog that has OIDs should have