From f9a726aa883e1690f66bec535d85b34e1f9ed7e7 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Sun, 12 Feb 2006 03:22:21 +0000 Subject: [PATCH] I've created a new shared catalog table pg_shdescription to store comments on cluster global objects like databases, tablespaces, and roles. It touches a lot of places, but not much in the way of big changes. The only design decision I made was to duplicate the query and manipulation functions rather than to try and have them handle both shared and local comments. I believe this is simpler for the code and not an issue for callers because they know what type of object they are dealing with. This has resulted in a shobj_description function analagous to obj_description and backend functions [Create/Delete]SharedComments mirroring the existing [Create/Delete]Comments functions. pg_shdescription.h goes into src/include/catalog/ Kris Jurka --- doc/src/sgml/catalogs.sgml | 80 ++++++- doc/src/sgml/func.sgml | 19 +- doc/src/sgml/ref/comment.sgml | 21 +- src/backend/catalog/Makefile | 9 +- src/backend/catalog/genbki.sh | 24 ++- src/backend/commands/comment.c | 235 +++++++++++++++++++-- src/backend/commands/dbcommands.c | 6 +- src/backend/commands/tablespace.c | 8 +- src/backend/commands/user.c | 8 +- src/backend/parser/gram.y | 7 +- src/bin/initdb/initdb.c | 51 ++++- src/bin/pg_dump/pg_dump.c | 41 +++- src/bin/pg_dump/pg_dumpall.c | 46 +++- src/bin/psql/command.c | 6 +- src/bin/psql/describe.c | 20 +- src/bin/psql/describe.h | 4 +- src/bin/psql/tab-complete.c | 5 +- src/include/catalog/catversion.h | 4 +- src/include/catalog/indexing.h | 4 +- src/include/catalog/pg_database.h | 4 +- src/include/catalog/pg_proc.h | 4 +- src/include/catalog/pg_shdescription.h | 80 +++++++ src/include/commands/comment.h | 7 +- src/include/postgres.h | 3 +- src/test/regress/expected/sanity_check.out | 3 +- 25 files changed, 617 insertions(+), 82 deletions(-) create mode 100644 src/include/catalog/pg_shdescription.h diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index d9fd64fdfc..69c8213dfd 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -1,6 +1,6 @@ @@ -188,6 +188,11 @@ dependencies on shared objects + + pg_shdescription + comments on shared objects + + pg_statistic planner statistics @@ -2230,6 +2235,12 @@ 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 @@ -3612,6 +3623,73 @@ + + <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> diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index e2c27e1a35..addf2eeb05 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -1,5 +1,5 @@ @@ -9463,6 +9463,10 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); col_description + + shobj_description + + comment about database objects @@ -9499,6 +9503,11 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); text get comment for a table column
+ + shobj_description(object_oid, catalog_name) + text + get comment for a shared database object + @@ -9521,6 +9530,14 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); 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. + diff --git a/doc/src/sgml/ref/comment.sgml b/doc/src/sgml/ref/comment.sgml index f3f425121f..d8c0a3acab 100644 --- a/doc/src/sgml/ref/comment.sgml +++ b/doc/src/sgml/ref/comment.sgml @@ -1,5 +1,5 @@ @@ -36,9 +36,11 @@ COMMENT ON 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,7 +69,8 @@ COMMENT ON \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 + obj_description, col_description, + and shobj_description (see ). @@ -197,17 +200,15 @@ COMMENT ON 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. + 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,10 +246,12 @@ COMMENT ON LARGE OBJECT 346344 IS 'Planning document'; 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'; diff --git a/src/backend/catalog/Makefile b/src/backend/catalog/Makefile index 1f520298b2..635b553dca 100644 --- a/src/backend/catalog/Makefile +++ b/src/backend/catalog/Makefile @@ -2,7 +2,7 @@ # # Makefile for backend/catalog # -# $PostgreSQL: pgsql/src/backend/catalog/Makefile,v 1.58 2005/12/09 21:19:35 petere Exp $ +# $PostgreSQL: pgsql/src/backend/catalog/Makefile,v 1.59 2006/02/12 03:22:17 momjian Exp $ # #------------------------------------------------------------------------- @@ -15,7 +15,7 @@ OBJS = catalog.o dependency.o heap.o index.o indexing.o namespace.o aclchk.o \ pg_largeobject.o pg_namespace.o pg_operator.o pg_proc.o pg_shdepend.o \ pg_type.o -BKIFILES = postgres.bki postgres.description +BKIFILES = postgres.bki postgres.description postgres.shdescription all: SUBSYS.o $(BKIFILES) @@ -34,7 +34,7 @@ POSTGRES_BKI_SRCS := $(addprefix $(top_srcdir)/src/include/catalog/,\ 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_authid.h pg_auth_members.h pg_shdepend.h pg_shdescription.h \ indexing.h \ ) @@ -43,6 +43,8 @@ pg_includes := $(sort -I$(top_srcdir)/src/include -I$(top_builddir)/src/include) # 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,6 +53,7 @@ postgres.bki: genbki.sh $(POSTGRES_BKI_SRCS) \ 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' diff --git a/src/backend/catalog/genbki.sh b/src/backend/catalog/genbki.sh index 9d9b75bde5..4f6b6b2ec6 100644 --- a/src/backend/catalog/genbki.sh +++ b/src/backend/catalog/genbki.sh @@ -11,7 +11,7 @@ # # # IDENTIFICATION -# $PostgreSQL: pgsql/src/backend/catalog/genbki.sh,v 1.37 2005/06/28 05:08:52 tgl Exp $ +# $PostgreSQL: pgsql/src/backend/catalog/genbki.sh,v 1.38 2006/02/12 03:22:17 momjian Exp $ # # NOTES # non-essential whitespace is removed from the generated file. @@ -103,7 +103,7 @@ fi TMPFILE="genbkitmp$$.c" -trap "rm -f $TMPFILE ${OUTPUT_PREFIX}.bki.$$ ${OUTPUT_PREFIX}.description.$$" 0 1 2 3 15 +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,6 +131,7 @@ for dir in $INCLUDE_DIRS; do done touch ${OUTPUT_PREFIX}.description.$$ +touch ${OUTPUT_PREFIX}.shdescription.$$ # ---------------- # Strip comments and other trash from .h @@ -201,7 +202,7 @@ comment_level > 0 { next; } # ---------------- # DATA() statements are basically passed right through after # stripping off the DATA( and the ) on the end. -# Remember the OID for use by DESCR(). +# Remember the OID for use by DESCR() and SHDESCR(). # ---------------- /^DATA\(/ { data = substr($0, 6, length($0) - 6); @@ -225,6 +226,16 @@ comment_level > 0 { next; } 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,7 +376,7 @@ END { reln_open = 0; } } -' "descriptionfile=${OUTPUT_PREFIX}.description.$$" > $TMPFILE || exit +' "descriptionfile=${OUTPUT_PREFIX}.description.$$" "shdescriptionfile=${OUTPUT_PREFIX}.shdescription.$$" > $TMPFILE || exit echo "# PostgreSQL $major_version" >${OUTPUT_PREFIX}.bki.$$ @@ -386,10 +397,15 @@ if [ `wc -c < ${OUTPUT_PREFIX}.description.$$` -lt 10000 ]; then 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 diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c index d0385428db..30b740fca8 100644 --- a/src/backend/commands/comment.c +++ b/src/backend/commands/comment.c @@ -7,7 +7,7 @@ * Copyright (c) 1996-2005, PostgreSQL Global Development Group * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/comment.c,v 1.85 2005/11/22 18:17:08 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/commands/comment.c,v 1.86 2006/02/12 03:22:17 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -18,6 +18,7 @@ #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,10 +31,13 @@ #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,6 +74,8 @@ static void CommentLanguage(List *qualname, char *comment); 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,6 +140,12 @@ CommentObject(CommentStmt *stmt) 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); @@ -240,6 +252,100 @@ CreateComments(Oid oid, Oid classoid, int32 subid, char *comment) heap_close(description, NoLock); } +/* + * 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 * @@ -292,6 +398,42 @@ DeleteComments(Oid oid, Oid classoid, int32 subid) heap_close(description, RowExclusiveLock); } +/* + * 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 -- * @@ -425,7 +567,7 @@ CommentAttribute(List *qualname, char *comment) * 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. + * a comment is added/dropped using the CreateSharedComments() routine. */ static void CommentDatabase(List *qualname, char *comment) @@ -440,11 +582,6 @@ CommentDatabase(List *qualname, char *comment) 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 @@ -462,23 +599,83 @@ CommentDatabase(List *qualname, char *comment) 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); + /* 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); } /* diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index 5be522db86..ea910d7e87 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -15,7 +15,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.175 2005/11/22 18:17:08 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.176 2006/02/12 03:22:17 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -658,10 +658,8 @@ dropdb(const char *dbname, bool missing_ok) /* * 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); + DeleteSharedComments(db_id, DatabaseRelationId); /* * Remove shared dependency references for the database. diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c index 19955dd81e..2cca3fafe0 100644 --- a/src/backend/commands/tablespace.c +++ b/src/backend/commands/tablespace.c @@ -37,7 +37,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.29 2006/01/19 04:45:38 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.30 2006/02/12 03:22:17 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -54,6 +54,7 @@ #include "catalog/indexing.h" #include "catalog/pg_namespace.h" #include "catalog/pg_tablespace.h" +#include "commands/comment.h" #include "commands/tablespace.h" #include "miscadmin.h" #include "storage/fd.h" @@ -428,6 +429,11 @@ DropTableSpace(DropTableSpaceStmt *stmt) heap_endscan(scandesc); + /* + * Remove any comments on this tablespace. + */ + DeleteSharedComments(tablespaceoid, TableSpaceRelationId); + /* * Remove dependency on owner. */ diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index b3aa2ed829..24a5abdecc 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/backend/commands/user.c,v 1.168 2006/02/04 19:06:46 adunstan Exp $ + * $PostgreSQL: pgsql/src/backend/commands/user.c,v 1.169 2006/02/12 03:22:17 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -18,6 +18,7 @@ #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" @@ -940,6 +941,11 @@ DropRole(DropRoleStmt *stmt) 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, diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 19270bcbda..79e4616be1 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.527 2006/02/11 22:17:18 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.528 2006/02/12 03:22:17 momjian Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -2953,11 +2953,12 @@ TruncateStmt: * * COMMENT ON [ [ DATABASE | DOMAIN | INDEX | SEQUENCE | TABLE | TYPE | VIEW | * CONVERSION | LANGUAGE | OPERATOR CLASS | LARGE OBJECT | - * CAST ] | + * CAST | COLUMN | SCHEMA | TABLESPACE | ROLE ] | * AGGREGATE () | * FUNCTION (arg1, arg2, ...) | * OPERATOR (leftoperand_typ, rightoperand_typ) | * TRIGGER ON | + * CONSTRAINT ON | * RULE ON ] * IS 'text' * @@ -3088,6 +3089,8 @@ comment_type: | TYPE_P { $$ = OBJECT_TYPE; } | VIEW { $$ = OBJECT_VIEW; } | CONVERSION_P { $$ = OBJECT_CONVERSION; } + | TABLESPACE { $$ = OBJECT_TABLESPACE; } + | ROLE { $$ = OBJECT_ROLE; } ; comment_text: diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index 4a85dfb24d..e1c7ad30ce 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -42,7 +42,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * Portions taken from FreeBSD. * - * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.108 2006/02/10 22:05:42 tgl Exp $ + * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.109 2006/02/12 03:22:18 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -105,6 +105,7 @@ static const char *progname; 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; @@ -181,6 +182,7 @@ static void unlimit_systables(void); 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); @@ -1574,6 +1576,7 @@ unlimit_systables(void) "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 }; @@ -1751,6 +1754,42 @@ setup_description(void) check_ok(); } +/* + * 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 */ @@ -2702,6 +2741,7 @@ main(int argc, char *argv[]) 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"); @@ -2718,12 +2758,14 @@ main(int argc, char *argv[]) "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" + "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, conf_file, + desc_file, shdesc_file, + conf_file, hba_file, ident_file); if (show_setting) exit(0); @@ -2731,6 +2773,7 @@ main(int argc, char *argv[]) check_input(bki_file); check_input(desc_file); + check_input(shdesc_file); check_input(hba_file); check_input(ident_file); check_input(conf_file); @@ -2918,6 +2961,8 @@ main(int argc, char *argv[]) setup_description(); + setup_shared_description(); + setup_conversion(); setup_privileges(); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 3dffc9b3f4..fb0be000d5 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -12,7 +12,7 @@ * by PostgreSQL * * IDENTIFICATION - * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.427 2006/01/21 02:16:20 momjian Exp $ + * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.428 2006/02/12 03:22:18 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -1185,7 +1185,20 @@ dumpDatabase(Archive *AH) selectSourceSchema("pg_catalog"); /* Get the database owner and parameters from pg_database */ - if (g_fout->remoteVersion >= 80000) + 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,10 +1300,28 @@ dumpDatabase(Archive *AH) NULL); /* Dumper Arg */ /* Dump DB comment if any */ - resetPQExpBuffer(dbQry); - appendPQExpBuffer(dbQry, "DATABASE %s", fmtId(datname)); - dumpComment(AH, dbQry->data, NULL, "", + 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); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index d74e42fba5..a811b6353e 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * - * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.69 2005/10/15 02:49:39 momjian Exp $ + * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.70 2006/02/12 03:22:19 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -409,16 +409,25 @@ dumpRoles(PGconn *conn) i_rolcanlogin, i_rolconnlimit, i_rolpassword, - i_rolvaliduntil; + i_rolvaliduntil, + i_rolcomment; int i; /* note: rolconfig is dumped later */ - if (server_version >= 80100) + if (server_version >= 80200) printfPQExpBuffer(buf, "SELECT rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, rolcatupdate, " "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil " + "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,6 +441,7 @@ dumpRoles(PGconn *conn) "-1 as rolconnlimit, " "passwd as rolpassword, " "valuntil as rolvaliduntil " + "null as rolcomment " "FROM pg_shadow " "UNION ALL " "SELECT groname as rolname, " @@ -444,6 +454,7 @@ dumpRoles(PGconn *conn) "-1 as rolconnlimit, " "null::text as rolpassword, " "null::abstime as rolvaliduntil " + "null " "FROM pg_group"); res = executeQuery(conn, buf->data); @@ -458,6 +469,7 @@ dumpRoles(PGconn *conn) 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,6 +535,12 @@ dumpRoles(PGconn *conn) 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,9 +670,18 @@ dumpTablespaces(PGconn *conn) * Get all tablespaces except built-in ones (which we assume are named * pg_xxx) */ - res = executeQuery(conn, "SELECT spcname, " + if (server_version >= 80200) + res = executeQuery(conn, "SELECT spcname, " "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, " - "spclocation, spcacl " + "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,6 +695,7 @@ dumpTablespaces(PGconn *conn) 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,6 +721,12 @@ dumpTablespaces(PGconn *conn) 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); diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index a095e0321b..8bd2e14f56 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -3,7 +3,7 @@ * * Copyright (c) 2000-2005, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.159 2006/02/12 02:54:30 momjian Exp $ + * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.160 2006/02/12 03:22:19 momjian Exp $ */ #include "postgres_fe.h" #include "command.h" @@ -379,7 +379,7 @@ exec_command(const char *cmd, break; case 'g': /* no longer distinct from \du */ - success = describeRoles(pattern); + success = describeRoles(pattern, show_verbose); break; case 'l': success = do_lo_list(); @@ -404,7 +404,7 @@ exec_command(const char *cmd, success = listTables(&cmd[1], pattern, show_verbose); break; case 'u': - success = describeRoles(pattern); + success = describeRoles(pattern, show_verbose); break; default: diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index 5caf16df8c..17ca722f30 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -3,7 +3,7 @@ * * Copyright (c) 2000-2005, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.130 2005/11/22 18:17:29 momjian Exp $ + * $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.131 2006/02/12 03:22:19 momjian Exp $ */ #include "postgres_fe.h" #include "describe.h" @@ -127,8 +127,9 @@ describeTablespaces(const char *pattern, bool verbose) if (verbose) appendPQExpBuffer(&buf, - ",\n spcacl as \"%s\"", - _("Access privileges")); + ",\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,7 +363,7 @@ listAllDbs(bool verbose) _("Encoding")); if (verbose) appendPQExpBuffer(&buf, - ",\n pg_catalog.obj_description(d.oid, 'pg_database') as \"%s\"", + ",\n pg_catalog.shobj_description(d.oid, 'pg_database') as \"%s\"", _("Description")); appendPQExpBuffer(&buf, "\nFROM pg_catalog.pg_database d" @@ -1382,7 +1383,7 @@ add_tablespace_footer(char relkind, Oid tablespace, char **footers, * Describes roles. Any schema portion of the pattern is ignored. */ bool -describeRoles(const char *pattern) +describeRoles(const char *pattern, bool verbose) { PQExpBufferData buf; PGresult *res; @@ -1398,8 +1399,7 @@ describeRoles(const char *pattern) " 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", + " 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,6 +1407,12 @@ describeRoles(const char *pattern) _("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); diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h index 22528f95a3..6289238736 100644 --- a/src/bin/psql/describe.h +++ b/src/bin/psql/describe.h @@ -3,7 +3,7 @@ * * Copyright (c) 2000-2005, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/psql/describe.h,v 1.29 2005/08/14 18:49:30 tgl Exp $ + * $PostgreSQL: pgsql/src/bin/psql/describe.h,v 1.30 2006/02/12 03:22:19 momjian Exp $ */ #ifndef DESCRIBE_H #define DESCRIBE_H @@ -26,7 +26,7 @@ extern bool describeTypes(const char *pattern, bool verbose); extern bool describeOperators(const char *pattern); /* \du, \dg */ -extern bool describeRoles(const char *pattern); +extern bool describeRoles(const char *pattern, bool verbose); /* \z (or \dp) */ extern bool permissionsList(const char *pattern); diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index fd32a520fd..f77b3a8f43 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -3,7 +3,7 @@ * * Copyright (c) 2000-2005, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.145 2006/02/11 21:55:35 momjian Exp $ + * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.146 2006/02/12 03:22:19 momjian Exp $ */ /*---------------------------------------------------------------------- @@ -925,7 +925,8 @@ psql_completion(char *text, int start, int end) 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}; + "OPERATOR", "TRIGGER", "CONSTRAINT", "DOMAIN", "LARGE OBJECT", + "TABLESPACE", "ROLE", NULL}; COMPLETE_WITH_LIST(list_COMMENT); } diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index dd9dd24866..1c2ac77ea1 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -37,7 +37,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.314 2006/02/11 16:28:56 momjian Exp $ + * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.315 2006/02/12 03:22:19 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 200602111 +#define CATALOG_VERSION_NO 200602112 #endif diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h index 6edbf23873..e8c745f69c 100644 --- a/src/include/catalog/indexing.h +++ b/src/include/catalog/indexing.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/indexing.h,v 1.92 2005/10/15 02:49:42 momjian Exp $ + * $PostgreSQL: pgsql/src/include/catalog/indexing.h,v 1.93 2006/02/12 03:22:19 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -139,6 +139,8 @@ DECLARE_INDEX(pg_depend_reference_index, 2674, on pg_depend using btree(refclass 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, 2397, on pg_shdescription using btree(objoid oid_ops, classoid oid_ops)); +#define SharedDescriptionObjIndexId 2397 /* 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)); diff --git a/src/include/catalog/pg_database.h b/src/include/catalog/pg_database.h index ae81c65c38..a2ec3fd920 100644 --- a/src/include/catalog/pg_database.h +++ b/src/include/catalog/pg_database.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/pg_database.h,v 1.38 2005/10/15 02:49:42 momjian Exp $ + * $PostgreSQL: pgsql/src/include/catalog/pg_database.h,v 1.39 2006/02/12 03:22:19 momjian Exp $ * * NOTES * the genbki.sh script reads this file and generates .bki @@ -75,7 +75,7 @@ typedef FormData_pg_database *Form_pg_database; #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"); +SHDESCR("Default template database"); #define TemplateDbOid 1 #endif /* PG_DATABASE_H */ diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 93e186d5b1..d8700b8759 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.396 2006/02/11 20:39:58 tgl Exp $ + * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.397 2006/02/12 03:22:19 momjian Exp $ * * NOTES * The script catalog/genbki.sh reads this file and generates .bki @@ -1513,6 +1513,8 @@ DATA(insert OID = 1215 ( obj_description PGNSP PGUID 14 f f t f s 2 25 "26 19" 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"); diff --git a/src/include/catalog/pg_shdescription.h b/src/include/catalog/pg_shdescription.h new file mode 100644 index 0000000000..6cc9c77b3d --- /dev/null +++ b/src/include/catalog/pg_shdescription.h @@ -0,0 +1,80 @@ +/*------------------------------------------------------------------------- + * + * pg_shdescription.h + * definition of the system "shared description" relation + * (pg_shdescription) + * + * NOTE: an object is identified by the OID of the row that primarily + * defines the object, plus the OID of the table that that row appears in. + * For example, a database is identified by the OID of its pg_database row + * plus the pg_class OID of table pg_database. This allows unique + * identification of objects without assuming that OIDs are unique + * across tables. + * + * + * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * $PostgreSQL: pgsql/src/include/catalog/pg_shdescription.h,v 1.1 2006/02/12 03:22:21 momjian Exp $ + * + * NOTES + * the genbki.sh script reads this file and generates .bki + * information from the DATA() statements. + * + * XXX do NOT break up DATA() statements into multiple lines! + * the scripts are not as smart as you might think... + * + *------------------------------------------------------------------------- + */ +#ifndef PG_SHDESCRIPTION_H +#define PG_SHDESCRIPTION_H + +/* ---------------- + * postgres.h contains the system type definitions and the + * CATALOG(), BKI_BOOTSTRAP and DATA() sugar words so this file + * can be read by both genbki.sh and the C compiler. + * ---------------- + */ + +/* ---------------- + * pg_shdescription definition. cpp turns this into + * typedef struct FormData_pg_shdescription + * ---------------- + */ +#define SharedDescriptionRelationId 2396 + +CATALOG(pg_shdescription,2396) BKI_SHARED_RELATION BKI_WITHOUT_OIDS +{ + Oid objoid; /* OID of object itself */ + Oid classoid; /* OID of table containing object */ + text description; /* description of object */ +} FormData_pg_shdescription; + +/* ---------------- + * Form_pg_shdescription corresponds to a pointer to a tuple with + * the format of pg_shdescription relation. + * ---------------- + */ +typedef FormData_pg_shdescription *Form_pg_shdescription; + +/* ---------------- + * compiler constants for pg_shdescription + * ---------------- + */ +#define Natts_pg_shdescription 3 +#define Anum_pg_shdescription_objoid 1 +#define Anum_pg_shdescription_classoid 2 +#define Anum_pg_shdescription_description 3 + +/* ---------------- + * initial contents of pg_shdescription + * ---------------- + */ + +/* + * Because the contents of this table are taken from the other *.h files, + * there is no initialization here. The initial contents are extracted + * by genbki.sh and loaded during initdb. + */ + +#endif /* PG_SHDESCRIPTION_H */ diff --git a/src/include/commands/comment.h b/src/include/commands/comment.h index b27113e3ca..7737e7ebae 100644 --- a/src/include/commands/comment.h +++ b/src/include/commands/comment.h @@ -21,7 +21,8 @@ * 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. + * for a specific key. There are versions of these two methods for + * both normal and shared objects. *------------------------------------------------------------------ */ @@ -31,4 +32,8 @@ extern void DeleteComments(Oid oid, Oid classoid, int32 subid); 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 */ diff --git a/src/include/postgres.h b/src/include/postgres.h index 8d1a38941b..10d2ed4c29 100644 --- a/src/include/postgres.h +++ b/src/include/postgres.h @@ -10,7 +10,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1995, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/postgres.h,v 1.72 2006/01/08 21:24:37 tgl Exp $ + * $PostgreSQL: pgsql/src/include/postgres.h,v 1.73 2006/02/12 03:22:19 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -539,6 +539,7 @@ extern int ExceptionalCondition(char *conditionName, char *errorType, /* 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 */ diff --git a/src/test/regress/expected/sanity_check.out b/src/test/regress/expected/sanity_check.out index 250de98595..10edcb3e8c 100644 --- a/src/test/regress/expected/sanity_check.out +++ b/src/test/regress/expected/sanity_check.out @@ -59,6 +59,7 @@ SELECT relname, relhasindex pg_proc | t pg_rewrite | t pg_shdepend | t + pg_shdescription | t pg_statistic | t pg_tablespace | t pg_trigger | t @@ -68,7 +69,7 @@ SELECT relname, relhasindex shighway | t tenk1 | t tenk2 | t -(58 rows) +(59 rows) -- -- another sanity check: every system catalog that has OIDs should have