Support SET FROM CURRENT in CREATE/ALTER FUNCTION, ALTER DATABASE, ALTER ROLE.
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 3 Sep 2007 18:46:30 +0000 (18:46 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 3 Sep 2007 18:46:30 +0000 (18:46 +0000)
(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.

17 files changed:
doc/src/sgml/ref/alter_database.sgml
doc/src/sgml/ref/alter_function.sgml
doc/src/sgml/ref/alter_role.sgml
doc/src/sgml/ref/alter_user.sgml
doc/src/sgml/ref/create_function.sgml
src/backend/commands/dbcommands.c
src/backend/commands/functioncmds.c
src/backend/commands/user.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/parser/gram.y
src/backend/tcop/pquery.c
src/backend/tcop/utility.c
src/backend/utils/misc/guc.c
src/include/nodes/nodes.h
src/include/nodes/parsenodes.h
src/include/utils/guc.h

index 8ddff97e029ca94063734d2b4c855a4297a1f010..d16cc2fdad1a0b889d34d94b00f0d85469284d68 100644 (file)
@@ -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>
index 964603b067a15659d023bd2fd03839148a6dd122..bee2f6f4390f201be9b3c7fdc4cfe038bf7bb2eb 100644 (file)
@@ -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>
index ce28f2ad59792904977ce8a6968e9077386eab6f..a471095e4963d88b1d9379b8f751582ee9e2531b 100644 (file)
@@ -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>
index 8f41a35e7aa237ae4f8250607b0022ce24813454..f989651d6fe02e85b678d47e2bb649b1475df5a5 100644 (file)
@@ -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>
 
index 7aff876d37d203bffe6cf5520816179e382fbee4..b0cfe84db1c67ed14735b56ca270f02b2c997789 100644 (file)
@@ -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>
index 34b6da99df9c4f79e6ad0b3e63efa10858041ec3..f6274803622112a5a08969bc1158685d3dca9cb3 100644 (file)
@@ -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 */
index a6768ab83c2de0f3bde287027aebd5f52cf25feb..9e5d0b1095ba08f16c3cc0105f122dc5c7bd7d62 100644 (file)
@@ -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;
index cbbc31ca6f088e43c60674394f5e6a08bb1017bf..ccf34178a074e9d5c89c45fd9c96077b17764275 100644 (file)
@@ -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);
index 932da9f4d239053333857a44b9319595bc1d18f7..b6c6331d17085809b4d6ea59a02a23a0e416d8ac 100644 (file)
@@ -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;
index 68a503547606f12a6cecbb7aaffee81eb3e24e06..a12351ae289581a63929b743f83059c69dca3c33 100644 (file)
@@ -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;
index 9f9f644168f8bc3b7796dede76180304ad6e29e0..a7521eca522a5a7172494a1295502211885d408f 100644 (file)
@@ -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;
                                }
                ;
index 58ed351c59e3a153e6233add0380aea10c8cbfce..15b2cd4c2cfc40bd55abc8bc7a178c4d7f7a7a6e 100644 (file)
@@ -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) ||
index c38647db322d0885fdeaefda938f13a1ba73bfe3..d0b23d8d2925ee84fc0943d3b5a0fae89519b3a9 100644 (file)
@@ -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;
index b8c7b85494520bc22105b714492afc5dfbe7785e..60f7ed5ca32b6325f074a4be3ceef81f257da337 100644 (file)
@@ -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
index 7f6a08f450fd4af7d3e2cfdac55543b7ff5c7c8b..fa9d318509b936e5bcbfa0254f2e0866ba98da27 100644 (file)
@@ -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,
index 79449c55847c84f8c865d4b646675d696045b32e..412fadac54e94784e8207478a55c19608c859185 100644 (file)
@@ -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
  * ----------------------
index 5dd06ee7a124d646e9a406fd586e2d0705f5f705..d8fafff55902222bac01e59a9115aa047b4717ab 100644 (file)
@@ -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);