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.
This commit is contained in:
parent
dd4594e332
commit
e7889b83b7
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$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
|
||||
-->
|
||||
|
||||
@ -26,12 +26,14 @@ where <replaceable class="PARAMETER">option</replaceable> can be:
|
||||
|
||||
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> 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>
|
||||
</refsynopsisdiv>
|
||||
|
||||
@ -49,7 +51,24 @@ ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> OWNER TO <repla
|
||||
</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
|
||||
owner or a superuser can rename a database; non-superuser owners must
|
||||
also have the
|
||||
<literal>CREATEDB</literal> privilege. The current database cannot
|
||||
be renamed. (Connect to a different database if you need to do
|
||||
that.)
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The third form changes the owner of the database.
|
||||
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
|
||||
<literal>CREATEDB</literal> privilege.
|
||||
(Note that superusers have all these privileges automatically.)
|
||||
</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.
|
||||
@ -60,23 +79,6 @@ ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> OWNER TO <repla
|
||||
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
|
||||
also have the
|
||||
<literal>CREATEDB</literal> privilege. The current database cannot
|
||||
be renamed. (Connect to a different database if you need to do
|
||||
that.)
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The fifth form changes the owner of the database.
|
||||
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
|
||||
<literal>CREATEDB</literal> privilege.
|
||||
(Note that superusers have all these privileges automatically.)
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
@ -102,28 +104,6 @@ ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> OWNER TO <repla
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><replaceable>parameter</replaceable></term>
|
||||
<term><replaceable>value</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set this database's session default for the specified configuration
|
||||
parameter to the given value. If
|
||||
<replaceable>value</replaceable> is <literal>DEFAULT</literal>
|
||||
or, equivalently, <literal>RESET</literal> is used, the
|
||||
database-specific setting is removed, so the system-wide default
|
||||
setting will be inherited in new sessions. Use <literal>RESET
|
||||
ALL</literal> to clear all database-specific settings.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
See <xref linkend="sql-set" endterm="sql-set-title"> and <xref linkend="runtime-config">
|
||||
for more information about allowed parameter names
|
||||
and values.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><replaceable>newname</replaceable></term>
|
||||
<listitem>
|
||||
@ -141,6 +121,30 @@ ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> OWNER TO <repla
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><replaceable>configuration_parameter</replaceable></term>
|
||||
<term><replaceable>value</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set this database's session default for the specified configuration
|
||||
parameter to the given value. If
|
||||
<replaceable>value</replaceable> is <literal>DEFAULT</literal>
|
||||
or, equivalently, <literal>RESET</literal> is used, the
|
||||
database-specific setting is removed, so the system-wide default
|
||||
setting will be inherited in new sessions. Use <literal>RESET
|
||||
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>
|
||||
See <xref linkend="sql-set" endterm="sql-set-title"> and <xref linkend="runtime-config">
|
||||
for more information about allowed parameter names
|
||||
and values.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
@ -148,10 +152,10 @@ ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> OWNER TO <repla
|
||||
<title>Notes</title>
|
||||
|
||||
<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
|
||||
<xref linkend="sql-alteruser" endterm="sql-alteruser-title">.
|
||||
User-specific settings override database-specific
|
||||
<xref linkend="sql-alterrole" endterm="sql-alterrole-title">.
|
||||
Role-specific settings override database-specific
|
||||
ones if there is a conflict.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$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
|
||||
-->
|
||||
|
||||
@ -21,7 +21,7 @@ PostgreSQL documentation
|
||||
<refsynopsisdiv>
|
||||
<synopsis>
|
||||
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> [, ...] ] )
|
||||
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> [, ...] ] )
|
||||
@ -36,8 +36,10 @@ where <replaceable class="PARAMETER">action</replaceable> is one of:
|
||||
[ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
|
||||
COST <replaceable class="parameter">execution_cost</replaceable>
|
||||
ROWS <replaceable class="parameter">result_rows</replaceable>
|
||||
SET <replaceable class="parameter">parameter</replaceable> { TO | = } { <replaceable class="parameter">value</replaceable> | DEFAULT }
|
||||
RESET <replaceable class="parameter">parameter</replaceable>
|
||||
SET <replaceable class="parameter">configuration_parameter</replaceable> { TO | = } { <replaceable class="parameter">value</replaceable> | DEFAULT }
|
||||
SET <replaceable class="parameter">configuration_parameter</replaceable> FROM CURRENT
|
||||
RESET <replaceable class="parameter">configuration_parameter</replaceable>
|
||||
RESET ALL
|
||||
</synopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
@ -215,7 +217,7 @@ where <replaceable class="PARAMETER">action</replaceable> is one of:
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><replaceable>parameter</replaceable></term>
|
||||
<term><replaceable>configuration_parameter</replaceable></term>
|
||||
<term><replaceable>value</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
@ -226,6 +228,8 @@ where <replaceable class="PARAMETER">action</replaceable> is one of:
|
||||
setting is removed, so that the function executes with the value
|
||||
present in its environment. Use <literal>RESET
|
||||
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>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$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
|
||||
-->
|
||||
|
||||
@ -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> 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 ALL
|
||||
</synopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
@ -77,7 +79,7 @@ ALTER ROLE <replaceable class="PARAMETER">name</replaceable> RESET <replaceable>
|
||||
</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
|
||||
starts a new session, the specified value becomes the session default,
|
||||
overriding whatever setting is present in <filename>postgresql.conf</>
|
||||
@ -155,6 +157,8 @@ ALTER ROLE <replaceable class="PARAMETER">name</replaceable> RESET <replaceable>
|
||||
role-specific variable setting is removed, so the role will
|
||||
inherit the system-wide default setting in new sessions. Use
|
||||
<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>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$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
|
||||
-->
|
||||
|
||||
@ -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> 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 ALL
|
||||
</synopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$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">
|
||||
@ -28,7 +28,7 @@ CREATE [ OR REPLACE ] FUNCTION
|
||||
| [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
|
||||
| COST <replaceable class="parameter">execution_cost</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">obj_file</replaceable>', '<replaceable class="parameter">link_symbol</replaceable>'
|
||||
} ...
|
||||
@ -324,13 +324,15 @@ CREATE [ OR REPLACE ] FUNCTION
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><replaceable>parameter</replaceable></term>
|
||||
<term><replaceable>configuration_parameter</replaceable></term>
|
||||
<term><replaceable>value</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>SET</> clause causes the specified configuration
|
||||
parameter to be set to the specified value when the function is
|
||||
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>
|
||||
|
@ -13,7 +13,7 @@
|
||||
*
|
||||
*
|
||||
* 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)
|
||||
char repl_null[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,
|
||||
@ -910,12 +910,12 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt)
|
||||
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE,
|
||||
stmt->dbname);
|
||||
|
||||
MemSet(repl_repl, ' ', sizeof(repl_repl));
|
||||
memset(repl_repl, ' ', sizeof(repl_repl));
|
||||
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_val[Anum_pg_database_datconfig - 1] = (Datum) 0;
|
||||
}
|
||||
@ -927,15 +927,16 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt)
|
||||
|
||||
repl_null[Anum_pg_database_datconfig - 1] = ' ';
|
||||
|
||||
/* Extract old value of datconfig */
|
||||
datum = heap_getattr(tuple, Anum_pg_database_datconfig,
|
||||
RelationGetDescr(rel), &isnull);
|
||||
|
||||
a = isnull ? NULL : DatumGetArrayTypeP(datum);
|
||||
|
||||
/* Update (valuestr is NULL in RESET cases) */
|
||||
if (valuestr)
|
||||
a = GUCArrayAdd(a, stmt->variable, valuestr);
|
||||
a = GUCArrayAdd(a, stmt->setstmt->name, valuestr);
|
||||
else
|
||||
a = GUCArrayDelete(a, stmt->variable);
|
||||
a = GUCArrayDelete(a, stmt->setstmt->name);
|
||||
|
||||
if (a)
|
||||
repl_val[Anum_pg_database_datconfig - 1] = PointerGetDatum(a);
|
||||
@ -943,7 +944,8 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt)
|
||||
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);
|
||||
|
||||
/* Update indexes */
|
||||
|
@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* 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
|
||||
* These routines take the parse tree and pick out the
|
||||
@ -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.
|
||||
*/
|
||||
@ -365,33 +365,20 @@ update_proconfig_value(ArrayType *a, List *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);
|
||||
}
|
||||
else /* SET TO DEFAULT */
|
||||
else /* RESET */
|
||||
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;
|
||||
|
@ -6,7 +6,7 @@
|
||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||
* 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)
|
||||
Datum repl_val[Natts_pg_authid];
|
||||
char repl_null[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);
|
||||
oldtuple = SearchSysCache(AUTHNAME,
|
||||
@ -754,14 +753,14 @@ AlterRoleSet(AlterRoleSetStmt *stmt)
|
||||
errmsg("permission denied")));
|
||||
}
|
||||
|
||||
for (i = 0; i < Natts_pg_authid; i++)
|
||||
repl_repl[i] = ' ';
|
||||
|
||||
memset(repl_repl, ' ', sizeof(repl_repl));
|
||||
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_val[Anum_pg_authid_rolconfig - 1] = (Datum) 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -771,15 +770,16 @@ AlterRoleSet(AlterRoleSetStmt *stmt)
|
||||
|
||||
repl_null[Anum_pg_authid_rolconfig - 1] = ' ';
|
||||
|
||||
/* Extract old value of rolconfig */
|
||||
datum = SysCacheGetAttr(AUTHNAME, oldtuple,
|
||||
Anum_pg_authid_rolconfig, &isnull);
|
||||
|
||||
array = isnull ? NULL : DatumGetArrayTypeP(datum);
|
||||
|
||||
/* Update (valuestr is NULL in RESET cases) */
|
||||
if (valuestr)
|
||||
array = GUCArrayAdd(array, stmt->variable, valuestr);
|
||||
array = GUCArrayAdd(array, stmt->setstmt->name, valuestr);
|
||||
else
|
||||
array = GUCArrayDelete(array, stmt->variable);
|
||||
array = GUCArrayDelete(array, stmt->setstmt->name);
|
||||
|
||||
if (array)
|
||||
repl_val[Anum_pg_authid_rolconfig - 1] = PointerGetDatum(array);
|
||||
|
@ -15,7 +15,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* 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)
|
||||
AlterDatabaseSetStmt *newnode = makeNode(AlterDatabaseSetStmt);
|
||||
|
||||
COPY_STRING_FIELD(dbname);
|
||||
COPY_STRING_FIELD(variable);
|
||||
COPY_NODE_FIELD(value);
|
||||
COPY_NODE_FIELD(setstmt);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
@ -2597,6 +2596,7 @@ _copyVariableSetStmt(VariableSetStmt *from)
|
||||
{
|
||||
VariableSetStmt *newnode = makeNode(VariableSetStmt);
|
||||
|
||||
COPY_SCALAR_FIELD(kind);
|
||||
COPY_STRING_FIELD(name);
|
||||
COPY_NODE_FIELD(args);
|
||||
COPY_SCALAR_FIELD(is_local);
|
||||
@ -2614,16 +2614,6 @@ _copyVariableShowStmt(VariableShowStmt *from)
|
||||
return newnode;
|
||||
}
|
||||
|
||||
static VariableResetStmt *
|
||||
_copyVariableResetStmt(VariableResetStmt *from)
|
||||
{
|
||||
VariableResetStmt *newnode = makeNode(VariableResetStmt);
|
||||
|
||||
COPY_STRING_FIELD(name);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
static DiscardStmt *
|
||||
_copyDiscardStmt(DiscardStmt *from)
|
||||
{
|
||||
@ -2746,8 +2736,7 @@ _copyAlterRoleSetStmt(AlterRoleSetStmt *from)
|
||||
AlterRoleSetStmt *newnode = makeNode(AlterRoleSetStmt);
|
||||
|
||||
COPY_STRING_FIELD(role);
|
||||
COPY_STRING_FIELD(variable);
|
||||
COPY_NODE_FIELD(value);
|
||||
COPY_NODE_FIELD(setstmt);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
@ -3428,9 +3417,6 @@ copyObject(void *from)
|
||||
case T_VariableShowStmt:
|
||||
retval = _copyVariableShowStmt(from);
|
||||
break;
|
||||
case T_VariableResetStmt:
|
||||
retval = _copyVariableResetStmt(from);
|
||||
break;
|
||||
case T_DiscardStmt:
|
||||
retval = _copyDiscardStmt(from);
|
||||
break;
|
||||
|
@ -18,7 +18,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* 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
|
||||
_equalAlterDatabaseSetStmt(AlterDatabaseSetStmt *a, AlterDatabaseSetStmt *b)
|
||||
{
|
||||
COMPARE_STRING_FIELD(dbname);
|
||||
COMPARE_STRING_FIELD(variable);
|
||||
COMPARE_NODE_FIELD(value);
|
||||
COMPARE_NODE_FIELD(setstmt);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1385,6 +1384,7 @@ _equalAlterSeqStmt(AlterSeqStmt *a, AlterSeqStmt *b)
|
||||
static bool
|
||||
_equalVariableSetStmt(VariableSetStmt *a, VariableSetStmt *b)
|
||||
{
|
||||
COMPARE_SCALAR_FIELD(kind);
|
||||
COMPARE_STRING_FIELD(name);
|
||||
COMPARE_NODE_FIELD(args);
|
||||
COMPARE_SCALAR_FIELD(is_local);
|
||||
@ -1400,14 +1400,6 @@ _equalVariableShowStmt(VariableShowStmt *a, VariableShowStmt *b)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalVariableResetStmt(VariableResetStmt *a, VariableResetStmt *b)
|
||||
{
|
||||
COMPARE_STRING_FIELD(name);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalDiscardStmt(DiscardStmt *a, DiscardStmt *b)
|
||||
{
|
||||
@ -1511,8 +1503,7 @@ static bool
|
||||
_equalAlterRoleSetStmt(AlterRoleSetStmt *a, AlterRoleSetStmt *b)
|
||||
{
|
||||
COMPARE_STRING_FIELD(role);
|
||||
COMPARE_STRING_FIELD(variable);
|
||||
COMPARE_NODE_FIELD(value);
|
||||
COMPARE_NODE_FIELD(setstmt);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -2356,9 +2347,6 @@ equal(void *a, void *b)
|
||||
case T_VariableShowStmt:
|
||||
retval = _equalVariableShowStmt(a, b);
|
||||
break;
|
||||
case T_VariableResetStmt:
|
||||
retval = _equalVariableResetStmt(a, b);
|
||||
break;
|
||||
case T_DiscardStmt:
|
||||
retval = _equalDiscardStmt(a, b);
|
||||
break;
|
||||
|
@ -11,7 +11,7 @@
|
||||
*
|
||||
*
|
||||
* 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
|
||||
* AUTHOR DATE MAJOR EVENT
|
||||
@ -292,7 +292,7 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
|
||||
|
||||
%type <istmt> insert_rest
|
||||
|
||||
%type <vsetstmt> set_rest
|
||||
%type <vsetstmt> set_rest SetResetClause
|
||||
|
||||
%type <node> TableElement ConstraintElem TableFuncElement
|
||||
%type <node> columnDef
|
||||
@ -330,7 +330,7 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
|
||||
%type <ival> Iconst SignedIconst
|
||||
%type <str> Sconst comment_text
|
||||
%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 <node> var_value zone_value
|
||||
|
||||
@ -796,20 +796,11 @@ AlterRoleStmt:
|
||||
;
|
||||
|
||||
AlterRoleSetStmt:
|
||||
ALTER ROLE RoleId SET set_rest
|
||||
ALTER ROLE RoleId SetResetClause
|
||||
{
|
||||
AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
|
||||
n->role = $3;
|
||||
n->variable = $5->name;
|
||||
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;
|
||||
n->setstmt = $4;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
;
|
||||
@ -834,20 +825,11 @@ AlterUserStmt:
|
||||
|
||||
|
||||
AlterUserSetStmt:
|
||||
ALTER USER RoleId SET set_rest
|
||||
ALTER USER RoleId SetResetClause
|
||||
{
|
||||
AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
|
||||
n->role = $3;
|
||||
n->variable = $5->name;
|
||||
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;
|
||||
n->setstmt = $4;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
;
|
||||
@ -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);
|
||||
n->kind = VAR_SET_VALUE;
|
||||
n->name = $1;
|
||||
n->args = $3;
|
||||
$$ = n;
|
||||
}
|
||||
| var_name '=' var_list_or_default
|
||||
| var_name '=' var_list
|
||||
{
|
||||
VariableSetStmt *n = makeNode(VariableSetStmt);
|
||||
n->kind = VAR_SET_VALUE;
|
||||
n->name = $1;
|
||||
n->args = $3;
|
||||
$$ = 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
|
||||
{
|
||||
VariableSetStmt *n = makeNode(VariableSetStmt);
|
||||
n->kind = VAR_SET_VALUE;
|
||||
n->name = "timezone";
|
||||
if ($3 != NULL)
|
||||
n->args = list_make1($3);
|
||||
else
|
||||
n->kind = VAR_SET_DEFAULT;
|
||||
$$ = n;
|
||||
}
|
||||
| TRANSACTION transaction_mode_list
|
||||
{
|
||||
VariableSetStmt *n = makeNode(VariableSetStmt);
|
||||
n->kind = VAR_SET_MULTI;
|
||||
n->name = "TRANSACTION";
|
||||
n->args = $2;
|
||||
$$ = n;
|
||||
@ -1088,6 +1099,7 @@ set_rest: var_name TO var_list_or_default
|
||||
| SESSION CHARACTERISTICS AS TRANSACTION transaction_mode_list
|
||||
{
|
||||
VariableSetStmt *n = makeNode(VariableSetStmt);
|
||||
n->kind = VAR_SET_MULTI;
|
||||
n->name = "SESSION CHARACTERISTICS";
|
||||
n->args = $5;
|
||||
$$ = n;
|
||||
@ -1095,14 +1107,18 @@ set_rest: var_name TO var_list_or_default
|
||||
| NAMES opt_encoding
|
||||
{
|
||||
VariableSetStmt *n = makeNode(VariableSetStmt);
|
||||
n->kind = VAR_SET_VALUE;
|
||||
n->name = "client_encoding";
|
||||
if ($2 != NULL)
|
||||
n->args = list_make1(makeStringConst($2, NULL));
|
||||
else
|
||||
n->kind = VAR_SET_DEFAULT;
|
||||
$$ = n;
|
||||
}
|
||||
| ROLE ColId_or_Sconst
|
||||
{
|
||||
VariableSetStmt *n = makeNode(VariableSetStmt);
|
||||
n->kind = VAR_SET_VALUE;
|
||||
n->name = "role";
|
||||
n->args = list_make1(makeStringConst($2, NULL));
|
||||
$$ = n;
|
||||
@ -1110,6 +1126,7 @@ set_rest: var_name TO var_list_or_default
|
||||
| SESSION AUTHORIZATION ColId_or_Sconst
|
||||
{
|
||||
VariableSetStmt *n = makeNode(VariableSetStmt);
|
||||
n->kind = VAR_SET_VALUE;
|
||||
n->name = "session_authorization";
|
||||
n->args = list_make1(makeStringConst($3, NULL));
|
||||
$$ = n;
|
||||
@ -1117,37 +1134,28 @@ set_rest: var_name TO var_list_or_default
|
||||
| SESSION AUTHORIZATION DEFAULT
|
||||
{
|
||||
VariableSetStmt *n = makeNode(VariableSetStmt);
|
||||
n->kind = VAR_SET_DEFAULT;
|
||||
n->name = "session_authorization";
|
||||
n->args = NIL;
|
||||
$$ = n;
|
||||
}
|
||||
| XML_P OPTION document_or_content
|
||||
{
|
||||
VariableSetStmt *n = makeNode(VariableSetStmt);
|
||||
n->kind = VAR_SET_VALUE;
|
||||
n->name = "xmloption";
|
||||
n->args = list_make1(makeStringConst($3 == XMLOPTION_DOCUMENT ? "DOCUMENT" : "CONTENT", NULL));
|
||||
$$ = n;
|
||||
}
|
||||
;
|
||||
|
||||
var_name:
|
||||
ColId { $$ = $1; }
|
||||
var_name: ColId { $$ = $1; }
|
||||
| var_name '.' ColId
|
||||
{
|
||||
int qLen = strlen($1);
|
||||
char* qualName = palloc(qLen + strlen($3) + 2);
|
||||
strcpy(qualName, $1);
|
||||
qualName[qLen] = '.';
|
||||
strcpy(qualName + qLen + 1, $3);
|
||||
$$ = qualName;
|
||||
$$ = palloc(strlen($1) + strlen($3) + 2);
|
||||
sprintf($$, "%s.%s", $1, $3);
|
||||
}
|
||||
;
|
||||
|
||||
var_list_or_default:
|
||||
var_list { $$ = $1; }
|
||||
| DEFAULT { $$ = NIL; }
|
||||
;
|
||||
|
||||
var_list: var_value { $$ = list_make1($1); }
|
||||
| var_list ',' var_value { $$ = lappend($1, $3); }
|
||||
;
|
||||
@ -1231,6 +1239,49 @@ ColId_or_Sconst:
|
||||
| SCONST { $$ = $1; }
|
||||
;
|
||||
|
||||
VariableResetStmt:
|
||||
RESET var_name
|
||||
{
|
||||
VariableSetStmt *n = makeNode(VariableSetStmt);
|
||||
n->kind = VAR_RESET;
|
||||
n->name = $2;
|
||||
$$ = (Node *) n;
|
||||
}
|
||||
| RESET TIME ZONE
|
||||
{
|
||||
VariableSetStmt *n = makeNode(VariableSetStmt);
|
||||
n->kind = VAR_RESET;
|
||||
n->name = "timezone";
|
||||
$$ = (Node *) n;
|
||||
}
|
||||
| RESET TRANSACTION ISOLATION LEVEL
|
||||
{
|
||||
VariableSetStmt *n = makeNode(VariableSetStmt);
|
||||
n->kind = VAR_RESET;
|
||||
n->name = "transaction_isolation";
|
||||
$$ = (Node *) n;
|
||||
}
|
||||
| RESET SESSION AUTHORIZATION
|
||||
{
|
||||
VariableSetStmt *n = makeNode(VariableSetStmt);
|
||||
n->kind = VAR_RESET;
|
||||
n->name = "session_authorization";
|
||||
$$ = (Node *) n;
|
||||
}
|
||||
| RESET ALL
|
||||
{
|
||||
VariableSetStmt *n = makeNode(VariableSetStmt);
|
||||
n->kind = VAR_RESET_ALL;
|
||||
$$ = (Node *) n;
|
||||
}
|
||||
;
|
||||
|
||||
/* SetResetClause allows SET or RESET without LOCAL */
|
||||
SetResetClause:
|
||||
SET set_rest { $$ = $2; }
|
||||
| VariableResetStmt { $$ = (VariableSetStmt *) $1; }
|
||||
;
|
||||
|
||||
|
||||
VariableShowStmt:
|
||||
SHOW var_name
|
||||
@ -1265,39 +1316,6 @@ VariableShowStmt:
|
||||
}
|
||||
;
|
||||
|
||||
VariableResetStmt:
|
||||
RESET var_name
|
||||
{
|
||||
VariableResetStmt *n = makeNode(VariableResetStmt);
|
||||
n->name = $2;
|
||||
$$ = (Node *) n;
|
||||
}
|
||||
| RESET TIME ZONE
|
||||
{
|
||||
VariableResetStmt *n = makeNode(VariableResetStmt);
|
||||
n->name = "timezone";
|
||||
$$ = (Node *) n;
|
||||
}
|
||||
| RESET TRANSACTION ISOLATION LEVEL
|
||||
{
|
||||
VariableResetStmt *n = makeNode(VariableResetStmt);
|
||||
n->name = "transaction_isolation";
|
||||
$$ = (Node *) n;
|
||||
}
|
||||
| RESET SESSION AUTHORIZATION
|
||||
{
|
||||
VariableResetStmt *n = makeNode(VariableResetStmt);
|
||||
n->name = "session_authorization";
|
||||
$$ = (Node *) n;
|
||||
}
|
||||
| RESET ALL
|
||||
{
|
||||
VariableResetStmt *n = makeNode(VariableResetStmt);
|
||||
n->name = "all";
|
||||
$$ = (Node *) n;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
ConstraintsSetStmt:
|
||||
SET CONSTRAINTS constraints_set_list constraints_set_mode
|
||||
@ -4270,15 +4288,10 @@ common_func_opt_item:
|
||||
{
|
||||
$$ = 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 */
|
||||
$$ = makeDefElem("set", $1);
|
||||
$$ = makeDefElem("set", (Node *)$1);
|
||||
}
|
||||
;
|
||||
|
||||
@ -5391,20 +5404,11 @@ AlterDatabaseStmt:
|
||||
;
|
||||
|
||||
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);
|
||||
n->dbname = $3;
|
||||
n->variable = ((VariableResetStmt *)$4)->name;
|
||||
n->value = NIL;
|
||||
n->setstmt = $4;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
;
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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,
|
||||
IsA(utilityStmt, LockStmt) ||
|
||||
IsA(utilityStmt, VariableSetStmt) ||
|
||||
IsA(utilityStmt, VariableShowStmt) ||
|
||||
IsA(utilityStmt, VariableResetStmt) ||
|
||||
IsA(utilityStmt, ConstraintsSetStmt) ||
|
||||
/* efficiency hacks from here down */
|
||||
IsA(utilityStmt, FetchStmt) ||
|
||||
|
@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* 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,
|
||||
break;
|
||||
|
||||
case T_VariableSetStmt:
|
||||
{
|
||||
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);
|
||||
}
|
||||
ExecSetVariableStmt((VariableSetStmt *) parsetree);
|
||||
break;
|
||||
|
||||
case T_VariableShowStmt:
|
||||
@ -1093,14 +1052,6 @@ ProcessUtility(Node *parsetree,
|
||||
}
|
||||
break;
|
||||
|
||||
case T_VariableResetStmt:
|
||||
{
|
||||
VariableResetStmt *n = (VariableResetStmt *) parsetree;
|
||||
|
||||
ResetPGVariable(n->name, isTopLevel);
|
||||
}
|
||||
break;
|
||||
|
||||
case T_DiscardStmt:
|
||||
DiscardCommand((DiscardStmt *) parsetree, isTopLevel);
|
||||
break;
|
||||
@ -1924,19 +1875,30 @@ CreateCommandTag(Node *parsetree)
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
case T_VariableShowStmt:
|
||||
tag = "SHOW";
|
||||
break;
|
||||
|
||||
case T_VariableResetStmt:
|
||||
tag = "RESET";
|
||||
break;
|
||||
|
||||
case T_DiscardStmt:
|
||||
switch (((DiscardStmt *) parsetree)->target) {
|
||||
switch (((DiscardStmt *) parsetree)->target)
|
||||
{
|
||||
case DISCARD_ALL:
|
||||
tag = "DISCARD ALL";
|
||||
break;
|
||||
@ -2402,10 +2364,6 @@ GetCommandLogLevel(Node *parsetree)
|
||||
lev = LOGSTMT_ALL;
|
||||
break;
|
||||
|
||||
case T_VariableResetStmt:
|
||||
lev = LOGSTMT_ALL;
|
||||
break;
|
||||
|
||||
case T_CreateTrigStmt:
|
||||
lev = LOGSTMT_DDL;
|
||||
break;
|
||||
|
@ -10,7 +10,7 @@
|
||||
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
||||
*
|
||||
* 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)
|
||||
* We need to be told the name of the variable the args are for, because
|
||||
* 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.
|
||||
*/
|
||||
char *
|
||||
static char *
|
||||
flatten_set_variable_args(const char *name, List *args)
|
||||
{
|
||||
struct config_generic *record;
|
||||
@ -4881,10 +4881,7 @@ flatten_set_variable_args(const char *name, List *args)
|
||||
StringInfoData buf;
|
||||
ListCell *l;
|
||||
|
||||
/*
|
||||
* Fast path if just DEFAULT. We do not check the variable name in this
|
||||
* case --- necessary for RESET ALL to work correctly.
|
||||
*/
|
||||
/* Fast path if just DEFAULT */
|
||||
if (args == NIL)
|
||||
return NULL;
|
||||
|
||||
@ -4979,6 +4976,108 @@ flatten_set_variable_args(const char *name, List *args)
|
||||
* SET command
|
||||
*/
|
||||
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)
|
||||
{
|
||||
char *argstring = flatten_set_variable_args(name, args);
|
||||
@ -5045,6 +5144,7 @@ set_config_by_name(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_TEXT_P(result_text);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
define_custom_variable(struct config_generic * variable)
|
||||
{
|
||||
@ -5283,23 +5383,6 @@ GetPGVariableResultDesc(const char *name)
|
||||
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
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||
* 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
|
||||
T_AlterSeqStmt,
|
||||
T_VariableSetStmt,
|
||||
T_VariableShowStmt,
|
||||
T_VariableResetStmt,
|
||||
T_DiscardStmt,
|
||||
T_CreateTrigStmt,
|
||||
T_DropPropertyStmt,
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||
* 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
|
||||
List *options; /* List of DefElem nodes */
|
||||
} 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
|
||||
*
|
||||
@ -1264,8 +1300,7 @@ typedef struct AlterRoleSetStmt
|
||||
{
|
||||
NodeTag type;
|
||||
char *role; /* role name */
|
||||
char *variable; /* GUC variable name */
|
||||
List *value; /* value for variable, or NIL for Reset */
|
||||
VariableSetStmt *setstmt; /* SET or RESET subcommand */
|
||||
} AlterRoleSetStmt;
|
||||
|
||||
typedef struct DropRoleStmt
|
||||
@ -1781,9 +1816,8 @@ typedef struct AlterDatabaseStmt
|
||||
typedef struct AlterDatabaseSetStmt
|
||||
{
|
||||
NodeTag type;
|
||||
char *dbname;
|
||||
char *variable;
|
||||
List *value;
|
||||
char *dbname; /* database name */
|
||||
VariableSetStmt *setstmt; /* SET or RESET subcommand */
|
||||
} AlterDatabaseSetStmt;
|
||||
|
||||
/* ----------------------
|
||||
@ -1848,41 +1882,6 @@ typedef struct CheckPointStmt
|
||||
NodeTag type;
|
||||
} 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
|
||||
* ----------------------
|
||||
|
@ -7,12 +7,13 @@
|
||||
* Copyright (c) 2000-2007, PostgreSQL Global Development Group
|
||||
* 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
|
||||
#define GUC_H
|
||||
|
||||
#include "nodes/parsenodes.h"
|
||||
#include "tcop/dest.h"
|
||||
#include "utils/array.h"
|
||||
|
||||
@ -203,9 +204,9 @@ extern int GetNumConfigOptions(void);
|
||||
extern void SetPGVariable(const char *name, List *args, bool is_local);
|
||||
extern void GetPGVariable(const char *name, DestReceiver *dest);
|
||||
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,
|
||||
GucContext context, GucSource source, bool isLocal);
|
||||
|
Loading…
x
Reference in New Issue
Block a user