create/alter user extension

This one should work much better than the one I sent in previously. The
functionality is the same, but the patch was missing one file resulting
in
the compilation failing. The docs also received a minor fix.

Peter Eisentraut                  Sernanders väg 10:115
This commit is contained in:
Bruce Momjian 1999-11-30 03:57:29 +00:00
parent 3ab5b1f1e6
commit eebfb9baa5
6 changed files with 208 additions and 105 deletions

View File

@ -1,5 +1,5 @@
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/alter_user.sgml,v 1.8 1999/07/22 15:09:06 thomas Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/ref/alter_user.sgml,v 1.9 1999/11/30 03:57:22 momjian Exp $
Postgres documentation Postgres documentation
--> -->
@ -23,7 +23,10 @@ Postgres documentation
<date>1999-07-20</date> <date>1999-07-20</date>
</refsynopsisdivinfo> </refsynopsisdivinfo>
<synopsis> <synopsis>
ALTER USER <replaceable class="PARAMETER">username</replaceable> [ WITH PASSWORD <replaceable class="PARAMETER">password</replaceable> ] ALTER USER <replaceable class="PARAMETER">username</replaceable>
[ WITH
[ SYSID <replaceable class="PARAMETER">uid</replaceable> ]
[ PASSWORD <replaceable class="PARAMETER">password</replaceable> ] ]
[ CREATEDB | NOCREATEDB ] [ CREATEUSER | NOCREATEUSER ] [ CREATEDB | NOCREATEDB ] [ CREATEUSER | NOCREATEUSER ]
[ IN GROUP <replaceable class="PARAMETER">groupname</replaceable> [, ...] ] [ IN GROUP <replaceable class="PARAMETER">groupname</replaceable> [, ...] ]
[ VALID UNTIL '<replaceable class="PARAMETER">abstime</replaceable>' ] [ VALID UNTIL '<replaceable class="PARAMETER">abstime</replaceable>' ]
@ -62,6 +65,22 @@ ALTER USER <replaceable class="PARAMETER">username</replaceable> [ WITH PASSWORD
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><replaceable class="parameter">uid</replaceable></term>
<listitem>
<para>
The new <productname>PostgreSQL</productname> user id of the user.
Since this number is used as a key into the
<literal>pg_shadow</literal>/<literal>pg_user</literal> table
throughout the system catalogs, it is not recommended that you change
it unless the user in question does not own anything at all and/or
you really know what you are doing. Note that it is not necessary that
database and <acronym>UNIX</acronym> user ids match, but some people
choose to keep the numbers the same.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><replaceable class="PARAMETER"> groupname </replaceable></term> <term><replaceable class="PARAMETER"> groupname </replaceable></term>
<listitem> <listitem>
@ -130,9 +149,7 @@ ERROR: alterUser: user "username" does not exist
<para> <para>
<command>ALTER USER</command> is used to change the attributes of a user's <command>ALTER USER</command> is used to change the attributes of a user's
<productname>Postgres</productname> account. <productname>Postgres</productname> account.
Please note that it is not possible Also, it is only possible for the
to alter a user's "<literal>usesysid</literal>" via the alter user
statement. Also, it is only possible for the
<productname>Postgres</productname> <productname>Postgres</productname>
user or any user with read and modify permissions on user or any user with read and modify permissions on
<literal>pg_shadow</literal> to alter user passwords. <literal>pg_shadow</literal> to alter user passwords.
@ -161,9 +178,7 @@ ERROR: alterUser: user "username" does not exist
to create or remove a user account. to create or remove a user account.
</para> </para>
<para> <para>
In the current release (v6.5), the IN GROUP clause is parsed The IN GROUP clause is not yet implemented.
but has no affect. When it is fully implemented, it is
intended to modify the pg_group relation.
</para> </para>
</refsect2> </refsect2>
</refsect1> </refsect1>

View File

@ -1,5 +1,5 @@
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_user.sgml,v 1.9 1999/10/07 16:40:36 momjian Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/ref/create_user.sgml,v 1.10 1999/11/30 03:57:23 momjian Exp $
Postgres documentation Postgres documentation
--> -->
@ -23,8 +23,10 @@ Postgres documentation
<date>1999-07-20</date> <date>1999-07-20</date>
</refsynopsisdivinfo> </refsynopsisdivinfo>
<synopsis> <synopsis>
CREATE USER<replaceable class="PARAMETER"> username</replaceable> CREATE USER <replaceable class="PARAMETER">username</replaceable>
[ WITH PASSWORD <replaceable class="PARAMETER">password</replaceable> ] [ WITH
[ SYSID <replaceable class="PARAMETER">uid</replaceable> ]
[ PASSWORD <replaceable class="PARAMETER">password</replaceable> ] ]
[ CREATEDB | NOCREATEDB ] [ CREATEUSER | NOCREATEUSER ] [ CREATEDB | NOCREATEDB ] [ CREATEUSER | NOCREATEUSER ]
[ IN GROUP <replaceable class="PARAMETER">groupname</replaceable> [, ...] ] [ IN GROUP <replaceable class="PARAMETER">groupname</replaceable> [, ...] ]
[ VALID UNTIL '<replaceable class="PARAMETER">abstime</replaceable>' ] [ VALID UNTIL '<replaceable class="PARAMETER">abstime</replaceable>' ]
@ -49,11 +51,28 @@ CREATE USER<replaceable class="PARAMETER"> username</replaceable>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><replaceable class="parameter">uid</replaceable></term>
<listitem>
<para>
The <literal>SYSID</literal> clause can be used to choose
the <productname>PostgreSQL</productname> user id of the user
that is being created. It is not at all necessary that those
match the <acronym>UNIX</acronym> user ids, but some people
choose to keep the numbers the same.
</para>
<para>
If this is not specified, the highest assigned user id plus one
will be used as default.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><replaceable class="parameter">password</replaceable></term> <term><replaceable class="parameter">password</replaceable></term>
<listitem> <listitem>
<para> <para>
The WITH PASSWORD clause sets the user's password within The PASSWORD clause sets the user's password within
the "<filename>pg_shadow</filename>" table. For this reason, the "<filename>pg_shadow</filename>" table. For this reason,
<filename>"pg_shadow</filename>" is no <filename>"pg_shadow</filename>" is no
longer accessible to the instance of longer accessible to the instance of
@ -173,30 +192,9 @@ CREATE USER
</title> </title>
<para> <para>
CREATE USER will add a new user to an instance of CREATE USER will add a new user to an instance of
<productname>Postgres</productname>. <productname>PostgreSQL</productname>.
</para> </para>
<para>
The new user will be given a <filename>usesysid</filename> of:
<programlisting>
SELECT MAX(usesysid) + 1 FROM pg_shadow;
</programlisting>
This means that
<productname>Postgres</productname> users' <filename>usesysid</filename>s will not
correspond to their operating
system(OS) user ids. The exception to this rule is
the <literal>postgres</literal> superuser, whose OS user id
is used as the
<filename>usesysid</filename> during the initdb process.
If you still want the
OS user id and the <filename>usesysid</filename> to match
for any given user,
use the <application>createuser</application> script provided with
the <productname>Postgres</productname> distribution.
</para>
<refsect2 id="R2-SQL-CREATEUSER-3"> <refsect2 id="R2-SQL-CREATEUSER-3">
<refsect2info> <refsect2info>
<date>1998-09-21</date> <date>1998-09-21</date>
@ -216,19 +214,17 @@ SELECT MAX(usesysid) + 1 FROM pg_shadow;
Refer to the <filename>pg_shadow</filename> table for further information. Refer to the <filename>pg_shadow</filename> table for further information.
</para> </para>
<programlisting> <programlisting>
Table = pg_shadow Table "pg_shadow"
+--------------------------+--------------------------+-------+ Attribute | Type | Extra
| Field | Type | Length| -------------+---------+-------
+--------------------------+--------------------------+-------+ usename | name |
| usename | name | 32 | usesysid | int4 |
| usesysid | int4 | 4 | usecreatedb | bool |
| usecreatedb | bool | 1 | usetrace | bool |
| usetrace | bool | 1 | usesuper | bool |
| usesuper | bool | 1 | usecatupd | bool |
| usecatupd | bool | 1 | passwd | text |
| passwd | text | var | valuntil | abstime |
| valuntil | abstime | 4 |
+--------------------------+--------------------------+-------+
</programlisting> </programlisting>
</refsect2> </refsect2>
</refsect1> </refsect1>

View File

@ -5,7 +5,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: user.c,v 1.38 1999/11/24 16:52:32 momjian Exp $ * $Id: user.c,v 1.39 1999/11/30 03:57:23 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -105,14 +105,15 @@ DefineUser(CreateUserStmt *stmt, CommandDest dest)
TupleDesc pg_shadow_dsc; TupleDesc pg_shadow_dsc;
HeapScanDesc scan; HeapScanDesc scan;
HeapTuple tuple; HeapTuple tuple;
Datum datum; bool user_exists = false,
bool exists = false, sysid_exists = false,
n,
inblock, inblock,
havesysid,
havepassword, havepassword,
havevaluntil; havevaluntil;
int max_id = -1; int max_id = -1;
havesysid = stmt->sysid >= 0;
havepassword = stmt->password && stmt->password[0]; havepassword = stmt->password && stmt->password[0];
havevaluntil = stmt->validUntil && stmt->validUntil[0]; havevaluntil = stmt->validUntil && stmt->validUntil[0];
@ -129,13 +130,13 @@ DefineUser(CreateUserStmt *stmt, CommandDest dest)
if (pg_aclcheck(ShadowRelationName, pg_shadow, ACL_RD | ACL_WR | ACL_AP) != ACLCHECK_OK) if (pg_aclcheck(ShadowRelationName, pg_shadow, ACL_RD | ACL_WR | ACL_AP) != ACLCHECK_OK)
{ {
UserAbortTransactionBlock(); UserAbortTransactionBlock();
elog(ERROR, "defineUser: user \"%s\" does not have SELECT and INSERT privilege for \"%s\"", elog(ERROR, "DefineUser: user \"%s\" does not have SELECT and INSERT privilege for \"%s\"",
pg_shadow, ShadowRelationName); pg_shadow, ShadowRelationName);
return; return;
} }
/* /*
* Scan the pg_shadow relation to be certain the user doesn't already * Scan the pg_shadow relation to be certain the user or id doesn't already
* exist. Note we secure exclusive lock, because we also need to be * exist. Note we secure exclusive lock, because we also need to be
* sure of what the next usesysid should be, and we need to protect * sure of what the next usesysid should be, and we need to protect
* our update of the flat password file. * our update of the flat password file.
@ -144,25 +145,33 @@ DefineUser(CreateUserStmt *stmt, CommandDest dest)
pg_shadow_dsc = RelationGetDescr(pg_shadow_rel); pg_shadow_dsc = RelationGetDescr(pg_shadow_rel);
scan = heap_beginscan(pg_shadow_rel, false, SnapshotNow, 0, NULL); scan = heap_beginscan(pg_shadow_rel, false, SnapshotNow, 0, NULL);
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0))) while (!user_exists && !sysid_exists && HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
{ {
datum = heap_getattr(tuple, Anum_pg_shadow_usename, pg_shadow_dsc, &n); Datum datum;
bool null;
if (!exists && !strncmp((char *) datum, stmt->user, strlen(stmt->user))) datum = heap_getattr(tuple, Anum_pg_shadow_usename, pg_shadow_dsc, &null);
exists = true; user_exists = datum && !null && (strcmp((char *) datum, stmt->user) == 0);
datum = heap_getattr(tuple, Anum_pg_shadow_usesysid, pg_shadow_dsc, &n); datum = heap_getattr(tuple, Anum_pg_shadow_usesysid, pg_shadow_dsc, &null);
if ((int) datum > max_id) if (havesysid) /* customized id wanted */
max_id = (int) datum; sysid_exists = datum && !null && ((int)datum == stmt->sysid);
else /* pick 1 + max */
{
if ((int) datum > max_id)
max_id = (int) datum;
}
} }
heap_endscan(scan); heap_endscan(scan);
if (exists) if (user_exists || sysid_exists)
{ {
heap_close(pg_shadow_rel, AccessExclusiveLock); heap_close(pg_shadow_rel, AccessExclusiveLock);
UserAbortTransactionBlock(); UserAbortTransactionBlock();
elog(ERROR, if (user_exists)
"defineUser: user \"%s\" has already been created", stmt->user); elog(ERROR, "DefineUser: user name \"%s\" already exists", stmt->user);
else
elog(ERROR, "DefineUser: sysid %d is already assigned", stmt->sysid);
return; return;
} }
@ -184,7 +193,7 @@ DefineUser(CreateUserStmt *stmt, CommandDest dest)
"values('%s',%d,'%c','f','%c','%c',%s%s%s,%s%s%s)", "values('%s',%d,'%c','f','%c','%c',%s%s%s,%s%s%s)",
ShadowRelationName, ShadowRelationName,
stmt->user, stmt->user,
max_id + 1, havesysid ? stmt->sysid : max_id + 1,
(stmt->createdb && *stmt->createdb) ? 't' : 'f', (stmt->createdb && *stmt->createdb) ? 't' : 'f',
(stmt->createuser && *stmt->createuser) ? 't' : 'f', (stmt->createuser && *stmt->createuser) ? 't' : 'f',
((stmt->createdb && *stmt->createdb) || ((stmt->createdb && *stmt->createdb) ||
@ -234,6 +243,7 @@ AlterUser(AlterUserStmt *stmt, CommandDest dest)
TupleDesc pg_shadow_dsc; TupleDesc pg_shadow_dsc;
HeapTuple tuple; HeapTuple tuple;
bool inblock; bool inblock;
bool comma = false;
if (stmt->password) if (stmt->password)
CheckPgUserAclNotNull(); CheckPgUserAclNotNull();
@ -248,7 +258,7 @@ AlterUser(AlterUserStmt *stmt, CommandDest dest)
if (pg_aclcheck(ShadowRelationName, pg_shadow, ACL_RD | ACL_WR) != ACLCHECK_OK) if (pg_aclcheck(ShadowRelationName, pg_shadow, ACL_RD | ACL_WR) != ACLCHECK_OK)
{ {
UserAbortTransactionBlock(); UserAbortTransactionBlock();
elog(ERROR, "alterUser: user \"%s\" does not have SELECT and UPDATE privilege for \"%s\"", elog(ERROR, "AlterUser: user \"%s\" does not have SELECT and UPDATE privilege for \"%s\"",
pg_shadow, ShadowRelationName); pg_shadow, ShadowRelationName);
return; return;
} }
@ -268,43 +278,79 @@ AlterUser(AlterUserStmt *stmt, CommandDest dest)
{ {
heap_close(pg_shadow_rel, AccessExclusiveLock); heap_close(pg_shadow_rel, AccessExclusiveLock);
UserAbortTransactionBlock(); UserAbortTransactionBlock();
elog(ERROR, "alterUser: user \"%s\" does not exist", stmt->user); elog(ERROR, "AlterUser: user \"%s\" does not exist", stmt->user);
} }
/* look for duplicate sysid */
tuple = SearchSysCacheTuple(USESYSID,
Int32GetDatum(stmt->sysid),
0, 0, 0);
if (HeapTupleIsValid(tuple))
{
Datum datum;
bool null;
datum = heap_getattr(tuple, Anum_pg_shadow_usename, pg_shadow_dsc, &null);
if (datum && !null && strcmp((char *) datum, stmt->user) != 0)
{
heap_close(pg_shadow_rel, AccessExclusiveLock);
UserAbortTransactionBlock();
elog(ERROR, "AlterUser: sysid %d is already assigned", stmt->sysid);
}
}
/* /*
* Create the update statement to modify the user. * Create the update statement to modify the user.
* *
* XXX see diatribe in preceding routine. This code is just as bogus. * XXX see diatribe in preceding routine. This code is just as bogus.
*/ */
snprintf(sql, SQL_LENGTH, "update %s set", ShadowRelationName); snprintf(sql, SQL_LENGTH, "update %s set ", ShadowRelationName);
if (stmt->password) if (stmt->password)
{
snprintf(sql + strlen(sql), SQL_LENGTH - strlen(sql), snprintf(sql + strlen(sql), SQL_LENGTH - strlen(sql),
" passwd = '%s'", stmt->password); "passwd = '%s'", stmt->password);
comma = true;
}
if (stmt->sysid>=0)
{
if (comma)
strcat(sql, ", ");
snprintf(sql + strlen(sql), SQL_LENGTH - strlen(sql),
"usesysid = %d", stmt->sysid);
comma = true;
}
if (stmt->createdb) if (stmt->createdb)
{ {
if (comma)
strcat(sql, ", ");
snprintf(sql + strlen(sql), SQL_LENGTH - strlen(sql), snprintf(sql + strlen(sql), SQL_LENGTH - strlen(sql),
"%s usecreatedb='%s'", "usecreatedb='%c'",
stmt->password ? "," : "", *stmt->createdb ? 't' : 'f');
*stmt->createdb ? "t" : "f"); comma = true;
} }
if (stmt->createuser) if (stmt->createuser)
{ {
if (comma)
strcat(sql, ", ");
snprintf(sql + strlen(sql), SQL_LENGTH - strlen(sql), snprintf(sql + strlen(sql), SQL_LENGTH - strlen(sql),
"%s usesuper='%s'", "usesuper='%c'",
(stmt->password || stmt->createdb) ? "," : "", *stmt->createuser ? 't' : 'f');
*stmt->createuser ? "t" : "f"); comma = true;
} }
if (stmt->validUntil) if (stmt->validUntil)
{ {
if (comma)
strcat(sql, ", ");
snprintf(sql + strlen(sql), SQL_LENGTH - strlen(sql), snprintf(sql + strlen(sql), SQL_LENGTH - strlen(sql),
"%s valuntil='%s'", "valuntil='%s'",
(stmt->password || stmt->createdb || stmt->createuser) ? "," : "",
stmt->validUntil); stmt->validUntil);
} }
snprintf(sql + strlen(sql), SQL_LENGTH - strlen(sql), snprintf(sql + strlen(sql), SQL_LENGTH - strlen(sql),
" where usename = '%s'", " where usename = '%s'",
@ -362,7 +408,7 @@ RemoveUser(char *user, CommandDest dest)
if (pg_aclcheck(ShadowRelationName, pg_shadow, ACL_RD | ACL_WR) != ACLCHECK_OK) if (pg_aclcheck(ShadowRelationName, pg_shadow, ACL_RD | ACL_WR) != ACLCHECK_OK)
{ {
UserAbortTransactionBlock(); UserAbortTransactionBlock();
elog(ERROR, "removeUser: user \"%s\" does not have SELECT and DELETE privilege for \"%s\"", elog(ERROR, "RemoveUser: user \"%s\" does not have SELECT and DELETE privilege for \"%s\"",
pg_shadow, ShadowRelationName); pg_shadow, ShadowRelationName);
} }
@ -381,7 +427,7 @@ RemoveUser(char *user, CommandDest dest)
{ {
heap_close(pg_shadow_rel, AccessExclusiveLock); heap_close(pg_shadow_rel, AccessExclusiveLock);
UserAbortTransactionBlock(); UserAbortTransactionBlock();
elog(ERROR, "removeUser: user \"%s\" does not exist", user); elog(ERROR, "RemoveUser: user \"%s\" does not exist", user);
} }
usesysid = (int32) heap_getattr(tuple, Anum_pg_shadow_usesysid, pg_dsc, &n); usesysid = (int32) heap_getattr(tuple, Anum_pg_shadow_usesysid, pg_dsc, &n);

View File

@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.115 1999/11/20 21:39:36 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.116 1999/11/30 03:57:24 momjian Exp $
* *
* HISTORY * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
@ -137,6 +137,7 @@ static Node *doNegate(Node *n);
%type <pboolean> user_createdb_clause, user_createuser_clause %type <pboolean> user_createdb_clause, user_createuser_clause
%type <str> user_passwd_clause %type <str> user_passwd_clause
%type <ival> sysid_clause
%type <str> user_valid_clause %type <str> user_valid_clause
%type <list> user_group_list, user_group_clause %type <list> user_group_list, user_group_clause
@ -295,6 +296,7 @@ static Node *doNegate(Node *n);
VALUES, VARCHAR, VARYING, VIEW, VALUES, VARCHAR, VARYING, VIEW,
WHEN, WHERE, WITH, WORK, YEAR_P, ZONE WHEN, WHERE, WITH, WORK, YEAR_P, ZONE
/* Keywords (in SQL3 reserved words) */ /* Keywords (in SQL3 reserved words) */
%token DEFERRABLE, DEFERRED, %token DEFERRABLE, DEFERRED,
IMMEDIATE, INITIALLY, IMMEDIATE, INITIALLY,
@ -323,7 +325,7 @@ static Node *doNegate(Node *n);
NEW, NOCREATEDB, NOCREATEUSER, NONE, NOTHING, NOTIFY, NOTNULL, NEW, NOCREATEDB, NOCREATEUSER, NONE, NOTHING, NOTIFY, NOTNULL,
OFFSET, OIDS, OPERATOR, PASSWORD, PROCEDURAL, OFFSET, OIDS, OPERATOR, PASSWORD, PROCEDURAL,
RENAME, RESET, RETURNS, ROW, RULE, RENAME, RESET, RETURNS, ROW, RULE,
SEQUENCE, SERIAL, SETOF, SHARE, SHOW, START, STATEMENT, STDIN, STDOUT, SEQUENCE, SERIAL, SETOF, SHARE, SHOW, START, STATEMENT, STDIN, STDOUT, SYSID,
TRUNCATE, TRUSTED, TRUNCATE, TRUSTED,
UNLISTEN, UNTIL, VACUUM, VALID, VERBOSE, VERSION UNLISTEN, UNTIL, VACUUM, VALID, VERBOSE, VERSION
@ -443,18 +445,34 @@ stmt : AddAttrStmt
* *
*****************************************************************************/ *****************************************************************************/
CreateUserStmt: CREATE USER UserId user_passwd_clause user_createdb_clause CreateUserStmt: CREATE USER UserId
user_createuser_clause user_group_clause user_valid_clause user_createdb_clause user_createuser_clause user_group_clause
user_valid_clause
{ {
CreateUserStmt *n = makeNode(CreateUserStmt); CreateUserStmt *n = makeNode(CreateUserStmt);
n->user = $3; n->user = $3;
n->password = $4; n->sysid = -1;
n->createdb = $5; n->password = NULL;
n->createuser = $6; n->createdb = $4;
n->groupElts = $7; n->createuser = $5;
n->validUntil = $8; n->groupElts = $6;
n->validUntil = $7;
$$ = (Node *)n; $$ = (Node *)n;
} }
| CREATE USER UserId WITH sysid_clause user_passwd_clause
user_createdb_clause user_createuser_clause user_group_clause
user_valid_clause
{
CreateUserStmt *n = makeNode(CreateUserStmt);
n->user = $3;
n->sysid = $5;
n->password = $6;
n->createdb = $7;
n->createuser = $8;
n->groupElts = $9;
n->validUntil = $10;
$$ = (Node *)n;
}
; ;
/***************************************************************************** /*****************************************************************************
@ -464,16 +482,31 @@ CreateUserStmt: CREATE USER UserId user_passwd_clause user_createdb_clause
* *
*****************************************************************************/ *****************************************************************************/
AlterUserStmt: ALTER USER UserId user_passwd_clause user_createdb_clause AlterUserStmt: ALTER USER UserId user_createdb_clause
user_createuser_clause user_group_clause user_valid_clause user_createuser_clause user_group_clause user_valid_clause
{ {
AlterUserStmt *n = makeNode(AlterUserStmt); AlterUserStmt *n = makeNode(AlterUserStmt);
n->user = $3; n->user = $3;
n->password = $4; n->sysid = -1;
n->createdb = $5; n->password = NULL;
n->createuser = $6; n->createdb = $4;
n->groupElts = $7; n->createuser = $5;
n->validUntil = $8; n->groupElts = $6;
n->validUntil = $7;
$$ = (Node *)n;
}
| ALTER USER UserId WITH sysid_clause user_passwd_clause
user_createdb_clause
user_createuser_clause user_group_clause user_valid_clause
{
AlterUserStmt *n = makeNode(AlterUserStmt);
n->user = $3;
n->sysid = $5;
n->password = $6;
n->createdb = $7;
n->createuser = $8;
n->groupElts = $9;
n->validUntil = $10;
$$ = (Node *)n; $$ = (Node *)n;
} }
; ;
@ -493,10 +526,14 @@ DropUserStmt: DROP USER UserId
} }
; ;
user_passwd_clause: WITH PASSWORD UserId { $$ = $3; } user_passwd_clause: PASSWORD UserId { $$ = $2; }
| /*EMPTY*/ { $$ = NULL; } | /*EMPTY*/ { $$ = NULL; }
; ;
sysid_clause: SYSID Iconst { $$ = $2; }
| /*EMPTY*/ { $$ = -1; }
;
user_createdb_clause: CREATEDB user_createdb_clause: CREATEDB
{ {
bool* b; bool* b;
@ -537,7 +574,13 @@ user_group_list: user_group_list ',' UserId
} }
; ;
user_group_clause: IN GROUP user_group_list { $$ = $3; } user_group_clause: IN GROUP user_group_list
{
/* the backend doesn't actually process this,
* so an error message is probably fairer */
yyerror("IN GROUP is not implemented");
/* $$ = $3; */
}
| /*EMPTY*/ { $$ = NULL; } | /*EMPTY*/ { $$ = NULL; }
; ;
@ -4764,6 +4807,7 @@ ColId: IDENT { $$ = $1; }
| STATEMENT { $$ = "statement"; } | STATEMENT { $$ = "statement"; }
| STDIN { $$ = "stdin"; } | STDIN { $$ = "stdin"; }
| STDOUT { $$ = "stdout"; } | STDOUT { $$ = "stdout"; }
| SYSID { $$ = "sysid"; }
| TIME { $$ = "time"; } | TIME { $$ = "time"; }
| TIMESTAMP { $$ = "timestamp"; } | TIMESTAMP { $$ = "timestamp"; }
| TIMEZONE_HOUR { $$ = "timezone_hour"; } | TIMEZONE_HOUR { $$ = "timezone_hour"; }

View File

@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.63 1999/10/15 01:49:41 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.64 1999/11/30 03:57:26 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -219,6 +219,7 @@ static ScanKeyword ScanKeywords[] = {
{"stdin", STDIN}, {"stdin", STDIN},
{"stdout", STDOUT}, {"stdout", STDOUT},
{"substring", SUBSTRING}, {"substring", SUBSTRING},
{"sysid", SYSID},
{"table", TABLE}, {"table", TABLE},
{"temp", TEMP}, {"temp", TEMP},
{"temporary", TEMPORARY}, {"temporary", TEMPORARY},

View File

@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: parsenodes.h,v 1.86 1999/10/26 03:12:39 momjian Exp $ * $Id: parsenodes.h,v 1.87 1999/11/30 03:57:29 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -237,6 +237,7 @@ typedef struct CreateUserStmt
NodeTag type; NodeTag type;
char *user; /* PostgreSQL user login */ char *user; /* PostgreSQL user login */
char *password; /* PostgreSQL user password */ char *password; /* PostgreSQL user password */
int sysid; /* PgSQL system id (-1 if don't care) */
bool *createdb; /* Can the user create databases? */ bool *createdb; /* Can the user create databases? */
bool *createuser; /* Can this user create users? */ bool *createuser; /* Can this user create users? */
List *groupElts; /* The groups the user is a member of */ List *groupElts; /* The groups the user is a member of */