diff --git a/doc/src/sgml/ref/alter_database.sgml b/doc/src/sgml/ref/alter_database.sgml index 8ddff97e029ca94063734d2b4c855a4297a1f010..d16cc2fdad1a0b889d34d94b00f0d85469284d68 100644 --- a/doc/src/sgml/ref/alter_database.sgml +++ b/doc/src/sgml/ref/alter_database.sgml @@ -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,20 +51,7 @@ 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 - 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 + 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 @@ -71,12 +60,25 @@ ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> OWNER TO <repla </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 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. + 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> @@ -102,8 +104,26 @@ ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> OWNER TO <repla </listitem> </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> - <term><replaceable>parameter</replaceable></term> + <term><replaceable>configuration_parameter</replaceable></term> <term><replaceable>value</replaceable></term> <listitem> <para> @@ -114,6 +134,8 @@ ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> OWNER TO <repla 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> @@ -123,24 +145,6 @@ ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> OWNER TO <repla </para> </listitem> </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> </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> diff --git a/doc/src/sgml/ref/alter_function.sgml b/doc/src/sgml/ref/alter_function.sgml index 964603b067a15659d023bd2fd03839148a6dd122..bee2f6f4390f201be9b3c7fdc4cfe038bf7bb2eb 100644 --- a/doc/src/sgml/ref/alter_function.sgml +++ b/doc/src/sgml/ref/alter_function.sgml @@ -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> diff --git a/doc/src/sgml/ref/alter_role.sgml b/doc/src/sgml/ref/alter_role.sgml index ce28f2ad59792904977ce8a6968e9077386eab6f..a471095e4963d88b1d9379b8f751582ee9e2531b 100644 --- a/doc/src/sgml/ref/alter_role.sgml +++ b/doc/src/sgml/ref/alter_role.sgml @@ -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> diff --git a/doc/src/sgml/ref/alter_user.sgml b/doc/src/sgml/ref/alter_user.sgml index 8f41a35e7aa237ae4f8250607b0022ce24813454..f989651d6fe02e85b678d47e2bb649b1475df5a5 100644 --- a/doc/src/sgml/ref/alter_user.sgml +++ b/doc/src/sgml/ref/alter_user.sgml @@ -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> diff --git a/doc/src/sgml/ref/create_function.sgml b/doc/src/sgml/ref/create_function.sgml index 7aff876d37d203bffe6cf5520816179e382fbee4..b0cfe84db1c67ed14735b56ca270f02b2c997789 100644 --- a/doc/src/sgml/ref/create_function.sgml +++ b/doc/src/sgml/ref/create_function.sgml @@ -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> diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index 34b6da99df9c4f79e6ad0b3e63efa10858041ec3..f6274803622112a5a08969bc1158685d3dca9cb3 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -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 */ diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index a6768ab83c2de0f3bde287027aebd5f52cf25feb..9e5d0b1095ba08f16c3cc0105f122dc5c7bd7d62 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -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; - - if (sstmt->args) - { - char *valuestr; + char *valuestr = ExtractSetVariableArgs(sstmt); - 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; diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index cbbc31ca6f088e43c60674394f5e6a08bb1017bf..ccf34178a074e9d5c89c45fd9c96077b17764275 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -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); diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 932da9f4d239053333857a44b9319595bc1d18f7..b6c6331d17085809b4d6ea59a02a23a0e416d8ac 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -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; diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 68a503547606f12a6cecbb7aaffee81eb3e24e06..a12351ae289581a63929b743f83059c69dca3c33 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -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; diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 9f9f644168f8bc3b7796dede76180304ad6e29e0..a7521eca522a5a7172494a1295502211885d408f 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -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,68 +1239,78 @@ ColId_or_Sconst: | SCONST { $$ = $1; } ; - -VariableShowStmt: - SHOW var_name +VariableResetStmt: + RESET var_name { - VariableShowStmt *n = makeNode(VariableShowStmt); + VariableSetStmt *n = makeNode(VariableSetStmt); + n->kind = VAR_RESET; n->name = $2; $$ = (Node *) n; } - | SHOW TIME ZONE + | RESET TIME ZONE { - VariableShowStmt *n = makeNode(VariableShowStmt); + VariableSetStmt *n = makeNode(VariableSetStmt); + n->kind = VAR_RESET; n->name = "timezone"; $$ = (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"; $$ = (Node *) n; } - | SHOW SESSION AUTHORIZATION + | RESET SESSION AUTHORIZATION { - VariableShowStmt *n = makeNode(VariableShowStmt); + VariableSetStmt *n = makeNode(VariableSetStmt); + n->kind = VAR_RESET; n->name = "session_authorization"; $$ = (Node *) n; } - | SHOW ALL + | RESET ALL { - VariableShowStmt *n = makeNode(VariableShowStmt); - n->name = "all"; + VariableSetStmt *n = makeNode(VariableSetStmt); + n->kind = VAR_RESET_ALL; $$ = (Node *) n; } ; -VariableResetStmt: - RESET var_name +/* SetResetClause allows SET or RESET without LOCAL */ +SetResetClause: + SET set_rest { $$ = $2; } + | VariableResetStmt { $$ = (VariableSetStmt *) $1; } + ; + + +VariableShowStmt: + SHOW var_name { - VariableResetStmt *n = makeNode(VariableResetStmt); + VariableShowStmt *n = makeNode(VariableShowStmt); n->name = $2; $$ = (Node *) n; } - | RESET TIME ZONE + | SHOW TIME ZONE { - VariableResetStmt *n = makeNode(VariableResetStmt); + VariableShowStmt *n = makeNode(VariableShowStmt); n->name = "timezone"; $$ = (Node *) n; } - | RESET TRANSACTION ISOLATION LEVEL + | SHOW TRANSACTION ISOLATION LEVEL { - VariableResetStmt *n = makeNode(VariableResetStmt); + VariableShowStmt *n = makeNode(VariableShowStmt); n->name = "transaction_isolation"; $$ = (Node *) n; } - | RESET SESSION AUTHORIZATION + | SHOW SESSION AUTHORIZATION { - VariableResetStmt *n = makeNode(VariableResetStmt); + VariableShowStmt *n = makeNode(VariableShowStmt); n->name = "session_authorization"; $$ = (Node *) n; } - | RESET ALL + | SHOW ALL { - VariableResetStmt *n = makeNode(VariableResetStmt); + VariableShowStmt *n = makeNode(VariableShowStmt); n->name = "all"; $$ = (Node *) n; } @@ -4270,15 +4288,10 @@ common_func_opt_item: { $$ = makeDefElem("rows", (Node *)$2); } - | SET set_rest - { - /* we abuse the normal content of a DefElem here */ - $$ = makeDefElem("set", (Node *)$2); - } - | VariableResetStmt + | SetResetClause { /* 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 - { - AlterDatabaseSetStmt *n = makeNode(AlterDatabaseSetStmt); - n->dbname = $3; - n->variable = $5->name; - n->value = $5->args; - $$ = (Node *)n; - } - | ALTER DATABASE database_name VariableResetStmt + ALTER DATABASE database_name SetResetClause { AlterDatabaseSetStmt *n = makeNode(AlterDatabaseSetStmt); n->dbname = $3; - n->variable = ((VariableResetStmt *)$4)->name; - n->value = NIL; + n->setstmt = $4; $$ = (Node *)n; } ; diff --git a/src/backend/tcop/pquery.c b/src/backend/tcop/pquery.c index 58ed351c59e3a153e6233add0380aea10c8cbfce..15b2cd4c2cfc40bd55abc8bc7a178c4d7f7a7a6e 100644 --- a/src/backend/tcop/pquery.c +++ b/src/backend/tcop/pquery.c @@ -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) || diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index c38647db322d0885fdeaefda938f13a1ba73bfe3..d0b23d8d2925ee84fc0943d3b5a0fae89519b3a9 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -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; diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index b8c7b85494520bc22105b714492afc5dfbe7785e..60f7ed5ca32b6325f074a4be3ceef81f257da337 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -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 diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index 7f6a08f450fd4af7d3e2cfdac55543b7ff5c7c8b..fa9d318509b936e5bcbfa0254f2e0866ba98da27 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -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, diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 79449c55847c84f8c865d4b646675d696045b32e..412fadac54e94784e8207478a55c19608c859185 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -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 * ---------------------- diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h index 5dd06ee7a124d646e9a406fd586e2d0705f5f705..d8fafff55902222bac01e59a9115aa047b4717ab 100644 --- a/src/include/utils/guc.h +++ b/src/include/utils/guc.h @@ -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);