]> granicus.if.org Git - postgresql/commitdiff
Allow more choices for style of value in various SET commands. Formerly,
authorThomas G. Lockhart <lockhart@fourpalms.org>
Sun, 21 Apr 2002 19:12:46 +0000 (19:12 +0000)
committerThomas G. Lockhart <lockhart@fourpalms.org>
Sun, 21 Apr 2002 19:12:46 +0000 (19:12 +0000)
 most required a stringy syntax in the parser; now integers and floats
 can (or should) be handled. There is at least one cheesy error message
 mentioning sending mail to me if there are problems; should be changed
 prior to release.
Allow lists of values from the parser in more cases. If multiple arguments
 were not allowed previously, they probably are not allowed now, but at
 least the data structures being passed around are more consistant across
 more cases.

src/backend/commands/variable.c

index 1794d2bda735b4e1c6851b018ce66cec4cbe170b..cb573d075c19439e982c6354cff5396fb324af4f 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.61 2002/03/29 19:06:07 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.62 2002/04/21 19:12:46 thomas Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -223,9 +223,9 @@ parse_datestyle_internal(char *value)
                {
                        DateStyle = USE_GERMAN_DATES;
                        dcnt++;
-                       EuroDates = TRUE;
                        if ((ecnt > 0) && (!EuroDates))
                                ecnt++;
+                       EuroDates = TRUE;
                }
                else if (!strncasecmp(tok, "EURO", 4))
                {
@@ -247,11 +247,11 @@ parse_datestyle_internal(char *value)
                        ecnt++;
                }
                else
-                       elog(ERROR, "Bad value for date style (%s)", tok);
+                       elog(ERROR, "SET DATESTYLE bad value (%s)", tok);
        }
 
        if (dcnt > 1 || ecnt > 1)
-               elog(WARNING, "Conflicting settings for date");
+               elog(WARNING, "SET DATESTYLE specified conflicting settings");
 
        return TRUE;
 }
@@ -259,16 +259,51 @@ parse_datestyle_internal(char *value)
 static bool
 parse_datestyle(List *args)
 {
+       int                     rstat;
+       List       *arg;
        char       *value;
 
        if (args == NULL)
                return reset_datestyle();
 
-       Assert(IsA(lfirst(args), A_Const));
+       Assert(IsA(args, List));
 
-       value = ((A_Const *) lfirst(args))->val.val.str;
+       foreach(arg, args)
+       {
+               Node       *n;
+
+               Assert(IsA(arg, List));
+               n = lfirst(arg);
+
+               /* Require untyped, stringy constants for arguments. */
+               if (IsA(n, A_Const))
+               {
+                       A_Const    *p = (A_Const *) n;
+                       TypeName   *type = p->typename;
+                       Value      *v = &(p->val);
+
+                       if (type != NULL)
+                       {
+                               Value *s;
+                               Assert(IsA(type->names, List));
+                               s = (Value *) lfirst(type->names);
+                               elog(ERROR, "SET DATESTYLE does not allow input of type %s", s->val.str);
+                       }
+
+                       value = v->val.str;
+               }
+               else
+               {
+                       elog(ERROR, "SET DATESTYLE argument is not valid");
+               }
+
+               rstat = parse_datestyle_internal(value);
+
+               if (rstat != TRUE)
+                       return rstat;
+       }
 
-       return parse_datestyle_internal(value);
+       return rstat;
 }
 
 static bool
@@ -554,8 +589,12 @@ parse_XactIsoLevel(List *args)
        if (args == NULL)
                return reset_XactIsoLevel();
 
+       Assert(IsA(args, List));
        Assert(IsA(lfirst(args), A_Const));
+       /* Should only get one argument from the parser */
+       Assert(lnext(args) == NIL);
 
+       Assert(((A_Const *) lfirst(args))->val.type = T_String);
        value = ((A_Const *) lfirst(args))->val.val.str;
 
        if (SerializableSnapshot != NULL)
@@ -607,17 +646,33 @@ reset_XactIsoLevel(void)
 static bool
 parse_random_seed(List *args)
 {
-       char       *value;
+       A_Const    *p;
        double          seed = 0;
 
        if (args == NULL)
                return reset_random_seed();
 
-       Assert(IsA(lfirst(args), A_Const));
+       Assert(IsA(args, List));
+       /* Should only get one argument from the parser */
+       Assert(lnext(args) == NIL);
 
-       value = ((A_Const *) lfirst(args))->val.val.str;
+       p = lfirst(args);
+       Assert(IsA(p, A_Const));
+
+       if ((p->val.type == T_String)
+               || (p->val.type == T_Float))
+       {
+               seed = DatumGetFloat8(DirectFunctionCall1(float8in, CStringGetDatum(p->val.val.str)));
+       }
+       else if (p->val.type == T_Integer)
+       {
+               seed = p->val.val.ival;
+       }
+       else
+       {
+               elog(ERROR, "SET SEED internal coding error");
+       }
 
-       sscanf(value, "%lf", &seed);
        DirectFunctionCall1(setseed, Float8GetDatum(seed));
 
        return (TRUE);
@@ -662,6 +717,10 @@ parse_client_encoding(List *args)
                return reset_client_encoding();
 
        Assert(IsA(lfirst(args), A_Const));
+       if (((A_Const *) lfirst(args))->val.type != T_String)
+       {
+               elog(ERROR, "SET CLIENT_ENCODING requires an encoding name");
+       }
 
        value = ((A_Const *) lfirst(args))->val.val.str;
 
@@ -778,12 +837,36 @@ SetPGVariable(const char *name, List *args)
                 */
                char       *value;
 
-               value = ((args != NULL) ? ((A_Const *) lfirst(args))->val.val.str : NULL);
+               if (args != NULL)
+               {
+                       A_Const *n;
+
+                       /* Ensure one argument only... */
+                       if (lnext(args) != NIL)
+                               elog(ERROR, "SET takes only one argument for this parameter");
+                       n = (A_Const *) lfirst(args);
+                       /* If this is a T_Integer, then we should convert back to a string
+                        * but for now we just reject the parameter.
+                        */
+                       if ((n->val.type != T_String)
+                               && (n->val.type != T_Float))
+                               elog(ERROR, "SET requires a string argument for this parameter"
+                                        "\n\tInternal coding error: report to thomas@fourpalms.org");
+
+                       value = n->val.val.str;
+               }
+               else
+               {
+                       value = NULL;
+               }
 
                if (strcasecmp(name, "session_authorization") == 0)
                        SetSessionAuthorization(value);
                else
-                       SetConfigOption(name, value, superuser() ? PGC_SUSET : PGC_USERSET, PGC_S_SESSION);
+                       SetConfigOption(name,
+                                                       value,
+                                                       (superuser() ? PGC_SUSET : PGC_USERSET),
+                                                       PGC_S_SESSION);
        }
        return;
 }