diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2002-03-29 19:06:29 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2002-03-29 19:06:29 +0000 |
commit | d5e99ab4d6718e8ef515575e33fb5c6181cdcc96 (patch) | |
tree | 6c817d6358f50ae920207245c3b862b2cdd74ceb /src/backend/commands/command.c | |
parent | 7c1ff354105e2256d7904497d8e282ccec53d2e6 (diff) | |
download | postgresql-d5e99ab4d6718e8ef515575e33fb5c6181cdcc96.tar.gz postgresql-d5e99ab4d6718e8ef515575e33fb5c6181cdcc96.zip |
pg_type has a typnamespace column; system now supports creating types
in different namespaces. Also, cleanup work on relation namespace
support: drop, alter, rename commands work for tables in non-default
namespaces.
Diffstat (limited to 'src/backend/commands/command.c')
-rw-r--r-- | src/backend/commands/command.c | 257 |
1 files changed, 111 insertions, 146 deletions
diff --git a/src/backend/commands/command.c b/src/backend/commands/command.c index bf7980d42c8..9180c539ff2 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.166 2002/03/26 19:15:36 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.167 2002/03/29 19:06:03 tgl Exp $ * * NOTES * The PerformAddAttribute() code, like most of the relation @@ -42,11 +42,12 @@ #include "optimizer/clauses.h" #include "optimizer/planmain.h" #include "optimizer/prep.h" +#include "parser/analyze.h" #include "parser/parse.h" #include "parser/parse_expr.h" #include "parser/parse_oper.h" #include "parser/parse_relation.h" -#include "parser/analyze.h" +#include "parser/parse_type.h" #include "tcop/utility.h" #include "utils/acl.h" #include "utils/builtins.h" @@ -58,9 +59,9 @@ static void drop_default(Oid relid, int16 attnum); static bool needs_toast_table(Relation rel); -static void AlterTableOwnerId(Oid relationOid, int32 newOwnerSysId); static void CheckTupleType(Form_pg_class tuple_class); + /* -------------------------------- * PortalCleanup * -------------------------------- @@ -309,13 +310,13 @@ PerformPortalClose(char *name, CommandDest dest) * ---------------- */ void -AlterTableAddColumn(const char *relationName, +AlterTableAddColumn(Oid myrelid, bool inherits, ColumnDef *colDef) { Relation rel, + pgclass, attrdesc; - Oid myrelid; HeapTuple reltup; HeapTuple newreltup; HeapTuple attributeTuple; @@ -326,19 +327,17 @@ AlterTableAddColumn(const char *relationName, maxatts; HeapTuple typeTuple; Form_pg_type tform; - char *typename; int attndims; /* * Grab an exclusive lock on the target table, which we will NOT * release until end of transaction. */ - rel = heap_openr(relationName, AccessExclusiveLock); - myrelid = RelationGetRelid(rel); + rel = heap_open(myrelid, AccessExclusiveLock); if (rel->rd_rel->relkind != RELKIND_RELATION) elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table", - relationName); + RelationGetRelationName(rel)); /* * permissions checking. this would normally be done in utility.c, @@ -346,13 +345,13 @@ AlterTableAddColumn(const char *relationName, * * normally, only the owner of a class can change its schema. */ - if (!allowSystemTableMods && IsSystemRelationName(relationName)) + if (!allowSystemTableMods + && IsSystemRelationName(RelationGetRelationName(rel))) elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog", - relationName); + RelationGetRelationName(rel)); if (!pg_class_ownercheck(myrelid, GetUserId())) - elog(ERROR, "ALTER TABLE: permission denied"); - - heap_close(rel, NoLock); /* close rel but keep lock! */ + elog(ERROR, "ALTER TABLE: \"%s\": permission denied", + RelationGetRelationName(rel)); /* * Recurse to add the column to child classes, if requested. @@ -377,17 +376,11 @@ AlterTableAddColumn(const char *relationName, foreach(child, children) { Oid childrelid = lfirsti(child); - char *childrelname; if (childrelid == myrelid) continue; - rel = heap_open(childrelid, AccessExclusiveLock); - childrelname = pstrdup(RelationGetRelationName(rel)); - heap_close(rel, AccessExclusiveLock); - - AlterTableAddColumn(childrelname, false, colDef); - pfree(childrelname); + AlterTableAddColumn(childrelid, false, colDef); } } @@ -412,23 +405,21 @@ AlterTableAddColumn(const char *relationName, elog(ERROR, "Adding NOT NULL columns is not implemented." "\n\tAdd the column, then use ALTER TABLE ADD CONSTRAINT."); - - rel = heap_openr(RelationRelationName, RowExclusiveLock); + pgclass = heap_openr(RelationRelationName, RowExclusiveLock); reltup = SearchSysCache(RELOID, ObjectIdGetDatum(myrelid), 0, 0, 0); - if (!HeapTupleIsValid(reltup)) elog(ERROR, "ALTER TABLE: relation \"%s\" not found", - relationName); + RelationGetRelationName(rel)); if (SearchSysCacheExists(ATTNAME, ObjectIdGetDatum(myrelid), PointerGetDatum(colDef->colname), 0, 0)) elog(ERROR, "ALTER TABLE: column name \"%s\" already exists in table \"%s\"", - colDef->colname, relationName); + colDef->colname, RelationGetRelationName(rel)); minattnum = ((Form_pg_class) GETSTRUCT(reltup))->relnatts; maxatts = minattnum + 1; @@ -440,21 +431,11 @@ AlterTableAddColumn(const char *relationName, attrdesc = heap_openr(AttributeRelationName, RowExclusiveLock); if (colDef->typename->arrayBounds) - { attndims = length(colDef->typename->arrayBounds); - typename = makeArrayTypeName(colDef->typename->name); - } else - { attndims = 0; - typename = colDef->typename->name; - } - typeTuple = SearchSysCache(TYPENAME, - PointerGetDatum(typename), - 0, 0, 0); - if (!HeapTupleIsValid(typeTuple)) - elog(ERROR, "ALTER TABLE: type \"%s\" does not exist", typename); + typeTuple = typenameType(colDef->typename); tform = (Form_pg_type) GETSTRUCT(typeTuple); attributeTuple = heap_addheader(Natts_pg_attribute, @@ -494,7 +475,7 @@ AlterTableAddColumn(const char *relationName, CatalogCloseIndices(Num_pg_attr_indices, idescs); } - heap_close(attrdesc, NoLock); + heap_close(attrdesc, RowExclusiveLock); /* * Update number of attributes in pg_class tuple @@ -502,22 +483,24 @@ AlterTableAddColumn(const char *relationName, newreltup = heap_copytuple(reltup); ((Form_pg_class) GETSTRUCT(newreltup))->relnatts = maxatts; - simple_heap_update(rel, &newreltup->t_self, newreltup); + simple_heap_update(pgclass, &newreltup->t_self, newreltup); /* keep catalog indices current */ - if (RelationGetForm(rel)->relhasindex) + if (RelationGetForm(pgclass)->relhasindex) { Relation ridescs[Num_pg_class_indices]; CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs); - CatalogIndexInsert(ridescs, Num_pg_class_indices, rel, newreltup); + CatalogIndexInsert(ridescs, Num_pg_class_indices, pgclass, newreltup); CatalogCloseIndices(Num_pg_class_indices, ridescs); } heap_freetuple(newreltup); ReleaseSysCache(reltup); - heap_close(rel, NoLock); + heap_close(pgclass, NoLock); + + heap_close(rel, NoLock); /* close rel but keep lock! */ /* * Make our catalog updates visible for subsequent steps. @@ -549,29 +532,28 @@ AlterTableAddColumn(const char *relationName, * ALTER TABLE ALTER COLUMN SET/DROP DEFAULT */ void -AlterTableAlterColumnDefault(const char *relationName, +AlterTableAlterColumnDefault(Oid myrelid, bool inh, const char *colName, Node *newDefault) { Relation rel; HeapTuple tuple; int16 attnum; - Oid myrelid; - rel = heap_openr(relationName, AccessExclusiveLock); - myrelid = RelationGetRelid(rel); + rel = heap_open(myrelid, AccessExclusiveLock); if (rel->rd_rel->relkind != RELKIND_RELATION) elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table", - relationName); + RelationGetRelationName(rel)); - if (!allowSystemTableMods && IsSystemRelationName(relationName)) + if (!allowSystemTableMods + && IsSystemRelationName(RelationGetRelationName(rel))) elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog", - relationName); - if (!pg_class_ownercheck(myrelid, GetUserId())) - elog(ERROR, "ALTER TABLE: permission denied"); + RelationGetRelationName(rel)); - heap_close(rel, NoLock); + if (!pg_class_ownercheck(myrelid, GetUserId())) + elog(ERROR, "ALTER TABLE: \"%s\" permission denied", + RelationGetRelationName(rel)); /* * Propagate to children if desired @@ -595,18 +577,13 @@ AlterTableAlterColumnDefault(const char *relationName, if (childrelid == myrelid) continue; - rel = heap_open(childrelid, AccessExclusiveLock); - AlterTableAlterColumnDefault(RelationGetRelationName(rel), + AlterTableAlterColumnDefault(childrelid, false, colName, newDefault); - heap_close(rel, AccessExclusiveLock); } } /* -= now do the thing on this relation =- */ - /* reopen the business */ - rel = heap_openr(relationName, AccessExclusiveLock); - /* * get the number of the attribute */ @@ -616,7 +593,7 @@ AlterTableAlterColumnDefault(const char *relationName, 0, 0); if (!HeapTupleIsValid(tuple)) elog(ERROR, "ALTER TABLE: relation \"%s\" has no column \"%s\"", - relationName, colName); + RelationGetRelationName(rel), colName); attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum; ReleaseSysCache(tuple); @@ -718,43 +695,42 @@ drop_default(Oid relid, int16 attnum) * ALTER TABLE ALTER COLUMN SET STATISTICS / STORAGE */ void -AlterTableAlterColumnFlags(const char *relationName, +AlterTableAlterColumnFlags(Oid myrelid, bool inh, const char *colName, Node *flagValue, const char *flagType) { Relation rel; - Oid myrelid; int newtarget = 1; char newstorage = 'x'; char *storagemode; Relation attrelation; HeapTuple tuple; - rel = heap_openr(relationName, AccessExclusiveLock); - myrelid = RelationGetRelid(rel); + rel = heap_open(myrelid, AccessExclusiveLock); if (rel->rd_rel->relkind != RELKIND_RELATION) elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table", - relationName); + RelationGetRelationName(rel)); - /* we allow statistics case for system tables */ - if (*flagType == 'M' && - !allowSystemTableMods && IsSystemRelationName(relationName)) + /* + * we allow statistics case for system tables + */ + if (*flagType != 'S' && + !allowSystemTableMods + && IsSystemRelationName(RelationGetRelationName(rel))) elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog", - relationName); - if (!pg_class_ownercheck(myrelid, GetUserId())) - elog(ERROR, "ALTER TABLE: permission denied"); - - heap_close(rel, NoLock); /* close rel, but keep lock! */ + RelationGetRelationName(rel)); + if (!pg_class_ownercheck(myrelid, GetUserId())) + elog(ERROR, "ALTER TABLE: \"%s\" permission denied", + RelationGetRelationName(rel)); /* * Check the supplied parameters before anything else */ - if (*flagType == 'S') /* - * STATISTICS - */ + if (*flagType == 'S') { + /* STATISTICS */ Assert(IsA(flagValue, Integer)); newtarget = intVal(flagValue); @@ -766,10 +742,9 @@ AlterTableAlterColumnFlags(const char *relationName, else if (newtarget > 1000) newtarget = 1000; } - else if (*flagType == 'M') /* - * STORAGE - */ + else if (*flagType == 'M') { + /* STORAGE */ Assert(IsA(flagValue, Value)); storagemode = strVal(flagValue); @@ -813,10 +788,8 @@ AlterTableAlterColumnFlags(const char *relationName, if (childrelid == myrelid) continue; - rel = heap_open(childrelid, AccessExclusiveLock); - AlterTableAlterColumnFlags(RelationGetRelationName(rel), - false, colName, flagValue, flagType); - heap_close(rel, AccessExclusiveLock); + AlterTableAlterColumnFlags(childrelid, + false, colName, flagValue, flagType); } } @@ -830,7 +803,7 @@ AlterTableAlterColumnFlags(const char *relationName, 0, 0); if (!HeapTupleIsValid(tuple)) elog(ERROR, "ALTER TABLE: relation \"%s\" has no column \"%s\"", - relationName, colName); + RelationGetRelationName(rel), colName); if (((Form_pg_attribute) GETSTRUCT(tuple))->attnum < 0) elog(ERROR, "ALTER TABLE: cannot change system attribute \"%s\"", @@ -864,6 +837,7 @@ AlterTableAlterColumnFlags(const char *relationName, heap_freetuple(tuple); heap_close(attrelation, NoLock); + heap_close(rel, NoLock); /* close rel, but keep lock! */ } @@ -1006,14 +980,13 @@ RemoveColumnReferences(Oid reloid, int attnum, bool checkonly, HeapTuple reltup) * ALTER TABLE DROP COLUMN */ void -AlterTableDropColumn(const char *relationName, +AlterTableDropColumn(Oid myrelid, bool inh, const char *colName, int behavior) { #ifdef _DROP_COLUMN_HACK__ Relation rel, attrdesc; - Oid myrelid; HeapTuple reltup; HeapTupleData classtuple; Buffer buffer; @@ -1031,12 +1004,16 @@ AlterTableDropColumn(const char *relationName, * Grab an exclusive lock on the target table, which we will NOT * release until end of transaction. */ - rel = heap_openr(relationName, AccessExclusiveLock); - myrelid = RelationGetRelid(rel); + rel = heap_open(myrelid, AccessExclusiveLock); if (rel->rd_rel->relkind != RELKIND_RELATION) elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table", - relationName); + RelationGetRelationName(rel)); + + if (!allowSystemTableMods + && IsSystemRelationName(RelationGetRelationName(rel)) + elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog", + RelationGetRelationName(rel)); /* * permissions checking. this would normally be done in utility.c, @@ -1044,9 +1021,6 @@ AlterTableDropColumn(const char *relationName, * * normally, only the owner of a class can change its schema. */ - if (!allowSystemTableMods && IsSystemRelationName(relationName)) - elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog", - relationName); if (!pg_class_ownercheck(myrelid, GetUserId())) elog(ERROR, "ALTER TABLE: permission denied"); @@ -1066,8 +1040,17 @@ AlterTableDropColumn(const char *relationName, ObjectIdGetDatum(myrelid), 0, 0, 0); if (!HeapTupleIsValid(reltup)) + { + Relation myrel; + char *myrelname; + + myrel = heap_open(myrelid, AccessExclusiveLock); + myrelname = pstrdup(RelationGetRelationName(myrel)); + heap_close(myrel, AccessExclusiveLock); + elog(ERROR, "ALTER TABLE: relation \"%s\" not found", - relationName); + myrelname); + } classtuple.t_self = reltup->t_self; ReleaseSysCache(reltup); @@ -1092,8 +1075,17 @@ AlterTableDropColumn(const char *relationName, PointerGetDatum(colName), 0, 0); if (!HeapTupleIsValid(tup)) + { + Relation myrel; + char *myrelname; + + myrel = heap_open(myrelid, AccessExclusiveLock); + myrelname = pstrdup(RelationGetRelationName(myrel)); + heap_close(myrel, AccessExclusiveLock); + elog(ERROR, "ALTER TABLE: column name \"%s\" doesn't exist in table \"%s\"", - colName, relationName); + colName, myrelname); + } attribute = (Form_pg_attribute) GETSTRUCT(tup); attnum = attribute->attnum; @@ -1164,29 +1156,30 @@ AlterTableDropColumn(const char *relationName, * ALTER TABLE ADD CONSTRAINT */ void -AlterTableAddConstraint(char *relationName, +AlterTableAddConstraint(Oid myrelid, bool inh, List *newConstraints) { Relation rel; - Oid myrelid; List *listptr; /* * Grab an exclusive lock on the target table, which we will NOT * release until end of transaction. */ - rel = heap_openr(relationName, AccessExclusiveLock); - myrelid = RelationGetRelid(rel); + rel = heap_open(myrelid, AccessExclusiveLock); if (rel->rd_rel->relkind != RELKIND_RELATION) elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table", - relationName); + RelationGetRelationName(rel)); - if (!allowSystemTableMods && IsSystemRelationName(relationName)) + if (!allowSystemTableMods + && IsSystemRelationName(RelationGetRelationName(rel))) elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog", - relationName); + RelationGetRelationName(rel)); + if (!pg_class_ownercheck(myrelid, GetUserId())) - elog(ERROR, "ALTER TABLE: permission denied"); + elog(ERROR, "ALTER TABLE: \"%s\": permission denied", + RelationGetRelationName(rel)); if (inh) { @@ -1204,16 +1197,10 @@ AlterTableAddConstraint(char *relationName, foreach(child, children) { Oid childrelid = lfirsti(child); - char *childrelname; - Relation childrel; if (childrelid == myrelid) continue; - childrel = heap_open(childrelid, AccessExclusiveLock); - childrelname = pstrdup(RelationGetRelationName(childrel)); - heap_close(childrel, AccessExclusiveLock); - AlterTableAddConstraint(childrelname, false, newConstraints); - pfree(childrelname); + AlterTableAddConstraint(childrelid, false, newConstraints); } } @@ -1262,7 +1249,7 @@ AlterTableAddConstraint(char *relationName, pstate = make_parsestate(NULL); rte = addRangeTableEntryForRelation(pstate, myrelid, - makeAlias(relationName, NIL), + makeAlias(RelationGetRelationName(rel), NIL), false, true); addRTEtoQuery(pstate, rte, true, true); @@ -1286,7 +1273,7 @@ AlterTableAddConstraint(char *relationName, */ if (length(pstate->p_rtable) != 1) elog(ERROR, "Only relation '%s' can be referenced in CHECK", - relationName); + RelationGetRelationName(rel)); /* * Might as well try to reduce any @@ -1358,7 +1345,7 @@ AlterTableAddConstraint(char *relationName, int count; if (is_temp_rel_name(fkconstraint->pktable->relname) && - !is_temp_rel_name(relationName)) + !is_temp_rel_name(RelationGetRelationName(rel))) elog(ERROR, "ALTER TABLE / ADD CONSTRAINT: Unable to reference temporary table from permanent table constraint."); /* @@ -1408,7 +1395,7 @@ AlterTableAddConstraint(char *relationName, trig.tgargs[0] = fkconstraint->constr_name; else trig.tgargs[0] = "<unknown>"; - trig.tgargs[1] = (char *) relationName; + trig.tgargs[1] = pstrdup(RelationGetRelationName(rel)); trig.tgargs[2] = fkconstraint->pktable->relname; trig.tgargs[3] = fkconstraint->match_type; count = 4; @@ -1483,12 +1470,11 @@ AlterTableAddConstraint(char *relationName, * Christopher Kings-Lynne */ void -AlterTableDropConstraint(const char *relationName, +AlterTableDropConstraint(Oid myrelid, bool inh, const char *constrName, int behavior) { Relation rel; - Oid myrelid; int deleted; /* @@ -1502,19 +1488,21 @@ AlterTableDropConstraint(const char *relationName, * Acquire an exclusive lock on the target relation for the duration * of the operation. */ - rel = heap_openr(relationName, AccessExclusiveLock); - myrelid = RelationGetRelid(rel); + rel = heap_open(myrelid, AccessExclusiveLock); /* Disallow DROP CONSTRAINT on views, indexes, sequences, etc */ if (rel->rd_rel->relkind != RELKIND_RELATION) elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table", - relationName); + RelationGetRelationName(rel)); - if (!allowSystemTableMods && IsSystemRelationName(relationName)) + if (!allowSystemTableMods + && IsSystemRelationName(RelationGetRelationName(rel))) elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog", - relationName); + RelationGetRelationName(rel)); + if (!pg_class_ownercheck(myrelid, GetUserId())) - elog(ERROR, "ALTER TABLE: permission denied"); + elog(ERROR, "ALTER TABLE: \"%s\": permission denied", + RelationGetRelationName(rel)); /* * Since all we have is the name of the constraint, we have to look @@ -1554,30 +1542,7 @@ AlterTableDropConstraint(const char *relationName, * ALTER TABLE OWNER */ void -AlterTableOwner(const RangeVar *tgtrel, const char *newOwnerName) -{ - Relation rel; - Oid myrelid; - int32 newOwnerSysId; - - /* check that we are the superuser */ - if (!superuser()) - elog(ERROR, "ALTER TABLE: permission denied"); - - /* lookup the OID of the target relation */ - rel = relation_openrv(tgtrel, AccessExclusiveLock); - myrelid = RelationGetRelid(rel); - heap_close(rel, NoLock); /* close rel but keep lock! */ - - /* lookup the sysid of the new owner */ - newOwnerSysId = get_usesysid(newOwnerName); - - /* do all the actual work */ - AlterTableOwnerId(myrelid, newOwnerSysId); -} - -static void -AlterTableOwnerId(Oid relationOid, int32 newOwnerSysId) +AlterTableOwner(Oid relationOid, int32 newOwnerSysId) { Relation target_rel; Relation class_rel; @@ -1629,7 +1594,7 @@ AlterTableOwnerId(Oid relationOid, int32 newOwnerSysId) /* For each index, recursively change its ownership */ foreach(i, index_oid_list) { - AlterTableOwnerId(lfirsti(i), newOwnerSysId); + AlterTableOwner(lfirsti(i), newOwnerSysId); } freeList(index_oid_list); @@ -1640,7 +1605,7 @@ AlterTableOwnerId(Oid relationOid, int32 newOwnerSysId) /* If it has a toast table, recurse to change its ownership */ if (tuple_class->reltoastrelid != InvalidOid) { - AlterTableOwnerId(tuple_class->reltoastrelid, newOwnerSysId); + AlterTableOwner(tuple_class->reltoastrelid, newOwnerSysId); } } |