OSDN Git Service

pg_type has a typnamespace column; system now supports creating types
[pg-rex/syncrep.git] / src / backend / commands / variable.c
1 /*-------------------------------------------------------------------------
2  *
3  * variable.c
4  *              Routines for handling of 'SET var TO',
5  *              'SHOW var' and 'RESET var' statements.
6  *
7  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  *
11  * IDENTIFICATION
12  *        $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.61 2002/03/29 19:06:07 tgl Exp $
13  *
14  *-------------------------------------------------------------------------
15  */
16
17 #include "postgres.h"
18
19 #include <ctype.h>
20 #include <time.h>
21
22 #include "access/xact.h"
23 #include "catalog/pg_shadow.h"
24 #include "catalog/pg_type.h"
25 #include "commands/variable.h"
26 #include "miscadmin.h"
27 #include "optimizer/cost.h"
28 #include "optimizer/paths.h"
29 #include "parser/parse_type.h"
30 #include "utils/builtins.h"
31 #include "utils/date.h"
32 #include "utils/guc.h"
33 #include "utils/tqual.h"
34
35 #ifdef MULTIBYTE
36 #include "mb/pg_wchar.h"
37 #else
38 /* Grand unified hard-coded badness */
39 #define pg_get_client_encoding_name()  "SQL_ASCII"
40 #define GetDatabaseEncodingName() "SQL_ASCII"
41 #endif
42
43
44 static bool show_datestyle(void);
45 static bool reset_datestyle(void);
46 static bool parse_datestyle(List *);
47 static bool show_timezone(void);
48 static bool reset_timezone(void);
49 static bool parse_timezone(List *);
50
51 static bool show_XactIsoLevel(void);
52 static bool reset_XactIsoLevel(void);
53 static bool parse_XactIsoLevel(List *);
54 static bool show_random_seed(void);
55 static bool reset_random_seed(void);
56 static bool parse_random_seed(List *);
57
58 static bool show_client_encoding(void);
59 static bool reset_client_encoding(void);
60 static bool parse_client_encoding(List *);
61 static bool show_server_encoding(void);
62 static bool reset_server_encoding(void);
63 static bool parse_server_encoding(List *);
64
65
66 /*
67  * get_token
68  *              Obtain the next item in a comma-separated list of items,
69  *              where each item can be either "word" or "word=word".
70  *              The "word=word" form is only accepted if 'val' is not NULL.
71  *              Words are any sequences not containing whitespace, ',', or '='.
72  *              Whitespace can appear between the words and punctuation.
73  *
74  * 'tok': receives a pointer to first word of item, or NULL if none.
75  * 'val': if not NULL, receives a pointer to second word, or NULL if none.
76  * 'str': start of input string.
77  *
78  * Returns NULL if input string contained no more words, else pointer
79  * to just past this item, which can be used as 'str' for next call.
80  * (If this is the last item, returned pointer will point at a null char,
81  * so caller can alternatively check for that instead of calling again.)
82  *
83  * NB: input string is destructively modified by placing null characters
84  * at ends of words!
85  *
86  * A former version of this code avoided modifying the input string by
87  * returning palloc'd copies of the words.  However, we want to use this
88  * code early in backend startup to parse the PGDATESTYLE environment var,
89  * and palloc/pfree aren't initialized at that point.  Cleanest answer
90  * seems to be to palloc in SetPGVariable() so that we can treat the string
91  * as modifiable here.
92  */
93 static char *
94 get_token(char **tok, char **val, char *str)
95 {
96         char            ch;
97
98         *tok = NULL;
99         if (val != NULL)
100                 *val = NULL;
101
102         if (!str || *str == '\0')
103                 return NULL;
104
105         /* skip leading white space */
106         while (isspace((unsigned char) *str))
107                 str++;
108
109         /* end of string? then return NULL */
110         if (*str == '\0')
111                 return NULL;
112
113         if (*str == ',' || *str == '=')
114                 elog(ERROR, "Syntax error near \"%s\": empty setting", str);
115
116         /* OK, at beginning of non-empty item */
117         *tok = str;
118
119         /* Advance to end of word */
120         while (*str && !isspace((unsigned char) *str) &&
121                    *str != ',' && *str != '=')
122                 str++;
123
124         /* Terminate word string for caller */
125         ch = *str;
126         *str = '\0';
127
128         /* Skip any whitespace */
129         while (isspace((unsigned char) ch))
130                 ch = *(++str);
131
132         /* end of string? */
133         if (ch == '\0')
134                 return str;
135         /* delimiter? */
136         if (ch == ',')
137                 return ++str;
138
139         /* Had better be '=', and caller must be expecting it */
140         if (val == NULL || ch != '=')
141                 elog(ERROR, "Syntax error near \"%s\"", str);
142
143         /* '=': get the value */
144         str++;
145
146         /* skip whitespace after '=' */
147         while (isspace((unsigned char) *str))
148                 str++;
149
150         if (*str == ',' || *str == '\0')
151                 elog(ERROR, "Syntax error near \"=%s\"", str);
152
153         /* OK, at beginning of non-empty value */
154         *val = str;
155
156         /* Advance to end of word */
157         while (*str && !isspace((unsigned char) *str) && *str != ',')
158                 str++;
159
160         /* Terminate word string for caller */
161         ch = *str;
162         *str = '\0';
163
164         /* Skip any whitespace */
165         while (isspace((unsigned char) ch))
166                 ch = *(++str);
167
168         /* end of string? */
169         if (ch == '\0')
170                 return str;
171         /* delimiter? */
172         if (ch == ',')
173                 return ++str;
174
175         elog(ERROR, "Syntax error near \"%s\"", str);
176
177         return str;
178 }
179
180
181 /*
182  * DATESTYLE
183  *
184  * NOTE: set_default_datestyle() is called during backend startup to check
185  * if the PGDATESTYLE environment variable is set.      We want the env var
186  * to determine the value that "RESET DateStyle" will reset to!
187  */
188
189 /* These get initialized from the "master" values in init/globals.c */
190 static int      DefaultDateStyle;
191 static bool DefaultEuroDates;
192
193 static bool
194 parse_datestyle_internal(char *value)
195 {
196         char       *tok;
197         int                     dcnt = 0,
198                                 ecnt = 0;
199
200         if (value == NULL)
201                 return reset_datestyle();
202
203         while ((value = get_token(&tok, NULL, value)) != 0)
204         {
205                 /* Ugh. Somebody ought to write a table driven version -- mjl */
206
207                 if (!strcasecmp(tok, "ISO"))
208                 {
209                         DateStyle = USE_ISO_DATES;
210                         dcnt++;
211                 }
212                 else if (!strcasecmp(tok, "SQL"))
213                 {
214                         DateStyle = USE_SQL_DATES;
215                         dcnt++;
216                 }
217                 else if (!strncasecmp(tok, "POSTGRESQL", 8))
218                 {
219                         DateStyle = USE_POSTGRES_DATES;
220                         dcnt++;
221                 }
222                 else if (!strcasecmp(tok, "GERMAN"))
223                 {
224                         DateStyle = USE_GERMAN_DATES;
225                         dcnt++;
226                         EuroDates = TRUE;
227                         if ((ecnt > 0) && (!EuroDates))
228                                 ecnt++;
229                 }
230                 else if (!strncasecmp(tok, "EURO", 4))
231                 {
232                         EuroDates = TRUE;
233                         if ((dcnt <= 0) || (DateStyle != USE_GERMAN_DATES))
234                                 ecnt++;
235                 }
236                 else if ((!strcasecmp(tok, "US"))
237                                  || (!strncasecmp(tok, "NONEURO", 7)))
238                 {
239                         EuroDates = FALSE;
240                         if ((dcnt <= 0) || (DateStyle == USE_GERMAN_DATES))
241                                 ecnt++;
242                 }
243                 else if (!strcasecmp(tok, "DEFAULT"))
244                 {
245                         DateStyle = DefaultDateStyle;
246                         EuroDates = DefaultEuroDates;
247                         ecnt++;
248                 }
249                 else
250                         elog(ERROR, "Bad value for date style (%s)", tok);
251         }
252
253         if (dcnt > 1 || ecnt > 1)
254                 elog(WARNING, "Conflicting settings for date");
255
256         return TRUE;
257 }
258
259 static bool
260 parse_datestyle(List *args)
261 {
262         char       *value;
263
264         if (args == NULL)
265                 return reset_datestyle();
266
267         Assert(IsA(lfirst(args), A_Const));
268
269         value = ((A_Const *) lfirst(args))->val.val.str;
270
271         return parse_datestyle_internal(value);
272 }
273
274 static bool
275 show_datestyle(void)
276 {
277         char            buf[64];
278
279         strcpy(buf, "DateStyle is ");
280         switch (DateStyle)
281         {
282                 case USE_ISO_DATES:
283                         strcat(buf, "ISO");
284                         break;
285                 case USE_SQL_DATES:
286                         strcat(buf, "SQL");
287                         break;
288                 case USE_GERMAN_DATES:
289                         strcat(buf, "German");
290                         break;
291                 default:
292                         strcat(buf, "Postgres");
293                         break;
294         };
295         strcat(buf, " with ");
296         strcat(buf, ((EuroDates) ? "European" : "US (NonEuropean)"));
297         strcat(buf, " conventions");
298
299         elog(INFO, buf, NULL);
300
301         return TRUE;
302 }
303
304 static bool
305 reset_datestyle(void)
306 {
307         DateStyle = DefaultDateStyle;
308         EuroDates = DefaultEuroDates;
309
310         return TRUE;
311 }
312
313 void
314 set_default_datestyle(void)
315 {
316         char       *DBDate;
317
318         /*
319          * Initialize from compile-time defaults in init/globals.c. NB: this
320          * is a necessary step; consider PGDATESTYLE="DEFAULT".
321          */
322         DefaultDateStyle = DateStyle;
323         DefaultEuroDates = EuroDates;
324
325         /* If the environment var is set, override compiled-in values */
326         DBDate = getenv("PGDATESTYLE");
327         if (DBDate == NULL)
328                 return;
329
330         /*
331          * Make a modifiable copy --- overwriting the env var doesn't seem
332          * like a good idea, even though we currently won't look at it again.
333          * Note that we cannot use palloc at this early stage of
334          * initialization.
335          */
336         DBDate = strdup(DBDate);
337
338         /*
339          * Parse desired setting into DateStyle/EuroDates Use
340          * parse_datestyle_internal() to avoid any palloc() issues per above -
341          * thomas 2001-10-15
342          */
343         parse_datestyle_internal(DBDate);
344
345         free(DBDate);
346
347         /* And make it the default for future RESETs */
348         DefaultDateStyle = DateStyle;
349         DefaultEuroDates = EuroDates;
350 }
351
352
353 /* Timezone support
354  * Working storage for strings is allocated with an arbitrary size of 64 bytes.
355  */
356
357 static char *defaultTZ = NULL;
358 static char TZvalue[64];
359 static char tzbuf[64];
360
361 /*
362  *
363  * TIMEZONE
364  *
365  */
366 /* parse_timezone()
367  * Handle SET TIME ZONE...
368  * Try to save existing TZ environment variable for later use in RESET TIME ZONE.
369  * Accept an explicit interval per SQL9x, though this is less useful than a full time zone.
370  * - thomas 2001-10-11
371  */
372 static bool
373 parse_timezone(List *args)
374 {
375         List       *arg;
376         TypeName   *type;
377
378         if (args == NULL)
379                 return reset_timezone();
380
381         Assert(IsA(args, List));
382
383         foreach(arg, args)
384         {
385                 A_Const    *p;
386
387                 Assert(IsA(arg, List));
388                 p = lfirst(arg);
389                 Assert(IsA(p, A_Const));
390
391                 type = p->typename;
392                 if (type != NULL)
393                 {
394                         Oid             typeOid = typenameTypeId(type);
395
396                         if (typeOid == INTERVALOID)
397                         {
398                                 Interval   *interval;
399
400                                 interval = DatumGetIntervalP(DirectFunctionCall3(interval_in,
401                                                                                                                                  CStringGetDatum(p->val.val.str),
402                                                                                                                                  ObjectIdGetDatum(InvalidOid),
403                                                                                                                                  Int32GetDatum(type->typmod)));
404                                 if (interval->month != 0)
405                                         elog(ERROR, "SET TIME ZONE illegal INTERVAL; month not allowed");
406                                 CTimeZone = interval->time;
407                         }
408                         else if (typeOid == FLOAT8OID)
409                         {
410                                 float8          time;
411
412                                 time = DatumGetFloat8(DirectFunctionCall1(float8in, CStringGetDatum(p->val.val.str)));
413                                 CTimeZone = time * 3600;
414                         }
415
416                         /*
417                          * We do not actually generate an integer constant in gram.y
418                          * so this is not used...
419                          */
420                         else if (typeOid == INT4OID)
421                         {
422                                 int32           time;
423
424                                 time = p->val.val.ival;
425                                 CTimeZone = time * 3600;
426                         }
427                         else
428                         {
429                                 elog(ERROR, "Unable to process SET TIME ZONE command; internal coding error");
430                         }
431
432                         HasCTZSet = true;
433                 }
434                 else
435                 {
436                         char       *tok;
437                         char       *value;
438
439                         value = p->val.val.str;
440
441                         while ((value = get_token(&tok, NULL, value)) != 0)
442                         {
443                                 /* Not yet tried to save original value from environment? */
444                                 if (defaultTZ == NULL)
445                                 {
446                                         /* found something? then save it for later */
447                                         if ((defaultTZ = getenv("TZ")) != NULL)
448                                                 strcpy(TZvalue, defaultTZ);
449
450                                         /* found nothing so mark with an invalid pointer */
451                                         else
452                                                 defaultTZ = (char *) -1;
453                                 }
454
455                                 strcpy(tzbuf, "TZ=");
456                                 strcat(tzbuf, tok);
457                                 if (putenv(tzbuf) != 0)
458                                         elog(ERROR, "Unable to set TZ environment variable to %s", tok);
459
460                                 tzset();
461                         }
462
463                         HasCTZSet = false;
464                 }
465         }
466
467         return TRUE;
468 }       /* parse_timezone() */
469
470 static bool
471 show_timezone(void)
472 {
473         char       *tzn;
474
475         if (HasCTZSet)
476         {
477                 Interval        interval;
478
479                 interval.month = 0;
480                 interval.time = CTimeZone;
481
482                 tzn = DatumGetCString(DirectFunctionCall1(interval_out, IntervalPGetDatum(&interval)));
483         }
484         else
485                 tzn = getenv("TZ");
486
487         if (tzn != NULL)
488                 elog(INFO, "Time zone is '%s'", tzn);
489         else
490                 elog(INFO, "Time zone is unset");
491
492         return TRUE;
493 }       /* show_timezone() */
494
495 /* reset_timezone()
496  * Set TZ environment variable to original value.
497  * Note that if TZ was originally not set, TZ should be cleared.
498  * unsetenv() works fine, but is BSD, not POSIX, and is not available
499  * under Solaris, among others. Apparently putenv() called as below
500  * clears the process-specific environment variables.
501  * Other reasonable arguments to putenv() (e.g. "TZ=", "TZ", "") result
502  * in a core dump (under Linux anyway).
503  * - thomas 1998-01-26
504  */
505 static bool
506 reset_timezone(void)
507 {
508         if (HasCTZSet)
509                 HasCTZSet = false;
510
511         /* no time zone has been set in this session? */
512         else if (defaultTZ == NULL)
513         {
514         }
515
516         /* time zone was set and original explicit time zone available? */
517         else if (defaultTZ != (char *) -1)
518         {
519                 strcpy(tzbuf, "TZ=");
520                 strcat(tzbuf, TZvalue);
521                 if (putenv(tzbuf) != 0)
522                         elog(ERROR, "Unable to set TZ environment variable to %s", TZvalue);
523                 tzset();
524         }
525
526         /*
527          * otherwise, time zone was set but no original explicit time zone
528          * available
529          */
530         else
531         {
532                 strcpy(tzbuf, "=");
533                 if (putenv(tzbuf) != 0)
534                         elog(ERROR, "Unable to clear TZ environment variable");
535                 tzset();
536         }
537
538         return TRUE;
539 }       /* reset_timezone() */
540
541
542
543 /*
544  *
545  * SET TRANSACTION
546  *
547  */
548
549 static bool
550 parse_XactIsoLevel(List *args)
551 {
552         char       *value;
553
554         if (args == NULL)
555                 return reset_XactIsoLevel();
556
557         Assert(IsA(lfirst(args), A_Const));
558
559         value = ((A_Const *) lfirst(args))->val.val.str;
560
561         if (SerializableSnapshot != NULL)
562         {
563                 elog(ERROR, "SET TRANSACTION ISOLATION LEVEL must be called before any query");
564                 return TRUE;
565         }
566
567         if (strcmp(value, "serializable") == 0)
568                 XactIsoLevel = XACT_SERIALIZABLE;
569         else if (strcmp(value, "read committed") == 0)
570                 XactIsoLevel = XACT_READ_COMMITTED;
571         else
572                 elog(ERROR, "invalid transaction isolation level: %s", value);
573
574         return TRUE;
575 }
576
577 static bool
578 show_XactIsoLevel(void)
579 {
580
581         if (XactIsoLevel == XACT_SERIALIZABLE)
582                 elog(INFO, "TRANSACTION ISOLATION LEVEL is SERIALIZABLE");
583         else
584                 elog(INFO, "TRANSACTION ISOLATION LEVEL is READ COMMITTED");
585         return TRUE;
586 }
587
588 static bool
589 reset_XactIsoLevel(void)
590 {
591
592         if (SerializableSnapshot != NULL)
593         {
594                 elog(ERROR, "SET TRANSACTION ISOLATION LEVEL must be called before any query");
595                 return TRUE;
596         }
597
598         XactIsoLevel = DefaultXactIsoLevel;
599
600         return TRUE;
601 }
602
603
604 /*
605  * Random number seed
606  */
607 static bool
608 parse_random_seed(List *args)
609 {
610         char       *value;
611         double          seed = 0;
612
613         if (args == NULL)
614                 return reset_random_seed();
615
616         Assert(IsA(lfirst(args), A_Const));
617
618         value = ((A_Const *) lfirst(args))->val.val.str;
619
620         sscanf(value, "%lf", &seed);
621         DirectFunctionCall1(setseed, Float8GetDatum(seed));
622
623         return (TRUE);
624 }
625
626 static bool
627 show_random_seed(void)
628 {
629         elog(INFO, "Seed for random number generator is unavailable");
630         return (TRUE);
631 }
632
633 static bool
634 reset_random_seed(void)
635 {
636         double          seed = 0.5;
637
638         DirectFunctionCall1(setseed, Float8GetDatum(seed));
639         return (TRUE);
640 }
641
642
643 /*
644  * MULTIBYTE-related functions
645  *
646  * If MULTIBYTE support was not compiled, we still allow these variables
647  * to exist, but you can't set them to anything but "SQL_ASCII".  This
648  * minimizes interoperability problems between non-MB servers and MB-enabled
649  * clients.
650  */
651
652 static bool
653 parse_client_encoding(List *args)
654 {
655         char       *value;
656
657 #ifdef MULTIBYTE
658         int                     encoding;
659 #endif
660
661         if (args == NULL)
662                 return reset_client_encoding();
663
664         Assert(IsA(lfirst(args), A_Const));
665
666         value = ((A_Const *) lfirst(args))->val.val.str;
667
668 #ifdef MULTIBYTE
669         encoding = pg_valid_client_encoding(value);
670         if (encoding < 0)
671         {
672                 if (value)
673                         elog(ERROR, "Client encoding '%s' is not supported", value);
674                 else
675                         elog(ERROR, "No client encoding is specified");
676         }
677         else
678         {
679                 if (pg_set_client_encoding(encoding) < 0)
680                 {
681                         elog(ERROR, "Conversion between %s and %s is not supported",
682                                  value, GetDatabaseEncodingName());
683                 }
684         }
685 #else
686         if (value &&
687                 strcasecmp(value, pg_get_client_encoding_name()) != 0)
688                 elog(ERROR, "Client encoding %s is not supported", value);
689 #endif
690         return TRUE;
691 }
692
693 static bool
694 show_client_encoding(void)
695 {
696         elog(INFO, "Current client encoding is '%s'",
697                  pg_get_client_encoding_name());
698         return TRUE;
699 }
700
701 static bool
702 reset_client_encoding(void)
703 {
704 #ifdef MULTIBYTE
705         int                     encoding;
706         char       *env = getenv("PGCLIENTENCODING");
707
708         if (env)
709         {
710                 encoding = pg_char_to_encoding(env);
711                 if (encoding < 0)
712                         encoding = GetDatabaseEncoding();
713         }
714         else
715                 encoding = GetDatabaseEncoding();
716
717         pg_set_client_encoding(encoding);
718 #endif
719         return TRUE;
720 }
721
722 /* Called during MULTIBYTE backend startup ... */
723 void
724 set_default_client_encoding(void)
725 {
726         reset_client_encoding();
727 }
728
729
730 static bool
731 parse_server_encoding(List *args)
732 {
733         elog(INFO, "SET SERVER_ENCODING is not supported");
734         return TRUE;
735 }
736
737 static bool
738 show_server_encoding(void)
739 {
740         elog(INFO, "Current server encoding is '%s'", GetDatabaseEncodingName());
741         return TRUE;
742 }
743
744 static bool
745 reset_server_encoding(void)
746 {
747         elog(INFO, "RESET SERVER_ENCODING is not supported");
748         return TRUE;
749 }
750
751
752
753 /* SetPGVariable()
754  * Dispatcher for handling SET commands.
755  * Special cases ought to be removed and handled separately by TCOP
756  */
757 void
758 SetPGVariable(const char *name, List *args)
759 {
760         if (strcasecmp(name, "datestyle") == 0)
761                 parse_datestyle(args);
762         else if (strcasecmp(name, "timezone") == 0)
763                 parse_timezone(args);
764         else if (strcasecmp(name, "XactIsoLevel") == 0)
765                 parse_XactIsoLevel(args);
766         else if (strcasecmp(name, "client_encoding") == 0)
767                 parse_client_encoding(args);
768         else if (strcasecmp(name, "server_encoding") == 0)
769                 parse_server_encoding(args);
770         else if (strcasecmp(name, "seed") == 0)
771                 parse_random_seed(args);
772         else
773         {
774                 /*
775                  * For routines defined somewhere else, go ahead and extract the
776                  * string argument to match the original interface definition.
777                  * Later, we can change this code too...
778                  */
779                 char       *value;
780
781                 value = ((args != NULL) ? ((A_Const *) lfirst(args))->val.val.str : NULL);
782
783                 if (strcasecmp(name, "session_authorization") == 0)
784                         SetSessionAuthorization(value);
785                 else
786                         SetConfigOption(name, value, superuser() ? PGC_SUSET : PGC_USERSET, PGC_S_SESSION);
787         }
788         return;
789 }
790
791 void
792 GetPGVariable(const char *name)
793 {
794         if (strcasecmp(name, "datestyle") == 0)
795                 show_datestyle();
796         else if (strcasecmp(name, "timezone") == 0)
797                 show_timezone();
798         else if (strcasecmp(name, "XactIsoLevel") == 0)
799                 show_XactIsoLevel();
800         else if (strcasecmp(name, "client_encoding") == 0)
801                 show_client_encoding();
802         else if (strcasecmp(name, "server_encoding") == 0)
803                 show_server_encoding();
804         else if (strcasecmp(name, "seed") == 0)
805                 show_random_seed();
806         else if (strcasecmp(name, "all") == 0)
807         {
808                 ShowAllGUCConfig();
809                 show_datestyle();
810                 show_timezone();
811                 show_XactIsoLevel();
812                 show_client_encoding();
813                 show_server_encoding();
814                 show_random_seed();
815         }
816         else
817         {
818                 const char *val = GetConfigOption(name);
819
820                 elog(INFO, "%s is %s", name, val);
821         }
822 }
823
824 void
825 ResetPGVariable(const char *name)
826 {
827         if (strcasecmp(name, "datestyle") == 0)
828                 reset_datestyle();
829         else if (strcasecmp(name, "timezone") == 0)
830                 reset_timezone();
831         else if (strcasecmp(name, "XactIsoLevel") == 0)
832                 reset_XactIsoLevel();
833         else if (strcasecmp(name, "client_encoding") == 0)
834                 reset_client_encoding();
835         else if (strcasecmp(name, "server_encoding") == 0)
836                 reset_server_encoding();
837         else if (strcasecmp(name, "seed") == 0)
838                 reset_random_seed();
839         else if (strcasecmp(name, "all") == 0)
840         {
841                 reset_random_seed();
842                 /* reset_server_encoding(); */
843                 reset_client_encoding();
844                 reset_datestyle();
845                 reset_timezone();
846
847                 ResetAllOptions(false);
848         }
849         else
850                 SetConfigOption(name, NULL,
851                                                 superuser() ? PGC_SUSET : PGC_USERSET,
852                                                 PGC_S_SESSION);
853 }