99 *
1010 *
1111 * IDENTIFICATION
12- * $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.61 2002/03/29 19:06:07 tgl Exp $
12+ * $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.62 2002/04/21 19:12:46 thomas Exp $
1313 *
1414 *-------------------------------------------------------------------------
1515 */
@@ -223,9 +223,9 @@ parse_datestyle_internal(char *value)
223223{
224224DateStyle = USE_GERMAN_DATES ;
225225dcnt ++ ;
226- EuroDates = TRUE;
227226if ((ecnt > 0 )&& (!EuroDates ))
228227ecnt ++ ;
228+ EuroDates = TRUE;
229229}
230230else if (!strncasecmp (tok ,"EURO" ,4 ))
231231{
@@ -247,28 +247,63 @@ parse_datestyle_internal(char *value)
247247ecnt ++ ;
248248}
249249else
250- elog (ERROR ,"Bad value for date style (%s)" ,tok );
250+ elog (ERROR ,"SET DATESTYLE bad value (%s)" ,tok );
251251}
252252
253253if (dcnt > 1 || ecnt > 1 )
254- elog (WARNING ,"Conflicting settings for date " );
254+ elog (WARNING ,"SET DATESTYLE specified conflicting settings " );
255255
256256return TRUE;
257257}
258258
259259static bool
260260parse_datestyle (List * args )
261261{
262+ int rstat ;
263+ List * arg ;
262264char * value ;
263265
264266if (args == NULL )
265267return reset_datestyle ();
266268
267- Assert (IsA (lfirst ( args ), A_Const ));
269+ Assert (IsA (args , List ));
268270
269- value = ((A_Const * )lfirst (args ))-> val .val .str ;
271+ foreach (arg ,args )
272+ {
273+ Node * n ;
274+
275+ Assert (IsA (arg ,List ));
276+ n = lfirst (arg );
277+
278+ /* Require untyped, stringy constants for arguments. */
279+ if (IsA (n ,A_Const ))
280+ {
281+ A_Const * p = (A_Const * )n ;
282+ TypeName * type = p -> typename ;
283+ Value * v = & (p -> val );
284+
285+ if (type != NULL )
286+ {
287+ Value * s ;
288+ Assert (IsA (type -> names ,List ));
289+ s = (Value * )lfirst (type -> names );
290+ elog (ERROR ,"SET DATESTYLE does not allow input of type %s" ,s -> val .str );
291+ }
292+
293+ value = v -> val .str ;
294+ }
295+ else
296+ {
297+ elog (ERROR ,"SET DATESTYLE argument is not valid" );
298+ }
299+
300+ rstat = parse_datestyle_internal (value );
301+
302+ if (rstat != TRUE)
303+ return rstat ;
304+ }
270305
271- return parse_datestyle_internal ( value ) ;
306+ return rstat ;
272307}
273308
274309static bool
@@ -554,8 +589,12 @@ parse_XactIsoLevel(List *args)
554589if (args == NULL )
555590return reset_XactIsoLevel ();
556591
592+ Assert (IsA (args ,List ));
557593Assert (IsA (lfirst (args ),A_Const ));
594+ /* Should only get one argument from the parser */
595+ Assert (lnext (args )== NIL );
558596
597+ Assert (((A_Const * )lfirst (args ))-> val .type = T_String );
559598value = ((A_Const * )lfirst (args ))-> val .val .str ;
560599
561600if (SerializableSnapshot != NULL )
@@ -607,17 +646,33 @@ reset_XactIsoLevel(void)
607646static bool
608647parse_random_seed (List * args )
609648{
610- char * value ;
649+ A_Const * p ;
611650double seed = 0 ;
612651
613652if (args == NULL )
614653return reset_random_seed ();
615654
616- Assert (IsA (lfirst (args ),A_Const ));
655+ Assert (IsA (args ,List ));
656+ /* Should only get one argument from the parser */
657+ Assert (lnext (args )== NIL );
617658
618- value = ((A_Const * )lfirst (args ))-> val .val .str ;
659+ p = lfirst (args );
660+ Assert (IsA (p ,A_Const ));
661+
662+ if ((p -> val .type == T_String )
663+ || (p -> val .type == T_Float ))
664+ {
665+ seed = DatumGetFloat8 (DirectFunctionCall1 (float8in ,CStringGetDatum (p -> val .val .str )));
666+ }
667+ else if (p -> val .type == T_Integer )
668+ {
669+ seed = p -> val .val .ival ;
670+ }
671+ else
672+ {
673+ elog (ERROR ,"SET SEED internal coding error" );
674+ }
619675
620- sscanf (value ,"%lf" ,& seed );
621676DirectFunctionCall1 (setseed ,Float8GetDatum (seed ));
622677
623678return (TRUE);
@@ -662,6 +717,10 @@ parse_client_encoding(List *args)
662717return reset_client_encoding ();
663718
664719Assert (IsA (lfirst (args ),A_Const ));
720+ if (((A_Const * )lfirst (args ))-> val .type != T_String )
721+ {
722+ elog (ERROR ,"SET CLIENT_ENCODING requires an encoding name" );
723+ }
665724
666725value = ((A_Const * )lfirst (args ))-> val .val .str ;
667726
@@ -778,12 +837,36 @@ SetPGVariable(const char *name, List *args)
778837 */
779838char * value ;
780839
781- value = ((args != NULL ) ? ((A_Const * )lfirst (args ))-> val .val .str :NULL );
840+ if (args != NULL )
841+ {
842+ A_Const * n ;
843+
844+ /* Ensure one argument only... */
845+ if (lnext (args )!= NIL )
846+ elog (ERROR ,"SET takes only one argument for this parameter" );
847+ n = (A_Const * )lfirst (args );
848+ /* If this is a T_Integer, then we should convert back to a string
849+ * but for now we just reject the parameter.
850+ */
851+ if ((n -> val .type != T_String )
852+ && (n -> val .type != T_Float ))
853+ elog (ERROR ,"SET requires a string argument for this parameter"
854+ "\n\tInternal coding error: report to thomas@fourpalms.org" );
855+
856+ value = n -> val .val .str ;
857+ }
858+ else
859+ {
860+ value = NULL ;
861+ }
782862
783863if (strcasecmp (name ,"session_authorization" )== 0 )
784864SetSessionAuthorization (value );
785865else
786- SetConfigOption (name ,value ,superuser () ?PGC_SUSET :PGC_USERSET ,PGC_S_SESSION );
866+ SetConfigOption (name ,
867+ value ,
868+ (superuser () ?PGC_SUSET :PGC_USERSET ),
869+ PGC_S_SESSION );
787870}
788871return ;
789872}