Support SET FROM CURRENT in CREATE/ALTER FUNCTION, ALTER DATABASE, ALTER ROLE.
authorTom Lane
Mon, 3 Sep 2007 18:46:30 +0000 (18:46 +0000)
committerTom Lane
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 @@
 
 
@@ -26,12 +26,14 @@ where option can be:
 
     CONNECTION LIMIT connlimit
 
-ALTER DATABASE name SET parameter { TO | = } { value | DEFAULT }
-ALTER DATABASE name RESET parameter
-
 ALTER DATABASE name RENAME TO newname
 
 ALTER DATABASE name OWNER TO new_owner
+
+ALTER DATABASE name SET configuration_parameter { TO | = } { value | DEFAULT }
+ALTER DATABASE name SET configuration_parameter FROM CURRENT
+ALTER DATABASE name RESET configuration_parameter
+ALTER DATABASE name RESET ALL
 
  
 
@@ -49,20 +51,7 @@ ALTER DATABASE name OWNER TO 
    
 
   
-   The second and third forms change the session default for a run-time
-   configuration variable for a PostgreSQL
-   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 postgresql.conf or has been received from the
-   postgres 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.
-  
-
-  
-   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
    CREATEDB privilege.  The current database cannot
@@ -71,12 +60,25 @@ ALTER DATABASE name OWNER TO 
   
 
   
-   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
    CREATEDB privilege.
    (Note that superusers have all these privileges automatically.)
   
+
+  
+   The remaining forms change the session default for a run-time
+   configuration variable for a PostgreSQL
+   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 postgresql.conf or has been received from the
+   postgres 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.
+  
  
 
  
@@ -102,8 +104,26 @@ ALTER DATABASE name OWNER TO 
       
       
 
+   
+    newname
+    
+     
+      The new name of the database.
+     
+    
+   
+
+   
+    new_owner
+    
+     
+      The new owner of the database.
+     
+    
+   
+
      
-      parameter
+      configuration_parameter
       value
       
        
@@ -114,6 +134,8 @@ ALTER DATABASE name OWNER TO 
         database-specific setting is removed, so the system-wide default
         setting will be inherited in new sessions.  Use RESET
         ALL to clear all database-specific settings.
+        SET FROM CURRENT saves the session's current value of
+        the parameter as the database-specific value.
        
 
        
@@ -123,24 +145,6 @@ ALTER DATABASE name OWNER TO 
        
       
      
-
-   
-    newname
-    
-     
-      The new name of the database.
-     
-    
-   
-
-   
-    new_owner
-    
-     
-      The new owner of the database.
-     
-    
-   
   
  
 
@@ -148,10 +152,10 @@ ALTER DATABASE name OWNER TO 
   Notes
 
   
-   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
-   user" endterm="sql-alteruser-title">.
-   User-specific settings override database-specific
+   role" endterm="sql-alterrole-title">.
+   Role-specific settings override database-specific
    ones if there is a conflict.
   
  
index 964603b067a15659d023bd2fd03839148a6dd122..bee2f6f4390f201be9b3c7fdc4cfe038bf7bb2eb 100644 (file)
@@ -1,5 +1,5 @@
 
 
@@ -21,7 +21,7 @@ PostgreSQL documentation
  
 
 ALTER FUNCTION name ( [ [ argmode ] [ argname ] argtype [, ...] ] )
-    action [, ... ] [ RESTRICT ]
+    action [ ... ] [ RESTRICT ]
 ALTER FUNCTION name ( [ [ argmode ] [ argname ] argtype [, ...] ] )
     RENAME TO new_name
 ALTER FUNCTION name ( [ [ argmode ] [ argname ] argtype [, ...] ] )
@@ -36,8 +36,10 @@ where action is one of:
     [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
     COST execution_cost
     ROWS result_rows
-    SET parameter { TO | = } { value | DEFAULT }
-    RESET parameter
+    SET configuration_parameter { TO | = } { value | DEFAULT }
+    SET configuration_parameter FROM CURRENT
+    RESET configuration_parameter
+    RESET ALL
 
  
   
@@ -215,7 +217,7 @@ where action is one of:
    
 
      
-      parameter
+      configuration_parameter
       value
       
        
@@ -226,6 +228,8 @@ where action is one of:
         setting is removed, so that the function executes with the value
         present in its environment.  Use RESET
         ALL to clear all function-local settings.
+        SET FROM CURRENT saves the session's current value of
+        the parameter as the value to be applied when the function is entered.
        
 
        
index ce28f2ad59792904977ce8a6968e9077386eab6f..a471095e4963d88b1d9379b8f751582ee9e2531b 100644 (file)
@@ -1,5 +1,5 @@
 
 
@@ -37,7 +37,9 @@ where option can be:
 ALTER ROLE name RENAME TO newname
 
 ALTER ROLE name SET configuration_parameter { TO | = } { value | DEFAULT }
+ALTER ROLE name SET configuration_parameter FROM CURRENT
 ALTER ROLE name RESET configuration_parameter
+ALTER ROLE name RESET ALL
 
  
 
@@ -77,7 +79,7 @@ ALTER ROLE name RESET 
   
 
   
-   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 postgresql.conf
@@ -155,6 +157,8 @@ ALTER ROLE name RESET 
         role-specific variable setting is removed, so the role will
         inherit the system-wide default setting in new sessions.  Use
         RESET ALL to clear all role-specific settings.
+        SET FROM CURRENT saves the session's current value of
+        the parameter as the role-specific value.
        
 
        
index 8f41a35e7aa237ae4f8250607b0022ce24813454..f989651d6fe02e85b678d47e2bb649b1475df5a5 100644 (file)
@@ -1,5 +1,5 @@
 
 
@@ -37,7 +37,9 @@ where option can be:
 ALTER USER name RENAME TO newname
 
 ALTER USER name SET configuration_parameter { TO | = } { value | DEFAULT }
+ALTER USER name SET configuration_parameter FROM CURRENT
 ALTER USER name RESET configuration_parameter
+ALTER USER name RESET ALL
 
  
 
index 7aff876d37d203bffe6cf5520816179e382fbee4..b0cfe84db1c67ed14735b56ca270f02b2c997789 100644 (file)
@@ -1,5 +1,5 @@
 
 
 
@@ -28,7 +28,7 @@ CREATE [ OR REPLACE ] FUNCTION
     | [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
     | COST execution_cost
     | ROWS result_rows
-    | SET parameter { TO | = } { value | DEFAULT }
+    | SET configuration_parameter { TO value | = value | FROM CURRENT }
     | AS 'definition'
     | AS 'obj_file', 'link_symbol'
   } ...
@@ -324,13 +324,15 @@ CREATE [ OR REPLACE ] FUNCTION
     
 
     
-     parameter
+     configuration_parameter
      value
      
       
        The 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.
+       SET FROM CURRENT saves the session's current value of
+       the parameter as the value to be applied when the function is entered.
       
 
       
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   insert_rest
 
-%type  set_rest
+%type  set_rest SetResetClause
 
 %type    TableElement ConstraintElem TableFuncElement
 %type    columnDef
@@ -330,7 +330,7 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
 %type    Iconst SignedIconst
 %type         Sconst comment_text
 %type         RoleId opt_granted_by opt_boolean ColId_or_Sconst
-%type    var_list var_list_or_default
+%type    var_list
 %type         ColId ColLabel var_name type_function_name param_name
 %type    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 .
  *
  * 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 .
  *
- * $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);