diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/commands/command.c | 67 | ||||
-rw-r--r-- | src/backend/parser/gram.y | 15 | ||||
-rw-r--r-- | src/backend/parser/keywords.c | 3 | ||||
-rw-r--r-- | src/backend/tcop/utility.c | 5 |
4 files changed, 85 insertions, 5 deletions
diff --git a/src/backend/commands/command.c b/src/backend/commands/command.c index d0faa943cfd..9535e197417 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.101 2000/09/12 04:49:06 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.102 2000/09/12 05:09:43 momjian Exp $ * * NOTES * The PerformAddAttribute() code, like most of the relation @@ -47,6 +47,7 @@ #include "utils/temprel.h" #include "executor/spi_priv.h" #include "catalog/pg_index.h" +#include "catalog/pg_shadow.h" #include "utils/relcache.h" #ifdef _DROP_COLUMN_HACK__ @@ -1450,6 +1451,70 @@ AlterTableDropConstraint(const char *relationName, /* + * ALTER TABLE OWNER + */ +void +AlterTableOwner(const char *relationName, const char *newOwnerName) +{ + Relation class_rel; + HeapTuple tuple; + int4 newOwnerSysid; + Relation idescs[Num_pg_class_indices]; + + /* + * first check that we are a superuser + */ + if (! superuser() ) + elog(ERROR, "ALTER TABLE: permission denied"); + + /* + * look up the new owner in pg_shadow and get the sysid + */ + tuple = SearchSysCacheTuple(SHADOWNAME, PointerGetDatum(newOwnerName), + 0, 0, 0); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "ALTER TABLE: user \"%s\" not found", newOwnerName); + + newOwnerSysid = ((Form_pg_shadow) GETSTRUCT(tuple))->usesysid; + heap_freetuple(tuple); + + /* + * find the table's entry in pg_class and lock it for writing + */ + class_rel = heap_openr(RelationRelationName, RowExclusiveLock); + + tuple = SearchSysCacheTuple(RELNAME, PointerGetDatum(relationName), + 0, 0, 0); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "ALTER TABLE: relation \"%s\" not found", + relationName); + + if (((Form_pg_class) GETSTRUCT(tuple))->relkind != RELKIND_RELATION) + elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table", + relationName); + + /* + * modify the table's entry and write to the heap + */ + ((Form_pg_class) GETSTRUCT(tuple))->relowner = newOwnerSysid; + + heap_update(class_rel, &tuple->t_self, tuple, NULL); + + /* Keep the catalog indices up to date */ + CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs); + CatalogIndexInsert(idescs, Num_pg_class_indices, class_rel, tuple); + CatalogCloseIndices(Num_pg_class_indices, idescs); + + /* + * unlock everything and return + */ + heap_freetuple(tuple); + heap_close(class_rel, RowExclusiveLock); + + return; +} + +/* * ALTER TABLE CREATE TOAST TABLE */ void diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index d57fcddaaec..7e970ab1871 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.187 2000/08/26 21:53:43 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.188 2000/09/12 05:09:44 momjian Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -350,7 +350,7 @@ static void doNegateFloat(Value *v); LANCOMPILER, LIMIT, LISTEN, LOAD, LOCATION, LOCK_P, MAXVALUE, MINVALUE, MODE, MOVE, NEW, NOCREATEDB, NOCREATEUSER, NONE, NOTHING, NOTIFY, NOTNULL, - OFFSET, OIDS, OPERATOR, PASSWORD, PROCEDURAL, + OFFSET, OIDS, OPERATOR, OWNER, PASSWORD, PROCEDURAL, REINDEX, RENAME, RESET, RETURNS, ROW, RULE, SEQUENCE, SERIAL, SETOF, SHARE, SHOW, START, STATEMENT, STDIN, STDOUT, SYSID, TEMP, TOAST, TRUNCATE, TRUSTED, @@ -1031,6 +1031,16 @@ AlterTableStmt: n->relname = $3; $$ = (Node *)n; } + +/* ALTER TABLE <name> OWNER TO UserId */ + | ALTER TABLE relation_name OWNER TO UserId + { + AlterTableStmt *n = makeNode(AlterTableStmt); + n->subtype = 'U'; + n->relname = $3; + n->name = $6; + $$ = (Node *)n; + } ; alter_column_action: @@ -5641,6 +5651,7 @@ TokenId: ABSOLUTE { $$ = "absolute"; } | OIDS { $$ = "oids"; } | OPERATOR { $$ = "operator"; } | OPTION { $$ = "option"; } + | OWNER { $$ = "owner"; } | PARTIAL { $$ = "partial"; } | PASSWORD { $$ = "password"; } | PENDANT { $$ = "pendant"; } diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c index 848f1dc8d6b..3562537c0a8 100644 --- a/src/backend/parser/keywords.c +++ b/src/backend/parser/keywords.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.80 2000/08/06 18:05:22 thomas Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.81 2000/09/12 05:09:44 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -196,6 +196,7 @@ static ScanKeyword ScanKeywords[] = { {"out", OUT}, {"outer", OUTER_P}, {"overlaps", OVERLAPS}, + {"owner", OWNER}, {"partial", PARTIAL}, {"password", PASSWORD}, {"path", PATH_P}, diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index d603914c514..9edb092e62d 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.93 2000/09/12 04:49:11 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.94 2000/09/12 05:09:45 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -371,6 +371,9 @@ ProcessUtility(Node *parsetree, case 'E': /* CREATE TOAST TABLE */ AlterTableCreateToastTable(stmt->relname, false); break; + case 'U': /* ALTER OWNER */ + AlterTableOwner(stmt->relname, stmt->name); + break; default: /* oops */ elog(ERROR, "T_AlterTableStmt: unknown subtype"); break; |