Commit 7f171b59 authored by Bruce Momjian's avatar Bruce Momjian

This patch implements the following command:

ALTER TABLE <tablename> OWNER TO <username>

Only a superuser may execute the command.

--
Mark Hollomon
mhh@mindspring.com
parent 65edb541
......@@ -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__
......@@ -1449,6 +1450,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
*/
......
......@@ -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"; }
......
......@@ -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},
......
......@@ -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;
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: command.h,v 1.22 2000/07/18 03:57:32 tgl Exp $
* $Id: command.h,v 1.23 2000/09/12 05:09:47 momjian Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -61,6 +61,8 @@ extern void AlterTableDropConstraint(const char *relationName,
extern void AlterTableCreateToastTable(const char *relationName,
bool silent);
extern void AlterTableOwner(const char *relationName, const char *newOwnerName);
/*
* LOCK
*/
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: parsenodes.h,v 1.111 2000/08/11 23:46:54 tgl Exp $
* $Id: parsenodes.h,v 1.112 2000/09/12 05:09:50 momjian Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -95,11 +95,13 @@ typedef struct Query
typedef struct AlterTableStmt
{
NodeTag type;
char subtype; /* A = add, T = alter, D = drop, C = add
* constr, X = drop constr */
char subtype; /* A = add column, T = alter column, D = drop column,
* C = add constraint, X = drop constraint,
* E = add toast table,
* U = change owner */
char *relname; /* table to work on */
bool inh; /* recursively on children? */
char *name; /* column or constraint name to act on */
char *name; /* column or constraint name to act on, or new owner */
Node *def; /* definition of new column or constraint */
int behavior; /* CASCADE or RESTRICT drop behavior */
} AlterTableStmt;
......
......@@ -10,7 +10,7 @@ import org.postgresql.largeobject.*;
import org.postgresql.util.*;
/**
* $Id: Connection.java,v 1.5 2000/09/12 04:58:47 momjian Exp $
* $Id: Connection.java,v 1.6 2000/09/12 05:09:54 momjian Exp $
*
* This abstract class is used by org.postgresql.Driver to open either the JDBC1 or
* JDBC2 versions of the Connection class.
......@@ -112,12 +112,12 @@ public abstract class Connection
throw new PSQLException("postgresql.con.pass");
this_driver = d;
this_url = new String(url);
PG_DATABASE = new String(database);
PG_PASSWORD = new String(info.getProperty("password"));
PG_USER = new String(info.getProperty("user"));
this_url = url;
PG_DATABASE = database;
PG_PASSWORD = info.getProperty("password");
PG_USER = info.getProperty("user");
PG_PORT = port;
PG_HOST = new String(host);
PG_HOST = host;
PG_STATUS = CONNECTION_BAD;
encoding = info.getProperty("charSet"); // could be null
......
......@@ -242,8 +242,8 @@ public class Driver implements java.sql.Driver
{
int state = -1;
Properties urlProps = new Properties(defaults);
String key = new String();
String value = new String();
String key = "";
String value = "";
StringTokenizer st = new StringTokenizer(url, ":/;=&?", true);
for (int count = 0; (st.hasMoreTokens()); count++) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment