From 9999f5a10e722c052006886b678995695001958a Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 12 Apr 2002 20:38:31 +0000 Subject: [PATCH] Checking to decide whether relations are system relations now depends on the namespace not the name; pg_ is not a reserved prefix for table names anymore. From Fernando Nasser. --- src/backend/catalog/aclchk.c | 7 +- src/backend/catalog/catalog.c | 125 +++++++++++++++++----- src/backend/catalog/heap.c | 13 ++- src/backend/catalog/index.c | 11 +- src/backend/catalog/namespace.c | 5 +- src/backend/commands/analyze.c | 6 +- src/backend/commands/command.c | 26 ++--- src/backend/commands/creatinh.c | 5 +- src/backend/commands/indexcmds.c | 29 +++-- src/backend/commands/rename.c | 10 +- src/backend/commands/trigger.c | 6 +- src/backend/commands/vacuum.c | 4 +- src/backend/executor/execUtils.c | 4 +- src/backend/optimizer/util/plancat.c | 5 +- src/backend/tcop/utility.c | 20 +--- src/backend/utils/cache/inval.c | 13 ++- src/backend/utils/cache/relcache.c | 6 +- src/include/catalog/catalog.h | 17 ++- src/test/regress/expected/alter_table.out | 3 + src/test/regress/expected/errors.out | 3 - src/test/regress/sql/alter_table.sql | 3 + src/test/regress/sql/errors.sql | 3 - 22 files changed, 198 insertions(+), 126 deletions(-) diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index e440489a34..5f223aab9d 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.64 2002/04/11 19:59:56 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.65 2002/04/12 20:38:17 tgl Exp $ * * NOTES * See acl.h. @@ -726,7 +726,6 @@ pg_class_aclcheck(Oid table_oid, Oid userid, AclMode mode) int32 result; bool usesuper, usecatupd; - char *relname; HeapTuple tuple; Datum aclDatum; bool isNull; @@ -761,9 +760,9 @@ pg_class_aclcheck(Oid table_oid, Oid userid, AclMode mode) * pg_shadow.usecatupd is set. (This is to let superusers protect * themselves from themselves.) */ - relname = NameStr(((Form_pg_class) GETSTRUCT(tuple))->relname); if ((mode & (ACL_INSERT | ACL_UPDATE | ACL_DELETE)) && - !allowSystemTableMods && IsSystemRelationName(relname) && + !allowSystemTableMods && + IsSystemClass((Form_pg_class) GETSTRUCT(tuple)) && !usecatupd) { #ifdef ACLDEBUG diff --git a/src/backend/catalog/catalog.c b/src/backend/catalog/catalog.c index 2a6ddf11ff..6e19877275 100644 --- a/src/backend/catalog/catalog.c +++ b/src/backend/catalog/catalog.c @@ -1,6 +1,7 @@ /*------------------------------------------------------------------------- * * catalog.c + * routines concerned with catalog naming conventions * * * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group @@ -8,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/catalog.c,v 1.44 2001/11/16 23:30:35 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/catalog.c,v 1.45 2002/04/12 20:38:18 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -18,9 +19,9 @@ #include "access/transam.h" #include "catalog/catalog.h" #include "catalog/catname.h" -#include "catalog/pg_type.h" +#include "catalog/pg_namespace.h" #include "miscadmin.h" -#include "utils/lsyscache.h" + /* * relpath - construct path to a relation's file @@ -74,54 +75,121 @@ GetDatabasePath(Oid tblNode) /* - * IsSystemRelationName - * True iff name is the name of a system catalog relation. + * IsSystemRelation + * True iff the relation is a system catalog relation. * - * NB: TOAST relations are considered system relations by this test. + * NB: TOAST relations are considered system relations by this test + * for compatibility with the old IsSystemRelationName function. * This is appropriate in many places but not all. Where it's not, - * also check IsToastRelationName. + * also check IsToastRelation. * - * We now make a new requirement where system catalog relns must begin - * with pg_ while user relns are forbidden to do so. Make the test - * trivial and instantaneous. - * - * XXX this is way bogus. -- pma + * We now just test if the relation is in the system catalog namespace; + * so it's no longer necessary to forbid user relations from having + * names starting with pg_. Now only schema names have the pg_ + * distinction/requirement. */ bool -IsSystemRelationName(const char *relname) +IsSystemRelation(Relation relation) { - /* ugly coding for speed */ - return (relname[0] == 'p' && - relname[1] == 'g' && - relname[2] == '_'); + return IsSystemNamespace(RelationGetNamespace(relation)) || + IsToastNamespace(RelationGetNamespace(relation)); } /* - * IsToastRelationName - * True iff name is the name of a TOAST support relation (or index). + * IsSystemClass + * Like the above, but takes a Form_pg_class as argument. + * Used when we do not want to open the relation and have to + * search pg_class directly. */ bool -IsToastRelationName(const char *relname) +IsSystemClass(Form_pg_class reltuple) { - return strncmp(relname, "pg_toast_", 9) == 0; + Oid relnamespace = reltuple->relnamespace; + + return IsSystemNamespace(relnamespace) || + IsToastNamespace(relnamespace); +} + +/* + * IsToastRelation + * True iff relation is a TOAST support relation (or index). + */ +bool +IsToastRelation(Relation relation) +{ + return IsToastNamespace(RelationGetNamespace(relation)); +} + +/* + * IsToastClass + * Like the above, but takes a Form_pg_class as argument. + * Used when we do not want to open the relation and have to + * search pg_class directly. + */ +bool +IsToastClass(Form_pg_class reltuple) +{ + Oid relnamespace = reltuple->relnamespace; + + return IsToastNamespace(relnamespace); +} + +/* + * IsSystemNamespace + * True iff namespace is pg_catalog. + * + * NOTE: the reason this isn't a macro is to avoid having to include + * catalog/pg_namespace.h in a lot of places. + */ +bool +IsSystemNamespace(Oid namespaceId) +{ + return namespaceId == PG_CATALOG_NAMESPACE; +} + +/* + * IsToastNamespace + * True iff namespace is pg_toast. + * + * NOTE: the reason this isn't a macro is to avoid having to include + * catalog/pg_namespace.h in a lot of places. + */ +bool +IsToastNamespace(Oid namespaceId) +{ + return namespaceId == PG_TOAST_NAMESPACE; +} + + +/* + * IsReservedName + * True iff name starts with the pg_ prefix. + * + * For some classes of objects, the prefix pg_ is reserved + * for system objects only. + */ +bool +IsReservedName(const char *name) +{ + /* ugly coding for speed */ + return (name[0] == 'p' && + name[1] == 'g' && + name[2] == '_'); } /* * IsSharedSystemRelationName * True iff name is the name of a shared system catalog relation. + * + * Note: This function assumes that this is a system relation + * in the first place. If that is not known, check the namespace + * (with IsSystemNamespace) before calling this function. */ bool IsSharedSystemRelationName(const char *relname) { int i; - /* - * Quick out: if it's not a system relation, it can't be a shared - * system relation. - */ - if (!IsSystemRelationName(relname)) - return FALSE; - i = 0; while (SharedSystemRelationNames[i] != NULL) { @@ -132,6 +200,7 @@ IsSharedSystemRelationName(const char *relname) return FALSE; } + /* * newoid - returns a unique identifier across all catalogs. * diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 1d225cc082..eb7487ae62 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.195 2002/04/11 19:59:56 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.196 2002/04/12 20:38:18 tgl Exp $ * * * INTERFACE ROUTINES @@ -38,7 +38,6 @@ #include "catalog/indexing.h" #include "catalog/pg_attrdef.h" #include "catalog/pg_inherits.h" -#include "catalog/pg_namespace.h" #include "catalog/pg_relcheck.h" #include "catalog/pg_statistic.h" #include "catalog/pg_type.h" @@ -224,10 +223,10 @@ heap_create(const char *relname, * sanity checks */ if (!allow_system_table_mods && - IsSystemRelationName(relname) && + (IsSystemNamespace(relnamespace) || IsToastNamespace(relnamespace)) && IsNormalProcessingMode()) - elog(ERROR, "invalid relation name \"%s\"; " - "the 'pg_' name prefix is reserved for system catalogs", + elog(ERROR, "invalid relation \"%s\"; " + "system catalog modifications are currently disallowed", relname); /* @@ -237,7 +236,7 @@ heap_create(const char *relname, * have to take special care for those rels that should be nailed * in cache and/or are shared across databases. */ - if (relnamespace == PG_CATALOG_NAMESPACE) + if (IsSystemNamespace(relnamespace)) { if (strcmp(TypeRelationName, relname) == 0) { @@ -1193,7 +1192,7 @@ heap_drop_with_catalog(Oid rid, * prevent deletion of system relations */ if (!allow_system_table_mods && - IsSystemRelationName(RelationGetRelationName(rel))) + IsSystemRelation(rel)) elog(ERROR, "System relation \"%s\" may not be dropped", RelationGetRelationName(rel)); diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index f8a1e5d4b2..d563d65418 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.175 2002/03/31 06:26:29 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.176 2002/04/12 20:38:19 tgl Exp $ * * * INTERFACE ROUTINES @@ -33,7 +33,6 @@ #include "catalog/index.h" #include "catalog/indexing.h" #include "catalog/pg_index.h" -#include "catalog/pg_namespace.h" #include "catalog/pg_opclass.h" #include "catalog/pg_proc.h" #include "catalog/pg_type.h" @@ -320,7 +319,7 @@ ConstructIndexReldesc(Relation indexRelation, Oid amoid) indexRelation->rd_rel->relowner = GetUserId(); indexRelation->rd_rel->relam = amoid; indexRelation->rd_rel->relisshared = - (RelationGetNamespace(indexRelation) == PG_CATALOG_NAMESPACE) && + IsSystemNamespace(RelationGetNamespace(indexRelation)) && IsSharedSystemRelationName(RelationGetRelationName(indexRelation)); indexRelation->rd_rel->relkind = RELKIND_INDEX; indexRelation->rd_rel->relhasoids = false; @@ -582,7 +581,7 @@ index_create(Oid heapRelationId, elog(ERROR, "must index at least one column"); if (!allow_system_table_mods && - IsSystemRelationName(RelationGetRelationName(heapRelation)) && + IsSystemRelation(heapRelation) && IsNormalProcessingMode()) elog(ERROR, "User-defined indexes on system catalogs are not supported"); @@ -1221,7 +1220,7 @@ setNewRelfilenode(Relation relation) Buffer buffer; RelationData workrel; - Assert(!IsSystemRelationName(NameStr(relation->rd_rel->relname)) || relation->rd_rel->relkind == RELKIND_INDEX); + Assert(!IsSystemRelation(relation) || relation->rd_rel->relkind == RELKIND_INDEX); pg_class = heap_openr(RelationRelationName, RowExclusiveLock); /* Fetch and lock the classTuple associated with this relation */ @@ -1912,7 +1911,7 @@ reindex_relation(Oid relid, bool force) * ignore the indexes of the target system relation while processing * reindex. */ - if (!IsIgnoringSystemIndexes() && IsSystemRelationName(NameStr(rel->rd_rel->relname))) + if (!IsIgnoringSystemIndexes() && IsSystemRelation(rel)) deactivate_needed = true; #ifndef ENABLE_REINDEX_NAILED_RELATIONS diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c index 6880dbe19e..84bd95e466 100644 --- a/src/backend/catalog/namespace.c +++ b/src/backend/catalog/namespace.c @@ -13,7 +13,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.7 2002/04/09 20:35:47 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.8 2002/04/12 20:38:19 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -21,6 +21,7 @@ #include "access/heapam.h" #include "access/xact.h" +#include "catalog/catalog.h" #include "catalog/catname.h" #include "catalog/heap.h" #include "catalog/namespace.h" @@ -391,7 +392,7 @@ FuncnameGetCandidates(List *names, int nargs) { /* Consider only procs that are in the search path */ if (pathContainsSystemNamespace || - procform->pronamespace != PG_CATALOG_NAMESPACE) + !IsSystemNamespace(procform->pronamespace)) { List *nsp; diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index ea778de336..e36f21273d 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.30 2002/04/02 01:03:05 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.31 2002/04/12 20:38:20 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -18,9 +18,9 @@ #include "access/heapam.h" #include "access/tuptoaster.h" +#include "catalog/catalog.h" #include "catalog/catname.h" #include "catalog/indexing.h" -#include "catalog/pg_namespace.h" #include "catalog/pg_operator.h" #include "catalog/pg_statistic.h" #include "catalog/pg_type.h" @@ -218,7 +218,7 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt) /* * We can ANALYZE any table except pg_statistic. See update_attstats */ - if (RelationGetNamespace(onerel) == PG_CATALOG_NAMESPACE && + if (IsSystemNamespace(RelationGetNamespace(onerel)) && strcmp(RelationGetRelationName(onerel), StatisticRelationName) == 0) { relation_close(onerel, AccessShareLock); diff --git a/src/backend/commands/command.c b/src/backend/commands/command.c index c74d24cf7a..c13b2aa67d 100644 --- a/src/backend/commands/command.c +++ b/src/backend/commands/command.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.173 2002/04/11 23:20:04 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.174 2002/04/12 20:38:20 tgl Exp $ * * NOTES * The PerformAddAttribute() code, like most of the relation @@ -346,7 +346,7 @@ AlterTableAddColumn(Oid myrelid, * normally, only the owner of a class can change its schema. */ if (!allowSystemTableMods - && IsSystemRelationName(RelationGetRelationName(rel))) + && IsSystemRelation(rel)) elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog", RelationGetRelationName(rel)); if (!pg_class_ownercheck(myrelid, GetUserId())) @@ -548,7 +548,7 @@ AlterTableAlterColumnDropNotNull(Oid myrelid, RelationGetRelationName(rel)); if (!allowSystemTableMods - && IsSystemRelationName(RelationGetRelationName(rel))) + && IsSystemRelation(rel)) elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog", RelationGetRelationName(rel)); @@ -699,7 +699,7 @@ AlterTableAlterColumnSetNotNull(Oid myrelid, RelationGetRelationName(rel)); if (!allowSystemTableMods - && IsSystemRelationName(RelationGetRelationName(rel))) + && IsSystemRelation(rel)) elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog", RelationGetRelationName(rel)); @@ -829,7 +829,7 @@ AlterTableAlterColumnDefault(Oid myrelid, RelationGetRelationName(rel)); if (!allowSystemTableMods - && IsSystemRelationName(RelationGetRelationName(rel))) + && IsSystemRelation(rel)) elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog", RelationGetRelationName(rel)); @@ -970,8 +970,8 @@ drop_default(Oid relid, int16 attnum) */ void AlterTableAlterColumnFlags(Oid myrelid, - bool inh, const char *colName, - Node *flagValue, const char *flagType) + bool inh, const char *colName, + Node *flagValue, const char *flagType) { Relation rel; int newtarget = 1; @@ -989,9 +989,7 @@ AlterTableAlterColumnFlags(Oid myrelid, /* * we allow statistics case for system tables */ - if (*flagType != 'S' && - !allowSystemTableMods - && IsSystemRelationName(RelationGetRelationName(rel))) + if (*flagType != 'S' && !allowSystemTableMods && IsSystemRelation(rel)) elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog", RelationGetRelationName(rel)); @@ -1150,7 +1148,7 @@ AlterTableAddConstraint(Oid myrelid, RelationGetRelationName(rel)); if (!allowSystemTableMods - && IsSystemRelationName(RelationGetRelationName(rel))) + && IsSystemRelation(rel)) elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog", RelationGetRelationName(rel)); @@ -1476,7 +1474,7 @@ AlterTableDropConstraint(Oid myrelid, RelationGetRelationName(rel)); if (!allowSystemTableMods - && IsSystemRelationName(RelationGetRelationName(rel))) + && IsSystemRelation(rel)) elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog", RelationGetRelationName(rel)); @@ -1952,6 +1950,10 @@ CreateSchemaCommand(CreateSchemaStmt *stmt) owner_name, authId); } + if (!allowSystemTableMods && IsReservedName(schemaName)) + elog(ERROR, "CREATE SCHEMA: Illegal schema name: \"%s\" -- pg_ is reserved for system schemas", + schemaName); + /* Create the schema's namespace */ NamespaceCreate(schemaName, owner_userid); diff --git a/src/backend/commands/creatinh.c b/src/backend/commands/creatinh.c index 4a76e0c11e..6a0cf81147 100644 --- a/src/backend/commands/creatinh.c +++ b/src/backend/commands/creatinh.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.95 2002/03/31 06:26:30 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.96 2002/04/12 20:38:22 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -22,7 +22,6 @@ #include "catalog/indexing.h" #include "catalog/namespace.h" #include "catalog/pg_inherits.h" -#include "catalog/pg_namespace.h" #include "catalog/pg_type.h" #include "commands/creatinh.h" #include "miscadmin.h" @@ -275,7 +274,7 @@ TruncateRelation(const RangeVar *relation) elog(ERROR, "TRUNCATE cannot be used on views. '%s' is a view", RelationGetRelationName(rel)); - if (!allowSystemTableMods && IsSystemRelationName(RelationGetRelationName(rel))) + if (!allowSystemTableMods && IsSystemRelation(rel)) elog(ERROR, "TRUNCATE cannot be used on system tables. '%s' is a system table", RelationGetRelationName(rel)); diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 0a8ddc1807..297d5e7266 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.69 2002/04/11 19:59:58 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.70 2002/04/12 20:38:22 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -104,13 +104,13 @@ DefineIndex(RangeVar *heapRelation, relationId = RelationGetRelid(rel); - heap_close(rel, NoLock); - if (!IsBootstrapProcessingMode() && - IsSystemRelationName(heapRelation->relname) && + IsSystemRelation(rel) && !IndexesAreActive(relationId, false)) elog(ERROR, "Existing indexes are inactive. REINDEX first"); + heap_close(rel, NoLock); + /* * look up the access method, verify it can handle the requested * features @@ -560,6 +560,16 @@ ReindexIndex(RangeVar *indexRelation, bool force /* currently unused */ ) indexRelation->relname, ((Form_pg_class) GETSTRUCT(tuple))->relkind); + if (IsSystemClass((Form_pg_class) GETSTRUCT(tuple))) + { + if (!allowSystemTableMods) + elog(ERROR, "\"%s\" is a system index. call REINDEX under standalone postgres with -O -P options", + indexRelation->relname); + if (!IsIgnoringSystemIndexes()) + elog(ERROR, "\"%s\" is a system index. call REINDEX under standalone postgres with -P -O options", + indexRelation->relname); + } + ReleaseSysCache(tuple); if (IsIgnoringSystemIndexes()) @@ -611,10 +621,6 @@ ReindexTable(RangeVar *relation, bool force) /* * ReindexDatabase * Recreate indexes of a database. - * - * Exceptions: - * "ERROR" if table nonexistent. - * ... */ void ReindexDatabase(const char *dbname, bool force, bool all) @@ -638,6 +644,11 @@ ReindexDatabase(const char *dbname, bool force, bool all) if (!(superuser() || is_dbadmin(MyDatabaseId))) elog(ERROR, "REINDEX DATABASE: Permission denied."); + if (!allowSystemTableMods) + elog(ERROR, "must be called under standalone postgres with -O -P options"); + if (!IsIgnoringSystemIndexes()) + elog(ERROR, "must be called under standalone postgres with -P -O options"); + /* * We cannot run inside a user transaction block; if we were inside a * transaction, then our commit- and start-transaction-command calls @@ -668,7 +679,7 @@ ReindexDatabase(const char *dbname, bool force, bool all) { if (!all) { - if (!IsSystemRelationName(NameStr(((Form_pg_class) GETSTRUCT(tuple))->relname))) + if (!IsSystemClass((Form_pg_class) GETSTRUCT(tuple))) continue; } if (((Form_pg_class) GETSTRUCT(tuple))->relkind == RELKIND_RELATION) diff --git a/src/backend/commands/rename.c b/src/backend/commands/rename.c index 5760cbe300..21db59b7f6 100644 --- a/src/backend/commands/rename.c +++ b/src/backend/commands/rename.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.69 2002/04/05 11:58:24 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.70 2002/04/12 20:38:24 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -92,7 +92,7 @@ renameatt(Oid relid, * normally, only the owner of a class can change its schema. */ if (!allowSystemTableMods - && IsSystemRelationName(RelationGetRelationName(targetrelation))) + && IsSystemRelation(targetrelation)) elog(ERROR, "renameatt: class \"%s\" is a system catalog", RelationGetRelationName(targetrelation)); if (!pg_class_ownercheck(relid, GetUserId())) @@ -276,14 +276,10 @@ renamerel(Oid relid, const char *newrelname) /* Validity checks */ if (!allowSystemTableMods && - IsSystemRelationName(RelationGetRelationName(targetrelation))) + IsSystemRelation(targetrelation)) elog(ERROR, "renamerel: system relation \"%s\" may not be renamed", RelationGetRelationName(targetrelation)); - if (!allowSystemTableMods && IsSystemRelationName(newrelname)) - elog(ERROR, "renamerel: Illegal class name: \"%s\" -- pg_ is reserved for system catalogs", - newrelname); - relkind = targetrelation->rd_rel->relkind; relhastriggers = (targetrelation->rd_rel->reltriggers > 0); diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 72f13d3db4..891b9f3cfb 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.112 2002/04/09 20:35:48 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.113 2002/04/12 20:38:24 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -80,7 +80,7 @@ CreateTrigger(CreateTrigStmt *stmt) elog(ERROR, "CreateTrigger: relation \"%s\" is not a table", stmt->relation->relname); - if (!allowSystemTableMods && IsSystemRelationName(stmt->relation->relname)) + if (!allowSystemTableMods && IsSystemRelation(rel)) elog(ERROR, "CreateTrigger: can't create trigger for system relation %s", stmt->relation->relname); @@ -326,7 +326,7 @@ DropTrigger(Oid relid, const char *trigname) elog(ERROR, "DropTrigger: relation \"%s\" is not a table", RelationGetRelationName(rel)); - if (!allowSystemTableMods && IsSystemRelationName(RelationGetRelationName(rel))) + if (!allowSystemTableMods && IsSystemRelation(rel)) elog(ERROR, "DropTrigger: can't drop trigger for system relation %s", RelationGetRelationName(rel)); diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index ed3effab65..20a366d02a 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -13,7 +13,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.222 2002/04/02 05:11:55 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.223 2002/04/12 20:38:25 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -806,7 +806,7 @@ full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt) bool reindex = false; if (IsIgnoringSystemIndexes() && - IsSystemRelationName(RelationGetRelationName(onerel))) + IsSystemRelation(onerel)) reindex = true; vacuum_set_xid_limits(vacstmt, onerel->rd_rel->relisshared, diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c index 5b07194877..9b03401e44 100644 --- a/src/backend/executor/execUtils.c +++ b/src/backend/executor/execUtils.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.79 2002/02/19 20:11:13 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.80 2002/04/12 20:38:26 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -467,7 +467,7 @@ ExecOpenIndices(ResultRelInfo *resultRelInfo) if (!RelationGetForm(resultRelation)->relhasindex) return; if (IsIgnoringSystemIndexes() && - IsSystemRelationName(RelationGetRelationName(resultRelation))) + IsSystemRelation(resultRelation)) return; /* diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 447b3e61f2..6ae9e1b7e9 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.70 2002/02/19 20:11:14 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.71 2002/04/12 20:38:26 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -58,8 +58,7 @@ get_relation_info(Oid relationObjectId, relationObjectId); relation = (Form_pg_class) GETSTRUCT(relationTuple); - if (IsIgnoringSystemIndexes() && - IsSystemRelationName(NameStr(relation->relname))) + if (IsIgnoringSystemIndexes() && IsSystemClass(relation)) *hasindex = false; else *hasindex = relation->relhasindex; diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 7e2be17ede..77dfe4a236 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.147 2002/04/12 09:17:10 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.148 2002/04/12 20:38:27 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -127,7 +127,7 @@ CheckDropPermissions(RangeVar *rel, char rightkind) elog(ERROR, "you do not own %s \"%s\"", rentry->name, rel->relname); - if (!allowSystemTableMods && IsSystemRelationName(rel->relname)) + if (!allowSystemTableMods && IsSystemClass(classform)) elog(ERROR, "%s \"%s\" is a system %s", rentry->name, rel->relname, rentry->name); @@ -153,7 +153,8 @@ CheckOwnership(RangeVar *rel, bool noCatalogs) if (noCatalogs) { - if (!allowSystemTableMods && IsSystemRelationName(rel->relname)) + if (!allowSystemTableMods && + IsSystemClass((Form_pg_class) GETSTRUCT(tuple))) elog(ERROR, "relation \"%s\" is a system catalog", rel->relname); } @@ -791,15 +792,6 @@ ProcessUtility(Node *parsetree, { case INDEX: relname = (char *) stmt->relation->relname; - if (IsSystemRelationName(relname)) - { - if (!allowSystemTableMods) - elog(ERROR, "\"%s\" is a system index. call REINDEX under standalone postgres with -O -P options", - relname); - if (!IsIgnoringSystemIndexes()) - elog(ERROR, "\"%s\" is a system index. call REINDEX under standalone postgres with -P -O options", - relname); - } CheckOwnership(stmt->relation, false); ReindexIndex(stmt->relation, stmt->force); break; @@ -809,10 +801,6 @@ ProcessUtility(Node *parsetree, break; case DATABASE: relname = (char *) stmt->name; - if (!allowSystemTableMods) - elog(ERROR, "must be called under standalone postgres with -O -P options"); - if (!IsIgnoringSystemIndexes()) - elog(ERROR, "must be called under standalone postgres with -P -O options"); ReindexDatabase(relname, stmt->force, false); break; } diff --git a/src/backend/utils/cache/inval.c b/src/backend/utils/cache/inval.c index 6d397a7ba9..483c06bd6a 100644 --- a/src/backend/utils/cache/inval.c +++ b/src/backend/utils/cache/inval.c @@ -74,7 +74,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/inval.c,v 1.49 2002/03/03 17:47:55 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/inval.c,v 1.50 2002/04/12 20:38:28 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -456,12 +456,15 @@ PrepareForTupleInvalidation(Relation relation, HeapTuple tuple, * We only need to worry about invalidation for tuples that are in * system relations; user-relation tuples are never in catcaches and * can't affect the relcache either. - * - * TOAST tuples can likewise be ignored here. */ - if (!IsSystemRelationName(NameStr(RelationGetForm(relation)->relname))) + if (!IsSystemRelation(relation)) return; - if (IsToastRelationName(NameStr(RelationGetForm(relation)->relname))) + /* + * TOAST tuples can likewise be ignored here. + * Note that TOAST tables are considered system relations + * so they are not filtered by the above test. + */ + if (IsToastRelation(relation)) return; /* diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index fcdffa9132..9a8e76f492 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.159 2002/03/31 06:26:31 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.160 2002/04/12 20:38:29 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -183,7 +183,7 @@ do { \ elog(ERROR, "out of memory for relation descriptor cache"); \ /* used to give notice if found -- now just keep quiet */ \ nodentry->reldesc = RELATION; \ - if (RelationGetNamespace(RELATION) == PG_CATALOG_NAMESPACE) \ + if (IsSystemNamespace(RelationGetNamespace(RELATION))) \ { \ char *relname = RelationGetRelationName(RELATION); \ RelNameCacheEnt *namehentry; \ @@ -244,7 +244,7 @@ do { \ HASH_REMOVE, NULL); \ if (nodentry == NULL) \ elog(WARNING, "trying to delete a reldesc that does not exist."); \ - if (RelationGetNamespace(RELATION) == PG_CATALOG_NAMESPACE) \ + if (IsSystemNamespace(RelationGetNamespace(RELATION))) \ { \ char *relname = RelationGetRelationName(RELATION); \ RelNameCacheEnt *namehentry; \ diff --git a/src/include/catalog/catalog.h b/src/include/catalog/catalog.h index 62cc5736f7..255bb265c4 100644 --- a/src/include/catalog/catalog.h +++ b/src/include/catalog/catalog.h @@ -7,22 +7,29 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: catalog.h,v 1.22 2002/03/22 21:34:44 tgl Exp $ + * $Id: catalog.h,v 1.23 2002/04/12 20:38:30 tgl Exp $ * *------------------------------------------------------------------------- */ #ifndef CATALOG_H #define CATALOG_H -#include "access/tupdesc.h" +#include "utils/rel.h" -#include "storage/relfilenode.h" extern char *relpath(RelFileNode rnode); extern char *GetDatabasePath(Oid tblNode); -extern bool IsSystemRelationName(const char *relname); -extern bool IsToastRelationName(const char *relname); +extern bool IsSystemRelation(Relation relation); +extern bool IsToastRelation(Relation relation); + +extern bool IsSystemClass(Form_pg_class reltuple); +extern bool IsToastClass(Form_pg_class reltuple); + +extern bool IsSystemNamespace(Oid namespaceId); +extern bool IsToastNamespace(Oid namespaceId); + +extern bool IsReservedName(const char *name); extern bool IsSharedSystemRelationName(const char *relname); extern Oid newoid(void); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index cbf0680a42..95821b513d 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -296,6 +296,9 @@ SELECT * FROM foo_seq_new; (1 row) DROP SEQUENCE foo_seq_new; +-- toast-like relation name +alter table stud_emp rename to pg_toast_stud_emp; +alter table pg_toast_stud_emp rename to stud_emp; -- FOREIGN KEY CONSTRAINT adding TEST CREATE TABLE tmp2 (a int primary key); NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'tmp2_pkey' for table 'tmp2' diff --git a/src/test/regress/expected/errors.out b/src/test/regress/expected/errors.out index 56c8939c6f..cdd4218d99 100644 --- a/src/test/regress/expected/errors.out +++ b/src/test/regress/expected/errors.out @@ -66,9 +66,6 @@ ERROR: Relation "nonesuch" does not exist -- no such relation alter table nonesuch rename to stud_emp; ERROR: Relation "nonesuch" does not exist --- system relation -alter table stud_emp rename to pg_stud_emp; -ERROR: renamerel: Illegal class name: "pg_stud_emp" -- pg_ is reserved for system catalogs -- conflict alter table stud_emp rename to aggtest; ERROR: renamerel: relation "aggtest" exists diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index 477f4696b5..2931e8ea18 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -178,6 +178,9 @@ CREATE SEQUENCE foo_seq; ALTER TABLE foo_seq RENAME TO foo_seq_new; SELECT * FROM foo_seq_new; DROP SEQUENCE foo_seq_new; +-- toast-like relation name +alter table stud_emp rename to pg_toast_stud_emp; +alter table pg_toast_stud_emp rename to stud_emp; -- FOREIGN KEY CONSTRAINT adding TEST diff --git a/src/test/regress/sql/errors.sql b/src/test/regress/sql/errors.sql index 949f640599..5ab09d2a12 100644 --- a/src/test/regress/sql/errors.sql +++ b/src/test/regress/sql/errors.sql @@ -77,9 +77,6 @@ alter table nonesuch rename to newnonesuch; -- no such relation alter table nonesuch rename to stud_emp; --- system relation -alter table stud_emp rename to pg_stud_emp; - -- conflict alter table stud_emp rename to aggtest;