Commit e7889b83 authored by Tom Lane's avatar Tom Lane

Support SET FROM CURRENT in CREATE/ALTER FUNCTION, ALTER DATABASE, ALTER ROLE.

(Actually, it works as a plain statement too, but I didn't document that
because it seems a bit useless.)  Unify VariableResetStmt with
VariableSetStmt, and clean up some ancient cruft in the representation of
same.
parent dd4594e3
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_database.sgml,v 1.19 2006/09/16 00:30:16 momjian Exp $ $PostgreSQL: pgsql/doc/src/sgml/ref/alter_database.sgml,v 1.20 2007/09/03 18:46:29 tgl Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -26,12 +26,14 @@ where <replaceable class="PARAMETER">option</replaceable> can be: ...@@ -26,12 +26,14 @@ where <replaceable class="PARAMETER">option</replaceable> can be:
CONNECTION LIMIT <replaceable class="PARAMETER">connlimit</replaceable> CONNECTION LIMIT <replaceable class="PARAMETER">connlimit</replaceable>
ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> SET <replaceable>parameter</replaceable> { TO | = } { <replaceable>value</replaceable> | DEFAULT }
ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> RESET <replaceable>parameter</replaceable>
ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable>newname</replaceable> ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable>newname</replaceable>
ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> OWNER TO <replaceable>new_owner</replaceable> ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> OWNER TO <replaceable>new_owner</replaceable>
ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> SET <replaceable>configuration_parameter</replaceable> { TO | = } { <replaceable>value</replaceable> | DEFAULT }
ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> SET <replaceable>configuration_parameter</replaceable> FROM CURRENT
ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> RESET <replaceable>configuration_parameter</replaceable>
ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> RESET ALL
</synopsis> </synopsis>
</refsynopsisdiv> </refsynopsisdiv>
...@@ -49,20 +51,7 @@ ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> OWNER TO <repla ...@@ -49,20 +51,7 @@ ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> OWNER TO <repla
</para> </para>
<para> <para>
The second and third forms change the session default for a run-time The second form changes the name of the database. Only the database
configuration variable for a <productname>PostgreSQL</productname>
database. Whenever a new session is subsequently started in that
database, the specified value becomes the session default value.
The database-specific default overrides whatever setting is present
in <filename>postgresql.conf</> or has been received from the
<command>postgres</command> command line. Only the database
owner or a superuser can change the session defaults for a
database. Certain variables cannot be set this way, or can only be
set by a superuser.
</para>
<para>
The fourth form changes the name of the database. Only the database
owner or a superuser can rename a database; non-superuser owners must owner or a superuser can rename a database; non-superuser owners must
also have the also have the
<literal>CREATEDB</literal> privilege. The current database cannot <literal>CREATEDB</literal> privilege. The current database cannot
...@@ -71,12 +60,25 @@ ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> OWNER TO <repla ...@@ -71,12 +60,25 @@ ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> OWNER TO <repla
</para> </para>
<para> <para>
The fifth form changes the owner of the database. The third form changes the owner of the database.
To alter the owner, you must own the database and also be a direct or To alter the owner, you must own the database and also be a direct or
indirect member of the new owning role, and you must have the indirect member of the new owning role, and you must have the
<literal>CREATEDB</literal> privilege. <literal>CREATEDB</literal> privilege.
(Note that superusers have all these privileges automatically.) (Note that superusers have all these privileges automatically.)
</para> </para>
<para>
The remaining forms change the session default for a run-time
configuration variable for a <productname>PostgreSQL</productname>
database. Whenever a new session is subsequently started in that
database, the specified value becomes the session default value.
The database-specific default overrides whatever setting is present
in <filename>postgresql.conf</> or has been received from the
<command>postgres</command> command line. Only the database
owner or a superuser can change the session defaults for a
database. Certain variables cannot be set this way, or can only be
set by a superuser.
</para>
</refsect1> </refsect1>
<refsect1> <refsect1>
...@@ -102,8 +104,26 @@ ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> OWNER TO <repla ...@@ -102,8 +104,26 @@ ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> OWNER TO <repla
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><replaceable>newname</replaceable></term>
<listitem>
<para>
The new name of the database.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">new_owner</replaceable></term>
<listitem>
<para>
The new owner of the database.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><replaceable>parameter</replaceable></term> <term><replaceable>configuration_parameter</replaceable></term>
<term><replaceable>value</replaceable></term> <term><replaceable>value</replaceable></term>
<listitem> <listitem>
<para> <para>
...@@ -114,6 +134,8 @@ ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> OWNER TO <repla ...@@ -114,6 +134,8 @@ ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> OWNER TO <repla
database-specific setting is removed, so the system-wide default database-specific setting is removed, so the system-wide default
setting will be inherited in new sessions. Use <literal>RESET setting will be inherited in new sessions. Use <literal>RESET
ALL</literal> to clear all database-specific settings. ALL</literal> to clear all database-specific settings.
<literal>SET FROM CURRENT</> saves the session's current value of
the parameter as the database-specific value.
</para> </para>
<para> <para>
...@@ -123,24 +145,6 @@ ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> OWNER TO <repla ...@@ -123,24 +145,6 @@ ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> OWNER TO <repla
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><replaceable>newname</replaceable></term>
<listitem>
<para>
The new name of the database.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">new_owner</replaceable></term>
<listitem>
<para>
The new owner of the database.
</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect1> </refsect1>
...@@ -148,10 +152,10 @@ ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> OWNER TO <repla ...@@ -148,10 +152,10 @@ ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> OWNER TO <repla
<title>Notes</title> <title>Notes</title>
<para> <para>
It is also possible to tie a session default to a specific user It is also possible to tie a session default to a specific role
rather than to a database; see rather than to a database; see
<xref linkend="sql-alteruser" endterm="sql-alteruser-title">. <xref linkend="sql-alterrole" endterm="sql-alterrole-title">.
User-specific settings override database-specific Role-specific settings override database-specific
ones if there is a conflict. ones if there is a conflict.
</para> </para>
</refsect1> </refsect1>
......
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_function.sgml,v 1.14 2007/09/03 00:39:12 tgl Exp $ $PostgreSQL: pgsql/doc/src/sgml/ref/alter_function.sgml,v 1.15 2007/09/03 18:46:29 tgl Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -21,7 +21,7 @@ PostgreSQL documentation ...@@ -21,7 +21,7 @@ PostgreSQL documentation
<refsynopsisdiv> <refsynopsisdiv>
<synopsis> <synopsis>
ALTER FUNCTION <replaceable>name</replaceable> ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ALTER FUNCTION <replaceable>name</replaceable> ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] )
<replaceable class="PARAMETER">action</replaceable> [, ... ] [ RESTRICT ] <replaceable class="PARAMETER">action</replaceable> [ ... ] [ RESTRICT ]
ALTER FUNCTION <replaceable>name</replaceable> ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ALTER FUNCTION <replaceable>name</replaceable> ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] )
RENAME TO <replaceable>new_name</replaceable> RENAME TO <replaceable>new_name</replaceable>
ALTER FUNCTION <replaceable>name</replaceable> ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ALTER FUNCTION <replaceable>name</replaceable> ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] )
...@@ -36,8 +36,10 @@ where <replaceable class="PARAMETER">action</replaceable> is one of: ...@@ -36,8 +36,10 @@ where <replaceable class="PARAMETER">action</replaceable> is one of:
[ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
COST <replaceable class="parameter">execution_cost</replaceable> COST <replaceable class="parameter">execution_cost</replaceable>
ROWS <replaceable class="parameter">result_rows</replaceable> ROWS <replaceable class="parameter">result_rows</replaceable>
SET <replaceable class="parameter">parameter</replaceable> { TO | = } { <replaceable class="parameter">value</replaceable> | DEFAULT } SET <replaceable class="parameter">configuration_parameter</replaceable> { TO | = } { <replaceable class="parameter">value</replaceable> | DEFAULT }
RESET <replaceable class="parameter">parameter</replaceable> SET <replaceable class="parameter">configuration_parameter</replaceable> FROM CURRENT
RESET <replaceable class="parameter">configuration_parameter</replaceable>
RESET ALL
</synopsis> </synopsis>
</refsynopsisdiv> </refsynopsisdiv>
...@@ -215,7 +217,7 @@ where <replaceable class="PARAMETER">action</replaceable> is one of: ...@@ -215,7 +217,7 @@ where <replaceable class="PARAMETER">action</replaceable> is one of:
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><replaceable>parameter</replaceable></term> <term><replaceable>configuration_parameter</replaceable></term>
<term><replaceable>value</replaceable></term> <term><replaceable>value</replaceable></term>
<listitem> <listitem>
<para> <para>
...@@ -226,6 +228,8 @@ where <replaceable class="PARAMETER">action</replaceable> is one of: ...@@ -226,6 +228,8 @@ where <replaceable class="PARAMETER">action</replaceable> is one of:
setting is removed, so that the function executes with the value setting is removed, so that the function executes with the value
present in its environment. Use <literal>RESET present in its environment. Use <literal>RESET
ALL</literal> to clear all function-local settings. ALL</literal> to clear all function-local settings.
<literal>SET FROM CURRENT</> saves the session's current value of
the parameter as the value to be applied when the function is entered.
</para> </para>
<para> <para>
......
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_role.sgml,v 1.8 2007/05/15 19:43:51 neilc Exp $ $PostgreSQL: pgsql/doc/src/sgml/ref/alter_role.sgml,v 1.9 2007/09/03 18:46:29 tgl Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -37,7 +37,9 @@ where <replaceable class="PARAMETER">option</replaceable> can be: ...@@ -37,7 +37,9 @@ where <replaceable class="PARAMETER">option</replaceable> can be:
ALTER ROLE <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable>newname</replaceable> ALTER ROLE <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable>newname</replaceable>
ALTER ROLE <replaceable class="PARAMETER">name</replaceable> SET <replaceable>configuration_parameter</replaceable> { TO | = } { <replaceable>value</replaceable> | DEFAULT } ALTER ROLE <replaceable class="PARAMETER">name</replaceable> SET <replaceable>configuration_parameter</replaceable> { TO | = } { <replaceable>value</replaceable> | DEFAULT }
ALTER ROLE <replaceable class="PARAMETER">name</replaceable> SET <replaceable>configuration_parameter</replaceable> FROM CURRENT
ALTER ROLE <replaceable class="PARAMETER">name</replaceable> RESET <replaceable>configuration_parameter</replaceable> ALTER ROLE <replaceable class="PARAMETER">name</replaceable> RESET <replaceable>configuration_parameter</replaceable>
ALTER ROLE <replaceable class="PARAMETER">name</replaceable> RESET ALL
</synopsis> </synopsis>
</refsynopsisdiv> </refsynopsisdiv>
...@@ -77,7 +79,7 @@ ALTER ROLE <replaceable class="PARAMETER">name</replaceable> RESET <replaceable> ...@@ -77,7 +79,7 @@ ALTER ROLE <replaceable class="PARAMETER">name</replaceable> RESET <replaceable>
</para> </para>
<para> <para>
The third and the fourth variant change a role's session default for The remaining variants change a role's session default for
a specified configuration variable. Whenever the role subsequently a specified configuration variable. Whenever the role subsequently
starts a new session, the specified value becomes the session default, starts a new session, the specified value becomes the session default,
overriding whatever setting is present in <filename>postgresql.conf</> overriding whatever setting is present in <filename>postgresql.conf</>
...@@ -155,6 +157,8 @@ ALTER ROLE <replaceable class="PARAMETER">name</replaceable> RESET <replaceable> ...@@ -155,6 +157,8 @@ ALTER ROLE <replaceable class="PARAMETER">name</replaceable> RESET <replaceable>
role-specific variable setting is removed, so the role will role-specific variable setting is removed, so the role will
inherit the system-wide default setting in new sessions. Use inherit the system-wide default setting in new sessions. Use
<literal>RESET ALL</literal> to clear all role-specific settings. <literal>RESET ALL</literal> to clear all role-specific settings.
<literal>SET FROM CURRENT</> saves the session's current value of
the parameter as the role-specific value.
</para> </para>
<para> <para>
......
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_user.sgml,v 1.43 2007/05/15 19:43:51 neilc Exp $ $PostgreSQL: pgsql/doc/src/sgml/ref/alter_user.sgml,v 1.44 2007/09/03 18:46:29 tgl Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -37,7 +37,9 @@ where <replaceable class="PARAMETER">option</replaceable> can be: ...@@ -37,7 +37,9 @@ where <replaceable class="PARAMETER">option</replaceable> can be:
ALTER USER <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable>newname</replaceable> ALTER USER <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable>newname</replaceable>
ALTER USER <replaceable class="PARAMETER">name</replaceable> SET <replaceable>configuration_parameter</replaceable> { TO | = } { <replaceable>value</replaceable> | DEFAULT } ALTER USER <replaceable class="PARAMETER">name</replaceable> SET <replaceable>configuration_parameter</replaceable> { TO | = } { <replaceable>value</replaceable> | DEFAULT }
ALTER USER <replaceable class="PARAMETER">name</replaceable> SET <replaceable>configuration_parameter</replaceable> FROM CURRENT
ALTER USER <replaceable class="PARAMETER">name</replaceable> RESET <replaceable>configuration_parameter</replaceable> ALTER USER <replaceable class="PARAMETER">name</replaceable> RESET <replaceable>configuration_parameter</replaceable>
ALTER USER <replaceable class="PARAMETER">name</replaceable> RESET ALL
</synopsis> </synopsis>
</refsynopsisdiv> </refsynopsisdiv>
......
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/ref/create_function.sgml,v 1.76 2007/09/03 00:39:13 tgl Exp $ $PostgreSQL: pgsql/doc/src/sgml/ref/create_function.sgml,v 1.77 2007/09/03 18:46:29 tgl Exp $
--> -->
<refentry id="SQL-CREATEFUNCTION"> <refentry id="SQL-CREATEFUNCTION">
...@@ -28,7 +28,7 @@ CREATE [ OR REPLACE ] FUNCTION ...@@ -28,7 +28,7 @@ CREATE [ OR REPLACE ] FUNCTION
| [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER | [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
| COST <replaceable class="parameter">execution_cost</replaceable> | COST <replaceable class="parameter">execution_cost</replaceable>
| ROWS <replaceable class="parameter">result_rows</replaceable> | ROWS <replaceable class="parameter">result_rows</replaceable>
| SET <replaceable class="parameter">parameter</replaceable> { TO | = } { <replaceable class="parameter">value</replaceable> | DEFAULT } | SET <replaceable class="parameter">configuration_parameter</replaceable> { TO <replaceable class="parameter">value</replaceable> | = <replaceable class="parameter">value</replaceable> | FROM CURRENT }
| AS '<replaceable class="parameter">definition</replaceable>' | AS '<replaceable class="parameter">definition</replaceable>'
| AS '<replaceable class="parameter">obj_file</replaceable>', '<replaceable class="parameter">link_symbol</replaceable>' | AS '<replaceable class="parameter">obj_file</replaceable>', '<replaceable class="parameter">link_symbol</replaceable>'
} ... } ...
...@@ -324,13 +324,15 @@ CREATE [ OR REPLACE ] FUNCTION ...@@ -324,13 +324,15 @@ CREATE [ OR REPLACE ] FUNCTION
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><replaceable>parameter</replaceable></term> <term><replaceable>configuration_parameter</replaceable></term>
<term><replaceable>value</replaceable></term> <term><replaceable>value</replaceable></term>
<listitem> <listitem>
<para> <para>
The <literal>SET</> clause causes the specified configuration The <literal>SET</> clause causes the specified configuration
parameter to be set to the specified value when the function is parameter to be set to the specified value when the function is
entered, and then restored to its prior value when the function exits. entered, and then restored to its prior value when the function exits.
<literal>SET FROM CURRENT</> saves the session's current value of
the parameter as the value to be applied when the function is entered.
</para> </para>
<para> <para>
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.197 2007/08/01 22:45:08 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.198 2007/09/03 18:46:29 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -886,7 +886,7 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt) ...@@ -886,7 +886,7 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt)
char repl_null[Natts_pg_database]; char repl_null[Natts_pg_database];
char repl_repl[Natts_pg_database]; char repl_repl[Natts_pg_database];
valuestr = flatten_set_variable_args(stmt->variable, stmt->value); valuestr = ExtractSetVariableArgs(stmt->setstmt);
/* /*
* Get the old tuple. We don't need a lock on the database per se, * Get the old tuple. We don't need a lock on the database per se,
...@@ -910,12 +910,12 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt) ...@@ -910,12 +910,12 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt)
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE, aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE,
stmt->dbname); stmt->dbname);
MemSet(repl_repl, ' ', sizeof(repl_repl)); memset(repl_repl, ' ', sizeof(repl_repl));
repl_repl[Anum_pg_database_datconfig - 1] = 'r'; repl_repl[Anum_pg_database_datconfig - 1] = 'r';
if (strcmp(stmt->variable, "all") == 0 && valuestr == NULL) if (stmt->setstmt->kind == VAR_RESET_ALL)
{ {
/* RESET ALL */ /* RESET ALL, so just set datconfig to null */
repl_null[Anum_pg_database_datconfig - 1] = 'n'; repl_null[Anum_pg_database_datconfig - 1] = 'n';
repl_val[Anum_pg_database_datconfig - 1] = (Datum) 0; repl_val[Anum_pg_database_datconfig - 1] = (Datum) 0;
} }
...@@ -927,15 +927,16 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt) ...@@ -927,15 +927,16 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt)
repl_null[Anum_pg_database_datconfig - 1] = ' '; repl_null[Anum_pg_database_datconfig - 1] = ' ';
/* Extract old value of datconfig */
datum = heap_getattr(tuple, Anum_pg_database_datconfig, datum = heap_getattr(tuple, Anum_pg_database_datconfig,
RelationGetDescr(rel), &isnull); RelationGetDescr(rel), &isnull);
a = isnull ? NULL : DatumGetArrayTypeP(datum); a = isnull ? NULL : DatumGetArrayTypeP(datum);
/* Update (valuestr is NULL in RESET cases) */
if (valuestr) if (valuestr)
a = GUCArrayAdd(a, stmt->variable, valuestr); a = GUCArrayAdd(a, stmt->setstmt->name, valuestr);
else else
a = GUCArrayDelete(a, stmt->variable); a = GUCArrayDelete(a, stmt->setstmt->name);
if (a) if (a)
repl_val[Anum_pg_database_datconfig - 1] = PointerGetDatum(a); repl_val[Anum_pg_database_datconfig - 1] = PointerGetDatum(a);
...@@ -943,7 +944,8 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt) ...@@ -943,7 +944,8 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt)
repl_null[Anum_pg_database_datconfig - 1] = 'n'; repl_null[Anum_pg_database_datconfig - 1] = 'n';
} }
newtuple = heap_modifytuple(tuple, RelationGetDescr(rel), repl_val, repl_null, repl_repl); newtuple = heap_modifytuple(tuple, RelationGetDescr(rel),
repl_val, repl_null, repl_repl);
simple_heap_update(rel, &tuple->t_self, newtuple); simple_heap_update(rel, &tuple->t_self, newtuple);
/* Update indexes */ /* Update indexes */
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.84 2007/09/03 00:39:15 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.85 2007/09/03 18:46:29 tgl Exp $
* *
* DESCRIPTION * DESCRIPTION
* These routines take the parse tree and pick out the * These routines take the parse tree and pick out the
...@@ -354,7 +354,7 @@ interpret_func_volatility(DefElem *defel) ...@@ -354,7 +354,7 @@ interpret_func_volatility(DefElem *defel)
} }
/* /*
* Update a proconfig value according to a list of SET and RESET items. * Update a proconfig value according to a list of VariableSetStmt items.
* *
* The input and result may be NULL to signify a null entry. * The input and result may be NULL to signify a null entry.
*/ */
...@@ -365,33 +365,20 @@ update_proconfig_value(ArrayType *a, List *set_items) ...@@ -365,33 +365,20 @@ update_proconfig_value(ArrayType *a, List *set_items)
foreach(l, set_items) foreach(l, set_items)
{ {
Node *sitem = (Node *) lfirst(l); VariableSetStmt *sstmt = (VariableSetStmt *) lfirst(l);
if (IsA(sitem, VariableSetStmt)) Assert(IsA(sstmt, VariableSetStmt));
if (sstmt->kind == VAR_RESET_ALL)
a = NULL;
else
{ {
VariableSetStmt *sstmt = (VariableSetStmt *) sitem; char *valuestr = ExtractSetVariableArgs(sstmt);
if (sstmt->args)
{
char *valuestr;
valuestr = flatten_set_variable_args(sstmt->name, sstmt->args); if (valuestr)
a = GUCArrayAdd(a, sstmt->name, valuestr); a = GUCArrayAdd(a, sstmt->name, valuestr);
} else /* RESET */
else /* SET TO DEFAULT */
a = GUCArrayDelete(a, sstmt->name); a = GUCArrayDelete(a, sstmt->name);
} }
else if (IsA(sitem, VariableResetStmt))
{
VariableResetStmt *rstmt = (VariableResetStmt *) sitem;
if (strcmp(rstmt->name, "all") == 0)
a = NULL; /* RESET ALL */
else
a = GUCArrayDelete(a, rstmt->name);
}
else
elog(ERROR, "unexpected node type: %d", nodeTag(sitem));
} }
return a; return a;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/backend/commands/user.c,v 1.176 2007/02/01 19:10:26 momjian Exp $ * $PostgreSQL: pgsql/src/backend/commands/user.c,v 1.177 2007/09/03 18:46:30 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -721,9 +721,8 @@ AlterRoleSet(AlterRoleSetStmt *stmt) ...@@ -721,9 +721,8 @@ AlterRoleSet(AlterRoleSetStmt *stmt)
Datum repl_val[Natts_pg_authid]; Datum repl_val[Natts_pg_authid];
char repl_null[Natts_pg_authid]; char repl_null[Natts_pg_authid];
char repl_repl[Natts_pg_authid]; char repl_repl[Natts_pg_authid];
int i;
valuestr = flatten_set_variable_args(stmt->variable, stmt->value); valuestr = ExtractSetVariableArgs(stmt->setstmt);
rel = heap_open(AuthIdRelationId, RowExclusiveLock); rel = heap_open(AuthIdRelationId, RowExclusiveLock);
oldtuple = SearchSysCache(AUTHNAME, oldtuple = SearchSysCache(AUTHNAME,
...@@ -754,14 +753,14 @@ AlterRoleSet(AlterRoleSetStmt *stmt) ...@@ -754,14 +753,14 @@ AlterRoleSet(AlterRoleSetStmt *stmt)
errmsg("permission denied"))); errmsg("permission denied")));
} }
for (i = 0; i < Natts_pg_authid; i++) memset(repl_repl, ' ', sizeof(repl_repl));
repl_repl[i] = ' ';
repl_repl[Anum_pg_authid_rolconfig - 1] = 'r'; repl_repl[Anum_pg_authid_rolconfig - 1] = 'r';
if (strcmp(stmt->variable, "all") == 0 && valuestr == NULL)
if (stmt->setstmt->kind == VAR_RESET_ALL)
{ {
/* RESET ALL */ /* RESET ALL, so just set rolconfig to null */
repl_null[Anum_pg_authid_rolconfig - 1] = 'n'; repl_null[Anum_pg_authid_rolconfig - 1] = 'n';
repl_val[Anum_pg_authid_rolconfig - 1] = (Datum) 0;
} }
else else
{ {
...@@ -771,15 +770,16 @@ AlterRoleSet(AlterRoleSetStmt *stmt) ...@@ -771,15 +770,16 @@ AlterRoleSet(AlterRoleSetStmt *stmt)
repl_null[Anum_pg_authid_rolconfig - 1] = ' '; repl_null[Anum_pg_authid_rolconfig - 1] = ' ';
/* Extract old value of rolconfig */
datum = SysCacheGetAttr(AUTHNAME, oldtuple, datum = SysCacheGetAttr(AUTHNAME, oldtuple,
Anum_pg_authid_rolconfig, &isnull); Anum_pg_authid_rolconfig, &isnull);
array = isnull ? NULL : DatumGetArrayTypeP(datum); array = isnull ? NULL : DatumGetArrayTypeP(datum);
/* Update (valuestr is NULL in RESET cases) */
if (valuestr) if (valuestr)
array = GUCArrayAdd(array, stmt->variable, valuestr); array = GUCArrayAdd(array, stmt->setstmt->name, valuestr);
else else
array = GUCArrayDelete(array, stmt->variable); array = GUCArrayDelete(array, stmt->setstmt->name);
if (array) if (array)
repl_val[Anum_pg_authid_rolconfig - 1] = PointerGetDatum(array); repl_val[Anum_pg_authid_rolconfig - 1] = PointerGetDatum(array);
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.381 2007/08/31 01:44:05 tgl Exp $ * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.382 2007/09/03 18:46:30 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -2525,8 +2525,7 @@ _copyAlterDatabaseSetStmt(AlterDatabaseSetStmt *from) ...@@ -2525,8 +2525,7 @@ _copyAlterDatabaseSetStmt(AlterDatabaseSetStmt *from)
AlterDatabaseSetStmt *newnode = makeNode(AlterDatabaseSetStmt); AlterDatabaseSetStmt *newnode = makeNode(AlterDatabaseSetStmt);
COPY_STRING_FIELD(dbname); COPY_STRING_FIELD(dbname);
COPY_STRING_FIELD(variable); COPY_NODE_FIELD(setstmt);
COPY_NODE_FIELD(value);
return newnode; return newnode;
} }
...@@ -2597,6 +2596,7 @@ _copyVariableSetStmt(VariableSetStmt *from) ...@@ -2597,6 +2596,7 @@ _copyVariableSetStmt(VariableSetStmt *from)
{ {
VariableSetStmt *newnode = makeNode(VariableSetStmt); VariableSetStmt *newnode = makeNode(VariableSetStmt);
COPY_SCALAR_FIELD(kind);
COPY_STRING_FIELD(name); COPY_STRING_FIELD(name);
COPY_NODE_FIELD(args); COPY_NODE_FIELD(args);
COPY_SCALAR_FIELD(is_local); COPY_SCALAR_FIELD(is_local);
...@@ -2614,16 +2614,6 @@ _copyVariableShowStmt(VariableShowStmt *from) ...@@ -2614,16 +2614,6 @@ _copyVariableShowStmt(VariableShowStmt *from)
return newnode; return newnode;
} }
static VariableResetStmt *
_copyVariableResetStmt(VariableResetStmt *from)
{
VariableResetStmt *newnode = makeNode(VariableResetStmt);
COPY_STRING_FIELD(name);
return newnode;
}
static DiscardStmt * static DiscardStmt *
_copyDiscardStmt(DiscardStmt *from) _copyDiscardStmt(DiscardStmt *from)
{ {
...@@ -2746,8 +2736,7 @@ _copyAlterRoleSetStmt(AlterRoleSetStmt *from) ...@@ -2746,8 +2736,7 @@ _copyAlterRoleSetStmt(AlterRoleSetStmt *from)
AlterRoleSetStmt *newnode = makeNode(AlterRoleSetStmt); AlterRoleSetStmt *newnode = makeNode(AlterRoleSetStmt);
COPY_STRING_FIELD(role); COPY_STRING_FIELD(role);
COPY_STRING_FIELD(variable); COPY_NODE_FIELD(setstmt);
COPY_NODE_FIELD(value);
return newnode; return newnode;
} }
...@@ -3428,9 +3417,6 @@ copyObject(void *from) ...@@ -3428,9 +3417,6 @@ copyObject(void *from)
case T_VariableShowStmt: case T_VariableShowStmt:
retval = _copyVariableShowStmt(from); retval = _copyVariableShowStmt(from);
break; break;
case T_VariableResetStmt:
retval = _copyVariableResetStmt(from);
break;
case T_DiscardStmt: case T_DiscardStmt:
retval = _copyDiscardStmt(from); retval = _copyDiscardStmt(from);
break; break;
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.312 2007/08/31 01:44:05 tgl Exp $ * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.313 2007/09/03 18:46:30 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1325,8 +1325,7 @@ static bool ...@@ -1325,8 +1325,7 @@ static bool
_equalAlterDatabaseSetStmt(AlterDatabaseSetStmt *a, AlterDatabaseSetStmt *b) _equalAlterDatabaseSetStmt(AlterDatabaseSetStmt *a, AlterDatabaseSetStmt *b)
{ {
COMPARE_STRING_FIELD(dbname); COMPARE_STRING_FIELD(dbname);
COMPARE_STRING_FIELD(variable); COMPARE_NODE_FIELD(setstmt);
COMPARE_NODE_FIELD(value);
return true; return true;
} }
...@@ -1385,6 +1384,7 @@ _equalAlterSeqStmt(AlterSeqStmt *a, AlterSeqStmt *b) ...@@ -1385,6 +1384,7 @@ _equalAlterSeqStmt(AlterSeqStmt *a, AlterSeqStmt *b)
static bool static bool
_equalVariableSetStmt(VariableSetStmt *a, VariableSetStmt *b) _equalVariableSetStmt(VariableSetStmt *a, VariableSetStmt *b)
{ {
COMPARE_SCALAR_FIELD(kind);
COMPARE_STRING_FIELD(name); COMPARE_STRING_FIELD(name);
COMPARE_NODE_FIELD(args); COMPARE_NODE_FIELD(args);
COMPARE_SCALAR_FIELD(is_local); COMPARE_SCALAR_FIELD(is_local);
...@@ -1400,14 +1400,6 @@ _equalVariableShowStmt(VariableShowStmt *a, VariableShowStmt *b) ...@@ -1400,14 +1400,6 @@ _equalVariableShowStmt(VariableShowStmt *a, VariableShowStmt *b)
return true; return true;
} }
static bool
_equalVariableResetStmt(VariableResetStmt *a, VariableResetStmt *b)
{
COMPARE_STRING_FIELD(name);
return true;
}
static bool static bool
_equalDiscardStmt(DiscardStmt *a, DiscardStmt *b) _equalDiscardStmt(DiscardStmt *a, DiscardStmt *b)
{ {
...@@ -1511,8 +1503,7 @@ static bool ...@@ -1511,8 +1503,7 @@ static bool
_equalAlterRoleSetStmt(AlterRoleSetStmt *a, AlterRoleSetStmt *b) _equalAlterRoleSetStmt(AlterRoleSetStmt *a, AlterRoleSetStmt *b)
{ {
COMPARE_STRING_FIELD(role); COMPARE_STRING_FIELD(role);
COMPARE_STRING_FIELD(variable); COMPARE_NODE_FIELD(setstmt);
COMPARE_NODE_FIELD(value);
return true; return true;
} }
...@@ -2356,9 +2347,6 @@ equal(void *a, void *b) ...@@ -2356,9 +2347,6 @@ equal(void *a, void *b)
case T_VariableShowStmt: case T_VariableShowStmt:
retval = _equalVariableShowStmt(a, b); retval = _equalVariableShowStmt(a, b);
break; break;
case T_VariableResetStmt:
retval = _equalVariableResetStmt(a, b);
break;
case T_DiscardStmt: case T_DiscardStmt:
retval = _equalDiscardStmt(a, b); retval = _equalDiscardStmt(a, b);
break; break;
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.601 2007/09/03 00:39:16 tgl Exp $ * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.602 2007/09/03 18:46:30 tgl Exp $
* *
* HISTORY * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -292,7 +292,7 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args) ...@@ -292,7 +292,7 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
%type <istmt> insert_rest %type <istmt> insert_rest
%type <vsetstmt> set_rest %type <vsetstmt> set_rest SetResetClause
%type <node> TableElement ConstraintElem TableFuncElement %type <node> TableElement ConstraintElem TableFuncElement
%type <node> columnDef %type <node> columnDef
...@@ -330,7 +330,7 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args) ...@@ -330,7 +330,7 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
%type <ival> Iconst SignedIconst %type <ival> Iconst SignedIconst
%type <str> Sconst comment_text %type <str> Sconst comment_text
%type <str> RoleId opt_granted_by opt_boolean ColId_or_Sconst %type <str> RoleId opt_granted_by opt_boolean ColId_or_Sconst
%type <list> var_list var_list_or_default %type <list> var_list
%type <str> ColId ColLabel var_name type_function_name param_name %type <str> ColId ColLabel var_name type_function_name param_name
%type <node> var_value zone_value %type <node> var_value zone_value
...@@ -796,20 +796,11 @@ AlterRoleStmt: ...@@ -796,20 +796,11 @@ AlterRoleStmt:
; ;
AlterRoleSetStmt: AlterRoleSetStmt:
ALTER ROLE RoleId SET set_rest ALTER ROLE RoleId SetResetClause
{ {
AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt); AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
n->role = $3; n->role = $3;
n->variable = $5->name; n->setstmt = $4;
n->value = $5->args;
$$ = (Node *)n;
}
| ALTER ROLE RoleId VariableResetStmt
{
AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
n->role = $3;
n->variable = ((VariableResetStmt *)$4)->name;
n->value = NIL;
$$ = (Node *)n; $$ = (Node *)n;
} }
; ;
...@@ -834,20 +825,11 @@ AlterUserStmt: ...@@ -834,20 +825,11 @@ AlterUserStmt:
AlterUserSetStmt: AlterUserSetStmt:
ALTER USER RoleId SET set_rest ALTER USER RoleId SetResetClause
{ {
AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt); AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
n->role = $3; n->role = $3;
n->variable = $5->name; n->setstmt = $4;
n->value = $5->args;
$$ = (Node *)n;
}
| ALTER USER RoleId VariableResetStmt
{
AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
n->role = $3;
n->variable = ((VariableResetStmt *)$4)->name;
n->value = NIL;
$$ = (Node *)n; $$ = (Node *)n;
} }
; ;
...@@ -1056,31 +1038,60 @@ VariableSetStmt: ...@@ -1056,31 +1038,60 @@ VariableSetStmt:
} }
; ;
set_rest: var_name TO var_list_or_default set_rest: /* Generic SET syntaxes: */
var_name TO var_list
{ {
VariableSetStmt *n = makeNode(VariableSetStmt); VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_SET_VALUE;
n->name = $1; n->name = $1;
n->args = $3; n->args = $3;
$$ = n; $$ = n;
} }
| var_name '=' var_list_or_default | var_name '=' var_list
{ {
VariableSetStmt *n = makeNode(VariableSetStmt); VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_SET_VALUE;
n->name = $1; n->name = $1;
n->args = $3; n->args = $3;
$$ = n; $$ = n;
} }
| var_name TO DEFAULT
{
VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_SET_DEFAULT;
n->name = $1;
$$ = n;
}
| var_name '=' DEFAULT
{
VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_SET_DEFAULT;
n->name = $1;
$$ = n;
}
| var_name FROM CURRENT_P
{
VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_SET_CURRENT;
n->name = $1;
$$ = n;
}
/* Special syntaxes mandated by SQL standard: */
| TIME ZONE zone_value | TIME ZONE zone_value
{ {
VariableSetStmt *n = makeNode(VariableSetStmt); VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_SET_VALUE;
n->name = "timezone"; n->name = "timezone";
if ($3 != NULL) if ($3 != NULL)
n->args = list_make1($3); n->args = list_make1($3);
else
n->kind = VAR_SET_DEFAULT;
$$ = n; $$ = n;
} }
| TRANSACTION transaction_mode_list | TRANSACTION transaction_mode_list
{ {
VariableSetStmt *n = makeNode(VariableSetStmt); VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_SET_MULTI;
n->name = "TRANSACTION"; n->name = "TRANSACTION";
n->args = $2; n->args = $2;
$$ = n; $$ = n;
...@@ -1088,6 +1099,7 @@ set_rest: var_name TO var_list_or_default ...@@ -1088,6 +1099,7 @@ set_rest: var_name TO var_list_or_default
| SESSION CHARACTERISTICS AS TRANSACTION transaction_mode_list | SESSION CHARACTERISTICS AS TRANSACTION transaction_mode_list
{ {
VariableSetStmt *n = makeNode(VariableSetStmt); VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_SET_MULTI;
n->name = "SESSION CHARACTERISTICS"; n->name = "SESSION CHARACTERISTICS";
n->args = $5; n->args = $5;
$$ = n; $$ = n;
...@@ -1095,14 +1107,18 @@ set_rest: var_name TO var_list_or_default ...@@ -1095,14 +1107,18 @@ set_rest: var_name TO var_list_or_default
| NAMES opt_encoding | NAMES opt_encoding
{ {
VariableSetStmt *n = makeNode(VariableSetStmt); VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_SET_VALUE;
n->name = "client_encoding"; n->name = "client_encoding";
if ($2 != NULL) if ($2 != NULL)
n->args = list_make1(makeStringConst($2, NULL)); n->args = list_make1(makeStringConst($2, NULL));
else
n->kind = VAR_SET_DEFAULT;
$$ = n; $$ = n;
} }
| ROLE ColId_or_Sconst | ROLE ColId_or_Sconst
{ {
VariableSetStmt *n = makeNode(VariableSetStmt); VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_SET_VALUE;
n->name = "role"; n->name = "role";
n->args = list_make1(makeStringConst($2, NULL)); n->args = list_make1(makeStringConst($2, NULL));
$$ = n; $$ = n;
...@@ -1110,6 +1126,7 @@ set_rest: var_name TO var_list_or_default ...@@ -1110,6 +1126,7 @@ set_rest: var_name TO var_list_or_default
| SESSION AUTHORIZATION ColId_or_Sconst | SESSION AUTHORIZATION ColId_or_Sconst
{ {
VariableSetStmt *n = makeNode(VariableSetStmt); VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_SET_VALUE;
n->name = "session_authorization"; n->name = "session_authorization";
n->args = list_make1(makeStringConst($3, NULL)); n->args = list_make1(makeStringConst($3, NULL));
$$ = n; $$ = n;
...@@ -1117,37 +1134,28 @@ set_rest: var_name TO var_list_or_default ...@@ -1117,37 +1134,28 @@ set_rest: var_name TO var_list_or_default
| SESSION AUTHORIZATION DEFAULT | SESSION AUTHORIZATION DEFAULT
{ {
VariableSetStmt *n = makeNode(VariableSetStmt); VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_SET_DEFAULT;
n->name = "session_authorization"; n->name = "session_authorization";
n->args = NIL;
$$ = n; $$ = n;
} }
| XML_P OPTION document_or_content | XML_P OPTION document_or_content
{ {
VariableSetStmt *n = makeNode(VariableSetStmt); VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_SET_VALUE;
n->name = "xmloption"; n->name = "xmloption";
n->args = list_make1(makeStringConst($3 == XMLOPTION_DOCUMENT ? "DOCUMENT" : "CONTENT", NULL)); n->args = list_make1(makeStringConst($3 == XMLOPTION_DOCUMENT ? "DOCUMENT" : "CONTENT", NULL));
$$ = n; $$ = n;
} }
; ;
var_name: var_name: ColId { $$ = $1; }
ColId { $$ = $1; }
| var_name '.' ColId | var_name '.' ColId
{ {
int qLen = strlen($1); $$ = palloc(strlen($1) + strlen($3) + 2);
char* qualName = palloc(qLen + strlen($3) + 2); sprintf($$, "%s.%s", $1, $3);
strcpy(qualName, $1);
qualName[qLen] = '.';
strcpy(qualName + qLen + 1, $3);
$$ = qualName;
} }
; ;
var_list_or_default:
var_list { $$ = $1; }
| DEFAULT { $$ = NIL; }
;
var_list: var_value { $$ = list_make1($1); } var_list: var_value { $$ = list_make1($1); }
| var_list ',' var_value { $$ = lappend($1, $3); } | var_list ',' var_value { $$ = lappend($1, $3); }
; ;
...@@ -1231,68 +1239,78 @@ ColId_or_Sconst: ...@@ -1231,68 +1239,78 @@ ColId_or_Sconst:
| SCONST { $$ = $1; } | SCONST { $$ = $1; }
; ;
VariableResetStmt:
VariableShowStmt: RESET var_name
SHOW var_name
{ {
VariableShowStmt *n = makeNode(VariableShowStmt); VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_RESET;
n->name = $2; n->name = $2;
$$ = (Node *) n; $$ = (Node *) n;
} }
| SHOW TIME ZONE | RESET TIME ZONE
{ {
VariableShowStmt *n = makeNode(VariableShowStmt); VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_RESET;
n->name = "timezone"; n->name = "timezone";
$$ = (Node *) n; $$ = (Node *) n;
} }
| SHOW TRANSACTION ISOLATION LEVEL | RESET TRANSACTION ISOLATION LEVEL
{ {
VariableShowStmt *n = makeNode(VariableShowStmt); VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_RESET;
n->name = "transaction_isolation"; n->name = "transaction_isolation";
$$ = (Node *) n; $$ = (Node *) n;
} }
| SHOW SESSION AUTHORIZATION | RESET SESSION AUTHORIZATION
{ {
VariableShowStmt *n = makeNode(VariableShowStmt); VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_RESET;
n->name = "session_authorization"; n->name = "session_authorization";
$$ = (Node *) n; $$ = (Node *) n;
} }
| SHOW ALL | RESET ALL
{ {
VariableShowStmt *n = makeNode(VariableShowStmt); VariableSetStmt *n = makeNode(VariableSetStmt);
n->name = "all"; n->kind = VAR_RESET_ALL;
$$ = (Node *) n; $$ = (Node *) n;
} }
; ;
VariableResetStmt: /* SetResetClause allows SET or RESET without LOCAL */
RESET var_name SetResetClause:
SET set_rest { $$ = $2; }
| VariableResetStmt { $$ = (VariableSetStmt *) $1; }
;
VariableShowStmt:
SHOW var_name
{ {
VariableResetStmt *n = makeNode(VariableResetStmt); VariableShowStmt *n = makeNode(VariableShowStmt);
n->name = $2; n->name = $2;
$$ = (Node *) n; $$ = (Node *) n;
} }
| RESET TIME ZONE | SHOW TIME ZONE
{ {
VariableResetStmt *n = makeNode(VariableResetStmt); VariableShowStmt *n = makeNode(VariableShowStmt);
n->name = "timezone"; n->name = "timezone";
$$ = (Node *) n; $$ = (Node *) n;
} }
| RESET TRANSACTION ISOLATION LEVEL | SHOW TRANSACTION ISOLATION LEVEL
{ {
VariableResetStmt *n = makeNode(VariableResetStmt); VariableShowStmt *n = makeNode(VariableShowStmt);
n->name = "transaction_isolation"; n->name = "transaction_isolation";
$$ = (Node *) n; $$ = (Node *) n;
} }
| RESET SESSION AUTHORIZATION | SHOW SESSION AUTHORIZATION
{ {
VariableResetStmt *n = makeNode(VariableResetStmt); VariableShowStmt *n = makeNode(VariableShowStmt);
n->name = "session_authorization"; n->name = "session_authorization";
$$ = (Node *) n; $$ = (Node *) n;
} }
| RESET ALL | SHOW ALL
{ {
VariableResetStmt *n = makeNode(VariableResetStmt); VariableShowStmt *n = makeNode(VariableShowStmt);
n->name = "all"; n->name = "all";
$$ = (Node *) n; $$ = (Node *) n;
} }
...@@ -4270,15 +4288,10 @@ common_func_opt_item: ...@@ -4270,15 +4288,10 @@ common_func_opt_item:
{ {
$$ = makeDefElem("rows", (Node *)$2); $$ = makeDefElem("rows", (Node *)$2);
} }
| SET set_rest | SetResetClause
{
/* we abuse the normal content of a DefElem here */
$$ = makeDefElem("set", (Node *)$2);
}
| VariableResetStmt
{ {
/* we abuse the normal content of a DefElem here */ /* we abuse the normal content of a DefElem here */
$$ = makeDefElem("set", $1); $$ = makeDefElem("set", (Node *)$1);
} }
; ;
...@@ -5391,20 +5404,11 @@ AlterDatabaseStmt: ...@@ -5391,20 +5404,11 @@ AlterDatabaseStmt:
; ;
AlterDatabaseSetStmt: AlterDatabaseSetStmt:
ALTER DATABASE database_name SET set_rest ALTER DATABASE database_name SetResetClause
{
AlterDatabaseSetStmt *n = makeNode(AlterDatabaseSetStmt);
n->dbname = $3;
n->variable = $5->name;
n->value = $5->args;
$$ = (Node *)n;
}
| ALTER DATABASE database_name VariableResetStmt
{ {
AlterDatabaseSetStmt *n = makeNode(AlterDatabaseSetStmt); AlterDatabaseSetStmt *n = makeNode(AlterDatabaseSetStmt);
n->dbname = $3; n->dbname = $3;
n->variable = ((VariableResetStmt *)$4)->name; n->setstmt = $4;
n->value = NIL;
$$ = (Node *)n; $$ = (Node *)n;
} }
; ;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/tcop/pquery.c,v 1.116 2007/04/27 22:05:49 tgl Exp $ * $PostgreSQL: pgsql/src/backend/tcop/pquery.c,v 1.117 2007/09/03 18:46:30 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1159,7 +1159,6 @@ PortalRunUtility(Portal portal, Node *utilityStmt, bool isTopLevel, ...@@ -1159,7 +1159,6 @@ PortalRunUtility(Portal portal, Node *utilityStmt, bool isTopLevel,
IsA(utilityStmt, LockStmt) || IsA(utilityStmt, LockStmt) ||
IsA(utilityStmt, VariableSetStmt) || IsA(utilityStmt, VariableSetStmt) ||
IsA(utilityStmt, VariableShowStmt) || IsA(utilityStmt, VariableShowStmt) ||
IsA(utilityStmt, VariableResetStmt) ||
IsA(utilityStmt, ConstraintsSetStmt) || IsA(utilityStmt, ConstraintsSetStmt) ||
/* efficiency hacks from here down */ /* efficiency hacks from here down */
IsA(utilityStmt, FetchStmt) || IsA(utilityStmt, FetchStmt) ||
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.285 2007/08/21 01:11:17 tgl Exp $ * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.286 2007/09/03 18:46:30 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1041,48 +1041,7 @@ ProcessUtility(Node *parsetree, ...@@ -1041,48 +1041,7 @@ ProcessUtility(Node *parsetree,
break; break;
case T_VariableSetStmt: case T_VariableSetStmt:
{ ExecSetVariableStmt((VariableSetStmt *) parsetree);
VariableSetStmt *n = (VariableSetStmt *) parsetree;
/*
* Special cases for special SQL syntax that effectively sets
* more than one variable per statement.
*/
if (strcmp(n->name, "TRANSACTION") == 0)
{
ListCell *head;
foreach(head, n->args)
{
DefElem *item = (DefElem *) lfirst(head);
if (strcmp(item->defname, "transaction_isolation") == 0)
SetPGVariable("transaction_isolation",
list_make1(item->arg), n->is_local);
else if (strcmp(item->defname, "transaction_read_only") == 0)
SetPGVariable("transaction_read_only",
list_make1(item->arg), n->is_local);
}
}
else if (strcmp(n->name, "SESSION CHARACTERISTICS") == 0)
{
ListCell *head;
foreach(head, n->args)
{
DefElem *item = (DefElem *) lfirst(head);
if (strcmp(item->defname, "transaction_isolation") == 0)
SetPGVariable("default_transaction_isolation",
list_make1(item->arg), n->is_local);
else if (strcmp(item->defname, "transaction_read_only") == 0)
SetPGVariable("default_transaction_read_only",
list_make1(item->arg), n->is_local);
}
}
else
SetPGVariable(n->name, n->args, n->is_local);
}
break; break;
case T_VariableShowStmt: case T_VariableShowStmt:
...@@ -1093,14 +1052,6 @@ ProcessUtility(Node *parsetree, ...@@ -1093,14 +1052,6 @@ ProcessUtility(Node *parsetree,
} }
break; break;
case T_VariableResetStmt:
{
VariableResetStmt *n = (VariableResetStmt *) parsetree;
ResetPGVariable(n->name, isTopLevel);
}
break;
case T_DiscardStmt: case T_DiscardStmt:
DiscardCommand((DiscardStmt *) parsetree, isTopLevel); DiscardCommand((DiscardStmt *) parsetree, isTopLevel);
break; break;
...@@ -1924,19 +1875,30 @@ CreateCommandTag(Node *parsetree) ...@@ -1924,19 +1875,30 @@ CreateCommandTag(Node *parsetree)
break; break;
case T_VariableSetStmt: case T_VariableSetStmt:
tag = "SET"; switch (((VariableSetStmt *) parsetree)->kind)
{
case VAR_SET_VALUE:
case VAR_SET_CURRENT:
case VAR_SET_DEFAULT:
case VAR_SET_MULTI:
tag = "SET";
break;
case VAR_RESET:
case VAR_RESET_ALL:
tag = "RESET";
break;
default:
tag = "???";
}
break; break;
case T_VariableShowStmt: case T_VariableShowStmt:
tag = "SHOW"; tag = "SHOW";
break; break;
case T_VariableResetStmt:
tag = "RESET";
break;
case T_DiscardStmt: case T_DiscardStmt:
switch (((DiscardStmt *) parsetree)->target) { switch (((DiscardStmt *) parsetree)->target)
{
case DISCARD_ALL: case DISCARD_ALL:
tag = "DISCARD ALL"; tag = "DISCARD ALL";
break; break;
...@@ -2402,10 +2364,6 @@ GetCommandLogLevel(Node *parsetree) ...@@ -2402,10 +2364,6 @@ GetCommandLogLevel(Node *parsetree)
lev = LOGSTMT_ALL; lev = LOGSTMT_ALL;
break; break;
case T_VariableResetStmt:
lev = LOGSTMT_ALL;
break;
case T_CreateTrigStmt: case T_CreateTrigStmt:
lev = LOGSTMT_DDL; lev = LOGSTMT_DDL;
break; break;
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>. * Written by Peter Eisentraut <peter_e@gmx.net>.
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.415 2007/09/03 00:39:19 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.416 2007/09/03 18:46:30 tgl Exp $
* *
*-------------------------------------------------------------------- *--------------------------------------------------------------------
*/ */
...@@ -4870,10 +4870,10 @@ IsSuperuserConfigOption(const char *name) ...@@ -4870,10 +4870,10 @@ IsSuperuserConfigOption(const char *name)
* We need to be told the name of the variable the args are for, because * We need to be told the name of the variable the args are for, because
* the flattening rules vary (ugh). * the flattening rules vary (ugh).
* *
* The result is NULL if input is NIL (ie, SET ... TO DEFAULT), otherwise * The result is NULL if args is NIL (ie, SET ... TO DEFAULT), otherwise
* a palloc'd string. * a palloc'd string.
*/ */
char * static char *
flatten_set_variable_args(const char *name, List *args) flatten_set_variable_args(const char *name, List *args)
{ {
struct config_generic *record; struct config_generic *record;
...@@ -4881,10 +4881,7 @@ flatten_set_variable_args(const char *name, List *args) ...@@ -4881,10 +4881,7 @@ flatten_set_variable_args(const char *name, List *args)
StringInfoData buf; StringInfoData buf;
ListCell *l; ListCell *l;
/* /* Fast path if just DEFAULT */
* Fast path if just DEFAULT. We do not check the variable name in this
* case --- necessary for RESET ALL to work correctly.
*/
if (args == NIL) if (args == NIL)
return NULL; return NULL;
...@@ -4979,6 +4976,108 @@ flatten_set_variable_args(const char *name, List *args) ...@@ -4979,6 +4976,108 @@ flatten_set_variable_args(const char *name, List *args)
* SET command * SET command
*/ */
void void
ExecSetVariableStmt(VariableSetStmt *stmt)
{
switch (stmt->kind)
{
case VAR_SET_VALUE:
case VAR_SET_CURRENT:
set_config_option(stmt->name,
ExtractSetVariableArgs(stmt),
(superuser() ? PGC_SUSET : PGC_USERSET),
PGC_S_SESSION,
stmt->is_local,
true);
break;
case VAR_SET_MULTI:
/*
* Special case for special SQL syntax that effectively sets
* more than one variable per statement.
*/
if (strcmp(stmt->name, "TRANSACTION") == 0)
{
ListCell *head;
foreach(head, stmt->args)
{
DefElem *item = (DefElem *) lfirst(head);
if (strcmp(item->defname, "transaction_isolation") == 0)
SetPGVariable("transaction_isolation",
list_make1(item->arg), stmt->is_local);
else if (strcmp(item->defname, "transaction_read_only") == 0)
SetPGVariable("transaction_read_only",
list_make1(item->arg), stmt->is_local);
else
elog(ERROR, "unexpected SET TRANSACTION element: %s",
item->defname);
}
}
else if (strcmp(stmt->name, "SESSION CHARACTERISTICS") == 0)
{
ListCell *head;
foreach(head, stmt->args)
{
DefElem *item = (DefElem *) lfirst(head);
if (strcmp(item->defname, "transaction_isolation") == 0)
SetPGVariable("default_transaction_isolation",
list_make1(item->arg), stmt->is_local);
else if (strcmp(item->defname, "transaction_read_only") == 0)
SetPGVariable("default_transaction_read_only",
list_make1(item->arg), stmt->is_local);
else
elog(ERROR, "unexpected SET SESSION element: %s",
item->defname);
}
}
else
elog(ERROR, "unexpected SET MULTI element: %s",
stmt->name);
break;
case VAR_SET_DEFAULT:
case VAR_RESET:
set_config_option(stmt->name,
NULL,
(superuser() ? PGC_SUSET : PGC_USERSET),
PGC_S_SESSION,
stmt->is_local,
true);
break;
case VAR_RESET_ALL:
ResetAllOptions();
break;
}
}
/*
* Get the value to assign for a VariableSetStmt, or NULL if it's RESET.
* The result is palloc'd.
*
* This is exported for use by actions such as ALTER ROLE SET.
*/
char *
ExtractSetVariableArgs(VariableSetStmt *stmt)
{
switch (stmt->kind)
{
case VAR_SET_VALUE:
return flatten_set_variable_args(stmt->name, stmt->args);
case VAR_SET_CURRENT:
return GetConfigOptionByName(stmt->name, NULL);
default:
return NULL;
}
}
/*
* SetPGVariable - SET command exported as an easily-C-callable function.
*
* This provides access to SET TO value, as well as SET TO DEFAULT (expressed
* by passing args == NIL), but not SET FROM CURRENT functionality.
*/
void
SetPGVariable(const char *name, List *args, bool is_local) SetPGVariable(const char *name, List *args, bool is_local)
{ {
char *argstring = flatten_set_variable_args(name, args); char *argstring = flatten_set_variable_args(name, args);
...@@ -5045,6 +5144,7 @@ set_config_by_name(PG_FUNCTION_ARGS) ...@@ -5045,6 +5144,7 @@ set_config_by_name(PG_FUNCTION_ARGS)
PG_RETURN_TEXT_P(result_text); PG_RETURN_TEXT_P(result_text);
} }
static void static void
define_custom_variable(struct config_generic * variable) define_custom_variable(struct config_generic * variable)
{ {
...@@ -5283,23 +5383,6 @@ GetPGVariableResultDesc(const char *name) ...@@ -5283,23 +5383,6 @@ GetPGVariableResultDesc(const char *name)
return tupdesc; return tupdesc;
} }
/*
* RESET command
*/
void
ResetPGVariable(const char *name, bool isTopLevel)
{
if (pg_strcasecmp(name, "all") == 0)
ResetAllOptions();
else
set_config_option(name,
NULL,
(superuser() ? PGC_SUSET : PGC_USERSET),
PGC_S_SESSION,
false,
true);
}
/* /*
* SHOW command * SHOW command
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.203 2007/08/21 01:11:27 tgl Exp $ * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.204 2007/09/03 18:46:30 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -275,7 +275,6 @@ typedef enum NodeTag ...@@ -275,7 +275,6 @@ typedef enum NodeTag
T_AlterSeqStmt, T_AlterSeqStmt,
T_VariableSetStmt, T_VariableSetStmt,
T_VariableShowStmt, T_VariableShowStmt,
T_VariableResetStmt,
T_DiscardStmt, T_DiscardStmt,
T_CreateTrigStmt, T_CreateTrigStmt,
T_DropPropertyStmt, T_DropPropertyStmt,
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.352 2007/08/22 05:13:50 tgl Exp $ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.353 2007/09/03 18:46:30 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1050,6 +1050,42 @@ typedef struct CopyStmt ...@@ -1050,6 +1050,42 @@ typedef struct CopyStmt
List *options; /* List of DefElem nodes */ List *options; /* List of DefElem nodes */
} CopyStmt; } CopyStmt;
/* ----------------------
* SET Statement (includes RESET)
*
* "SET var TO DEFAULT" and "RESET var" are semantically equivalent, but we
* preserve the distinction in VariableSetKind for CreateCommandTag().
* ----------------------
*/
typedef enum
{
VAR_SET_VALUE, /* SET var = value */
VAR_SET_DEFAULT, /* SET var TO DEFAULT */
VAR_SET_CURRENT, /* SET var FROM CURRENT */
VAR_SET_MULTI, /* special case for SET TRANSACTION ... */
VAR_RESET, /* RESET var */
VAR_RESET_ALL /* RESET ALL */
} VariableSetKind;
typedef struct VariableSetStmt
{
NodeTag type;
VariableSetKind kind;
char *name; /* variable to be set */
List *args; /* List of A_Const nodes */
bool is_local; /* SET LOCAL? */
} VariableSetStmt;
/* ----------------------
* Show Statement
* ----------------------
*/
typedef struct VariableShowStmt
{
NodeTag type;
char *name;
} VariableShowStmt;
/* ---------------------- /* ----------------------
* Create Table Statement * Create Table Statement
* *
...@@ -1264,8 +1300,7 @@ typedef struct AlterRoleSetStmt ...@@ -1264,8 +1300,7 @@ typedef struct AlterRoleSetStmt
{ {
NodeTag type; NodeTag type;
char *role; /* role name */ char *role; /* role name */
char *variable; /* GUC variable name */ VariableSetStmt *setstmt; /* SET or RESET subcommand */
List *value; /* value for variable, or NIL for Reset */
} AlterRoleSetStmt; } AlterRoleSetStmt;
typedef struct DropRoleStmt typedef struct DropRoleStmt
...@@ -1781,9 +1816,8 @@ typedef struct AlterDatabaseStmt ...@@ -1781,9 +1816,8 @@ typedef struct AlterDatabaseStmt
typedef struct AlterDatabaseSetStmt typedef struct AlterDatabaseSetStmt
{ {
NodeTag type; NodeTag type;
char *dbname; char *dbname; /* database name */
char *variable; VariableSetStmt *setstmt; /* SET or RESET subcommand */
List *value;
} AlterDatabaseSetStmt; } AlterDatabaseSetStmt;
/* ---------------------- /* ----------------------
...@@ -1848,41 +1882,6 @@ typedef struct CheckPointStmt ...@@ -1848,41 +1882,6 @@ typedef struct CheckPointStmt
NodeTag type; NodeTag type;
} CheckPointStmt; } CheckPointStmt;
/* ----------------------
* Set Statement
* ----------------------
*/
typedef struct VariableSetStmt
{
NodeTag type;
char *name;
List *args;
bool is_local; /* SET LOCAL */
} VariableSetStmt;
/* ----------------------
* Show Statement
* ----------------------
*/
typedef struct VariableShowStmt
{
NodeTag type;
char *name;
} VariableShowStmt;
/* ----------------------
* Reset Statement
* ----------------------
*/
typedef struct VariableResetStmt
{
NodeTag type;
char *name;
} VariableResetStmt;
/* ---------------------- /* ----------------------
* Discard Statement * Discard Statement
* ---------------------- * ----------------------
......
...@@ -7,12 +7,13 @@ ...@@ -7,12 +7,13 @@
* Copyright (c) 2000-2007, PostgreSQL Global Development Group * Copyright (c) 2000-2007, PostgreSQL Global Development Group
* Written by Peter Eisentraut <peter_e@gmx.net>. * Written by Peter Eisentraut <peter_e@gmx.net>.
* *
* $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.84 2007/09/03 00:39:25 tgl Exp $ * $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.85 2007/09/03 18:46:30 tgl Exp $
*-------------------------------------------------------------------- *--------------------------------------------------------------------
*/ */
#ifndef GUC_H #ifndef GUC_H
#define GUC_H #define GUC_H
#include "nodes/parsenodes.h"
#include "tcop/dest.h" #include "tcop/dest.h"
#include "utils/array.h" #include "utils/array.h"
...@@ -203,9 +204,9 @@ extern int GetNumConfigOptions(void); ...@@ -203,9 +204,9 @@ extern int GetNumConfigOptions(void);
extern void SetPGVariable(const char *name, List *args, bool is_local); extern void SetPGVariable(const char *name, List *args, bool is_local);
extern void GetPGVariable(const char *name, DestReceiver *dest); extern void GetPGVariable(const char *name, DestReceiver *dest);
extern TupleDesc GetPGVariableResultDesc(const char *name); extern TupleDesc GetPGVariableResultDesc(const char *name);
extern void ResetPGVariable(const char *name, bool isTopLevel);
extern char *flatten_set_variable_args(const char *name, List *args); extern void ExecSetVariableStmt(VariableSetStmt *stmt);
extern char *ExtractSetVariableArgs(VariableSetStmt *stmt);
extern void ProcessGUCArray(ArrayType *array, extern void ProcessGUCArray(ArrayType *array,
GucContext context, GucSource source, bool isLocal); GucContext context, GucSource source, bool isLocal);
......
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