LCOV - differential code coverage report
Current view: top level - src/backend/commands - variable.c (source / functions) Coverage Total Hit UNC LBC UIC UBC GBC GIC GNC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 67.6 % 420 284 97 22 65 35 20 137 75 52 62 140 3 3
Current Date: 2023-04-08 17:13:01 Functions: 94.4 % 36 34 2 18 16 2 33 1
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (120,180] days: 75.0 % 16 12 4 12
Legend: Lines: hit not hit (180,240] days: 86.3 % 73 63 10 63
(240..) days: 63.1 % 331 209 22 65 35 20 137 52 62 140
Function coverage date bins:
(180,240] days: 100.0 % 16 16 16
(240..) days: 45.0 % 40 18 2 18 1 19

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * variable.c
                                  4                 :  *      Routines for handling specialized SET variables.
                                  5                 :  *
                                  6                 :  *
                                  7                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
                                  8                 :  * Portions Copyright (c) 1994, Regents of the University of California
                                  9                 :  *
                                 10                 :  *
                                 11                 :  * IDENTIFICATION
                                 12                 :  *    src/backend/commands/variable.c
                                 13                 :  *
                                 14                 :  *-------------------------------------------------------------------------
                                 15                 :  */
                                 16                 : 
                                 17                 : #include "postgres.h"
                                 18                 : 
                                 19                 : #include <ctype.h>
                                 20                 : 
                                 21                 : #include "access/htup_details.h"
                                 22                 : #include "access/parallel.h"
                                 23                 : #include "access/xact.h"
                                 24                 : #include "access/xlog.h"
                                 25                 : #include "access/xlogprefetcher.h"
                                 26                 : #include "catalog/pg_authid.h"
                                 27                 : #include "common/string.h"
                                 28                 : #include "mb/pg_wchar.h"
                                 29                 : #include "miscadmin.h"
                                 30                 : #include "postmaster/postmaster.h"
                                 31                 : #include "postmaster/syslogger.h"
                                 32                 : #include "storage/bufmgr.h"
                                 33                 : #include "utils/acl.h"
                                 34                 : #include "utils/backend_status.h"
                                 35                 : #include "utils/builtins.h"
                                 36                 : #include "utils/datetime.h"
                                 37                 : #include "utils/guc_hooks.h"
                                 38                 : #include "utils/snapmgr.h"
                                 39                 : #include "utils/syscache.h"
                                 40                 : #include "utils/timestamp.h"
                                 41                 : #include "utils/tzparser.h"
                                 42                 : #include "utils/varlena.h"
                                 43                 : 
                                 44                 : /*
                                 45                 :  * DATESTYLE
                                 46                 :  */
                                 47                 : 
                                 48                 : /*
                                 49                 :  * check_datestyle: GUC check_hook for datestyle
                                 50                 :  */
                                 51                 : bool
 4385 tgl                        52 GIC       12373 : check_datestyle(char **newval, void **extra, GucSource source)
                                 53                 : {
 7632                            54           12373 :     int         newDateStyle = DateStyle;
 7194                            55           12373 :     int         newDateOrder = DateOrder;
 6513                            56           12373 :     bool        have_style = false;
                                 57           12373 :     bool        have_order = false;
 7632                            58           12373 :     bool        ok = true;
                                 59                 :     char       *rawstring;
 4385 tgl                        60 ECB             :     int        *myextra;
                                 61                 :     char       *result;
 7632                            62                 :     List       *elemlist;
 6892 neilc                      63                 :     ListCell   *l;
 9424 lockhart                   64                 : 
 7632 tgl                        65                 :     /* Need a modifiable copy of string */
 4385 tgl                        66 CBC       12373 :     rawstring = pstrdup(*newval);
                                 67                 : 
                                 68                 :     /* Parse string into list of identifiers */
 7632 tgl                        69 GIC       12373 :     if (!SplitIdentifierString(rawstring, ',', &elemlist))
                                 70                 :     {
                                 71                 :         /* syntax error in list */
 4385 tgl                        72 UIC           0 :         GUC_check_errdetail("List syntax is invalid.");
 7632                            73               0 :         pfree(rawstring);
 6892 neilc                      74 LBC           0 :         list_free(elemlist);
 4385 tgl                        75 UIC           0 :         return false;
                                 76                 :     }
 7632 tgl                        77 ECB             : 
 7632 tgl                        78 GIC       33130 :     foreach(l, elemlist)
                                 79                 :     {
 7632 tgl                        80 GBC       20757 :         char       *tok = (char *) lfirst(l);
 7632 tgl                        81 EUB             : 
 9488 scrappy                    82                 :         /* Ugh. Somebody ought to write a table driven version -- mjl */
 9424 lockhart                   83                 : 
 6911 tgl                        84 GIC       20757 :         if (pg_strcasecmp(tok, "ISO") == 0)
                                 85                 :         {
 6513 tgl                        86 CBC        8700 :             if (have_style && newDateStyle != USE_ISO_DATES)
 6513 tgl                        87 UIC           0 :                 ok = false;     /* conflicting styles */
 7632 tgl                        88 CBC        8700 :             newDateStyle = USE_ISO_DATES;
 6513 tgl                        89 GIC        8700 :             have_style = true;
                                 90                 :         }
 6911                            91           12057 :         else if (pg_strcasecmp(tok, "SQL") == 0)
 9345 bruce                      92 ECB             :         {
 6513 tgl                        93 GIC          15 :             if (have_style && newDateStyle != USE_SQL_DATES)
 6513 tgl                        94 LBC           0 :                 ok = false;     /* conflicting styles */
 7632 tgl                        95 GBC          15 :             newDateStyle = USE_SQL_DATES;
 6513 tgl                        96 CBC          15 :             have_style = true;
 9345 bruce                      97 ECB             :         }
 6911 tgl                        98 GIC       12042 :         else if (pg_strncasecmp(tok, "POSTGRES", 8) == 0)
 9345 bruce                      99 ECB             :         {
 6513 tgl                       100 GIC        3615 :             if (have_style && newDateStyle != USE_POSTGRES_DATES)
 6513 tgl                       101 LBC           0 :                 ok = false;     /* conflicting styles */
 7632 tgl                       102 GBC        3615 :             newDateStyle = USE_POSTGRES_DATES;
 6513 tgl                       103 CBC        3615 :             have_style = true;
 9345 bruce                     104 ECB             :         }
 6911 tgl                       105 GIC        8427 :         else if (pg_strcasecmp(tok, "GERMAN") == 0)
 9345 bruce                     106 ECB             :         {
 6513 tgl                       107 GIC          20 :             if (have_style && newDateStyle != USE_GERMAN_DATES)
 6513 tgl                       108 LBC           0 :                 ok = false;     /* conflicting styles */
 7632 tgl                       109 GBC          20 :             newDateStyle = USE_GERMAN_DATES;
 6513 tgl                       110 CBC          20 :             have_style = true;
 7194 tgl                       111 ECB             :             /* GERMAN also sets DMY, unless explicitly overridden */
 6513 tgl                       112 GIC          20 :             if (!have_order)
 7194 tgl                       113 CBC          20 :                 newDateOrder = DATEORDER_DMY;
                                114                 :         }
 6911                           115            8407 :         else if (pg_strcasecmp(tok, "YMD") == 0)
 9257 lockhart                  116 EUB             :         {
 6513 tgl                       117 CBC          18 :             if (have_order && newDateOrder != DATEORDER_YMD)
 6513 tgl                       118 LBC           0 :                 ok = false;     /* conflicting orders */
 7194 tgl                       119 GIC          18 :             newDateOrder = DATEORDER_YMD;
 6513 tgl                       120 CBC          18 :             have_order = true;
 9257 lockhart                  121 ECB             :         }
 6911 tgl                       122 GIC       16755 :         else if (pg_strcasecmp(tok, "DMY") == 0 ||
 6911 tgl                       123 CBC        8366 :                  pg_strncasecmp(tok, "EURO", 4) == 0)
                                124                 :         {
 6513                           125              32 :             if (have_order && newDateOrder != DATEORDER_DMY)
 6513 tgl                       126 UBC           0 :                 ok = false;     /* conflicting orders */
 7194 tgl                       127 CBC          32 :             newDateOrder = DATEORDER_DMY;
 6513                           128              32 :             have_order = true;
                                129                 :         }
 6911                           130            8366 :         else if (pg_strcasecmp(tok, "MDY") == 0 ||
                                131               9 :                  pg_strcasecmp(tok, "US") == 0 ||
 6911 tgl                       132 UIC           0 :                  pg_strncasecmp(tok, "NONEURO", 7) == 0)
 7194 tgl                       133 ECB             :         {
 6513 tgl                       134 GBC        8357 :             if (have_order && newDateOrder != DATEORDER_MDY)
 6513 tgl                       135 LBC           0 :                 ok = false;     /* conflicting orders */
 7194 tgl                       136 CBC        8357 :             newDateOrder = DATEORDER_MDY;
 6513 tgl                       137 GIC        8357 :             have_order = true;
 9345 bruce                     138 ECB             :         }
 6911 tgl                       139 LBC           0 :         else if (pg_strcasecmp(tok, "DEFAULT") == 0)
 9345 bruce                     140 EUB             :         {
                                141                 :             /*
 6385 bruce                     142 ECB             :              * Easiest way to get the current DEFAULT state is to fetch the
 6385 bruce                     143 EUB             :              * DEFAULT string from guc.c and recursively parse it.
 7632 tgl                       144 ECB             :              *
 4385                           145                 :              * We can't simply "return check_datestyle(...)" because we need
                                146                 :              * to handle constructs like "DEFAULT, ISO".
 7632 tgl                       147 EUB             :              */
                                148                 :             char       *subval;
 4382 bruce                     149 UIC           0 :             void       *subextra = NULL;
                                150                 : 
  177 tgl                       151 UNC           0 :             subval = guc_strdup(LOG, GetConfigOptionResetString("datestyle"));
 7632 tgl                       152 UIC           0 :             if (!subval)
                                153                 :             {
                                154               0 :                 ok = false;
                                155               0 :                 break;
                                156                 :             }
 4385 tgl                       157 UBC           0 :             if (!check_datestyle(&subval, &subextra, source))
                                158                 :             {
  177 tgl                       159 UNC           0 :                 guc_free(subval);
 4385 tgl                       160 UBC           0 :                 ok = false;
 4385 tgl                       161 UIC           0 :                 break;
 4385 tgl                       162 EUB             :             }
 4385 tgl                       163 UBC           0 :             myextra = (int *) subextra;
 4385 tgl                       164 UIC           0 :             if (!have_style)
 4385 tgl                       165 UBC           0 :                 newDateStyle = myextra[0];
 4385 tgl                       166 UIC           0 :             if (!have_order)
 4385 tgl                       167 UBC           0 :                 newDateOrder = myextra[1];
  177 tgl                       168 UNC           0 :             guc_free(subval);
                                169               0 :             guc_free(subextra);
                                170                 :         }
 9488 scrappy                   171 EUB             :         else
 7632 tgl                       172                 :         {
 4385 tgl                       173 UBC           0 :             GUC_check_errdetail("Unrecognized key word: \"%s\".", tok);
                                174               0 :             pfree(rawstring);
                                175               0 :             list_free(elemlist);
                                176               0 :             return false;
 7632 tgl                       177 EUB             :         }
                                178                 :     }
                                179                 : 
 7632 tgl                       180 GIC       12373 :     pfree(rawstring);
 6892 neilc                     181 GBC       12373 :     list_free(elemlist);
 7843 lockhart                  182 EUB             : 
 7632 tgl                       183 GBC       12373 :     if (!ok)
 7658 lockhart                  184 EUB             :     {
 4385 tgl                       185 UIC           0 :         GUC_check_errdetail("Conflicting \"datestyle\" specifications.");
                                186               0 :         return false;
                                187                 :     }
 7658 lockhart                  188 ECB             : 
 7632 tgl                       189                 :     /*
                                190                 :      * Prepare the canonical string to return.  GUC wants it guc_malloc'd.
                                191                 :      */
  177 tgl                       192 GNC       12373 :     result = (char *) guc_malloc(LOG, 32);
 7632 tgl                       193 GBC       12373 :     if (!result)
 4385 tgl                       194 UBC           0 :         return false;
                                195                 : 
 7632 tgl                       196 GIC       12373 :     switch (newDateStyle)
                                197                 :     {
                                198            8712 :         case USE_ISO_DATES:
                                199            8712 :             strcpy(result, "ISO");
 7632 tgl                       200 CBC        8712 :             break;
                                201              15 :         case USE_SQL_DATES:
 7632 tgl                       202 GBC          15 :             strcpy(result, "SQL");
 7632 tgl                       203 GIC          15 :             break;
 7632 tgl                       204 CBC          20 :         case USE_GERMAN_DATES:
 7208 tgl                       205 GIC          20 :             strcpy(result, "German");
 7632 tgl                       206 CBC          20 :             break;
                                207            3626 :         default:
 7208                           208            3626 :             strcpy(result, "Postgres");
 7632                           209            3626 :             break;
 7658 lockhart                  210 ECB             :     }
 7194 tgl                       211 CBC       12373 :     switch (newDateOrder)
 7194 tgl                       212 ECB             :     {
 7194 tgl                       213 CBC          24 :         case DATEORDER_YMD:
                                214              24 :             strcat(result, ", YMD");
                                215              24 :             break;
                                216              42 :         case DATEORDER_DMY:
                                217              42 :             strcat(result, ", DMY");
 7194 tgl                       218 GIC          42 :             break;
 7194 tgl                       219 CBC       12307 :         default:
 7194 tgl                       220 GIC       12307 :             strcat(result, ", MDY");
 7194 tgl                       221 CBC       12307 :             break;
 7194 tgl                       222 ECB             :     }
 7632                           223                 : 
  177 tgl                       224 GNC       12373 :     guc_free(*newval);
 4385 tgl                       225 CBC       12373 :     *newval = result;
 4385 tgl                       226 ECB             : 
 7632                           227                 :     /*
 4385                           228                 :      * Set up the "extra" struct actually used by assign_datestyle.
 7632                           229                 :      */
  177 tgl                       230 GNC       12373 :     myextra = (int *) guc_malloc(LOG, 2 * sizeof(int));
 4385 tgl                       231 GIC       12373 :     if (!myextra)
 4385 tgl                       232 LBC           0 :         return false;
 4385 tgl                       233 CBC       12373 :     myextra[0] = newDateStyle;
 4385 tgl                       234 GIC       12373 :     myextra[1] = newDateOrder;
                                235           12373 :     *extra = (void *) myextra;
                                236                 : 
                                237           12373 :     return true;
 4385 tgl                       238 ECB             : }
                                239                 : 
 4385 tgl                       240 EUB             : /*
 4385 tgl                       241 ECB             :  * assign_datestyle: GUC assign_hook for datestyle
                                242                 :  */
                                243                 : void
 4385 tgl                       244 GIC       15715 : assign_datestyle(const char *newval, void *extra)
 4385 tgl                       245 ECB             : {
 4385 tgl                       246 GIC       15715 :     int        *myextra = (int *) extra;
                                247                 : 
                                248           15715 :     DateStyle = myextra[0];
                                249           15715 :     DateOrder = myextra[1];
 7843 lockhart                  250           15715 : }
                                251                 : 
 8450 tgl                       252 ECB             : 
                                253                 : /*
 7632                           254                 :  * TIMEZONE
                                255                 :  */
 9281 lockhart                  256                 : 
 8943 bruce                     257                 : /*
 4385 tgl                       258                 :  * check_timezone: GUC check_hook for timezone
                                259                 :  */
                                260                 : bool
 4385 tgl                       261 GIC        8068 : check_timezone(char **newval, void **extra, GucSource source)
                                262                 : {
                                263                 :     pg_tz      *new_tz;
                                264                 :     long        gmtoffset;
                                265                 :     char       *endptr;
                                266                 :     double      hours;
                                267                 : 
                                268            8068 :     if (pg_strncasecmp(*newval, "interval", 8) == 0)
 9292 lockhart                  269 ECB             :     {
                                270                 :         /*
                                271                 :          * Support INTERVAL 'foo'.  This is for SQL spec compliance, not
                                272                 :          * because it has any actual real-world usefulness.
                                273                 :          */
 4385 tgl                       274 UIC           0 :         const char *valueptr = *newval;
                                275                 :         char       *val;
 7632 tgl                       276 ECB             :         Interval   *interval;
                                277                 : 
 7632 tgl                       278 UIC           0 :         valueptr += 8;
                                279               0 :         while (isspace((unsigned char) *valueptr))
                                280               0 :             valueptr++;
                                281               0 :         if (*valueptr++ != '\'')
 4385 tgl                       282 UBC           0 :             return false;
 7632 tgl                       283 UIC           0 :         val = pstrdup(valueptr);
                                284                 :         /* Check and remove trailing quote */
                                285               0 :         endptr = strchr(val, '\'');
 7632 tgl                       286 UBC           0 :         if (!endptr || endptr[1] != '\0')
 7843 lockhart                  287 EUB             :         {
 7632 tgl                       288 UBC           0 :             pfree(val);
 4385                           289               0 :             return false;
 7632 tgl                       290 EUB             :         }
 7632 tgl                       291 UBC           0 :         *endptr = '\0';
                                292                 : 
 7632 tgl                       293 EUB             :         /*
                                294                 :          * Try to parse it.  XXX an invalid interval format will result in
                                295                 :          * ereport(ERROR), which is not desirable for GUC.  We did what we
 5581                           296                 :          * could to guard against this in flatten_set_variable_args, but a
                                297                 :          * string coming in from postgresql.conf might contain anything.
                                298                 :          */
 7632 tgl                       299 UBC           0 :         interval = DatumGetIntervalP(DirectFunctionCall3(interval_in,
                                300                 :                                                          CStringGetDatum(val),
                                301                 :                                                          ObjectIdGetDatum(InvalidOid),
                                302                 :                                                          Int32GetDatum(-1)));
                                303                 : 
 7632 tgl                       304 UIC           0 :         pfree(val);
                                305               0 :         if (interval->month != 0)
                                306                 :         {
 4385 tgl                       307 UBC           0 :             GUC_check_errdetail("Cannot specify months in time zone interval.");
 7632 tgl                       308 UIC           0 :             pfree(interval);
 4385                           309               0 :             return false;
                                310                 :         }
 6472 bruce                     311               0 :         if (interval->day != 0)
 6472 bruce                     312 EUB             :         {
 4385 tgl                       313 UBC           0 :             GUC_check_errdetail("Cannot specify days in time zone interval.");
 6472 bruce                     314 UIC           0 :             pfree(interval);
 4385 tgl                       315 UBC           0 :             return false;
 6472 bruce                     316 EUB             :         }
 4385 tgl                       317                 : 
                                318                 :         /* Here we change from SQL to Unix sign convention */
 3446 tgl                       319 UBC           0 :         gmtoffset = -(interval->time / USECS_PER_SEC);
 3446 tgl                       320 UIC           0 :         new_tz = pg_tzset_offset(gmtoffset);
 6796 bruce                     321 EUB             : 
 7632 tgl                       322 UBC           0 :         pfree(interval);
 7632 tgl                       323 EUB             :     }
                                324                 :     else
                                325                 :     {
                                326                 :         /*
                                327                 :          * Try it as a numeric number of hours (possibly fractional).
                                328                 :          */
 4385 tgl                       329 GIC        8068 :         hours = strtod(*newval, &endptr);
 4385 tgl                       330 GBC        8068 :         if (endptr != *newval && *endptr == '\0')
                                331                 :         {
                                332                 :             /* Here we change from SQL to Unix sign convention */
 3446 tgl                       333 GIC          33 :             gmtoffset = -hours * SECS_PER_HOUR;
                                334              33 :             new_tz = pg_tzset_offset(gmtoffset);
                                335                 :         }
                                336                 :         else
 7843 lockhart                  337 ECB             :         {
 7632 tgl                       338                 :             /*
                                339                 :              * Otherwise assume it is a timezone name, and try to load it.
                                340                 :              */
 4385 tgl                       341 CBC        8035 :             new_tz = pg_tzset(*newval);
 7266 tgl                       342 ECB             : 
 6564 bruce                     343 GIC        8035 :             if (!new_tz)
                                344                 :             {
                                345                 :                 /* Doesn't seem to be any great value in errdetail here */
 4385 tgl                       346 UIC           0 :                 return false;
                                347                 :             }
                                348                 : 
 4230 tgl                       349 CBC        8035 :             if (!pg_tz_acceptable(new_tz))
                                350                 :             {
 4385 tgl                       351 LBC           0 :                 GUC_check_errmsg("time zone \"%s\" appears to use leap seconds",
                                352                 :                                  *newval);
 4385 tgl                       353 UIC           0 :                 GUC_check_errdetail("PostgreSQL does not support leap seconds.");
 4385 tgl                       354 UBC           0 :                 return false;
                                355                 :             }
                                356                 :         }
 9292 lockhart                  357 ECB             :     }
                                358                 : 
 3184 tgl                       359 EUB             :     /* Test for failure in pg_tzset_offset, which we assume is out-of-range */
 3184 tgl                       360 GIC        8068 :     if (!new_tz)
 3184 tgl                       361 EUB             :     {
 3184 tgl                       362 UBC           0 :         GUC_check_errdetail("UTC timezone offset is out of range.");
 3184 tgl                       363 UIC           0 :         return false;
                                364                 :     }
                                365                 : 
                                366                 :     /*
                                367                 :      * Pass back data for assign_timezone to use
 4385 tgl                       368 ECB             :      */
  177 tgl                       369 GNC        8068 :     *extra = guc_malloc(LOG, sizeof(pg_tz *));
 4385 tgl                       370 GBC        8068 :     if (!*extra)
 4385 tgl                       371 UBC           0 :         return false;
 3446 tgl                       372 GIC        8068 :     *((pg_tz **) *extra) = new_tz;
                                373                 : 
 4385                           374            8068 :     return true;
                                375                 : }
                                376                 : 
 4385 tgl                       377 ECB             : /*
                                378                 :  * assign_timezone: GUC assign_hook for timezone
 4385 tgl                       379 EUB             :  */
 4385 tgl                       380 ECB             : void
 4385 tgl                       381 GIC        8110 : assign_timezone(const char *newval, void *extra)
 4385 tgl                       382 ECB             : {
 3446 tgl                       383 GIC        8110 :     session_timezone = *((pg_tz **) extra);
 7632                           384            8110 : }
                                385                 : 
                                386                 : /*
                                387                 :  * show_timezone: GUC show_hook for timezone
                                388                 :  */
 7632 tgl                       389 ECB             : const char *
 8201 tgl                       390 GIC       18359 : show_timezone(void)
 9292 lockhart                  391 ECB             : {
 6797 bruce                     392                 :     const char *tzn;
                                393                 : 
                                394                 :     /* Always show the zone's canonical name */
 3446 tgl                       395 GIC       18359 :     tzn = pg_get_timezone_name(session_timezone);
                                396                 : 
 5727                           397           18359 :     if (tzn != NULL)
 5727 tgl                       398 CBC       18359 :         return tzn;
                                399                 : 
 5727 tgl                       400 UIC           0 :     return "unknown";
                                401                 : }
                                402                 : 
 5727 tgl                       403 ECB             : 
                                404                 : /*
                                405                 :  * LOG_TIMEZONE
                                406                 :  *
                                407                 :  * For log_timezone, we don't support the interval-based methods of setting a
 5727 tgl                       408 EUB             :  * zone, which are only there for SQL spec compliance not because they're
                                409                 :  * actually useful.
                                410                 :  */
                                411                 : 
                                412                 : /*
                                413                 :  * check_log_timezone: GUC check_hook for log_timezone
                                414                 :  */
                                415                 : bool
 4385 tgl                       416 GIC        6016 : check_log_timezone(char **newval, void **extra, GucSource source)
                                417                 : {
                                418                 :     pg_tz      *new_tz;
                                419                 : 
                                420                 :     /*
                                421                 :      * Assume it is a timezone name, and try to load it.
                                422                 :      */
                                423            6016 :     new_tz = pg_tzset(*newval);
 5727 tgl                       424 ECB             : 
 4385 tgl                       425 GIC        6016 :     if (!new_tz)
                                426                 :     {
                                427                 :         /* Doesn't seem to be any great value in errdetail here */
 4385 tgl                       428 UIC           0 :         return false;
                                429                 :     }
                                430                 : 
 4230 tgl                       431 CBC        6016 :     if (!pg_tz_acceptable(new_tz))
                                432                 :     {
 4385 tgl                       433 LBC           0 :         GUC_check_errmsg("time zone \"%s\" appears to use leap seconds",
                                434                 :                          *newval);
 4385 tgl                       435 UIC           0 :         GUC_check_errdetail("PostgreSQL does not support leap seconds.");
 4385 tgl                       436 UBC           0 :         return false;
                                437                 :     }
                                438                 : 
 5727 tgl                       439 ECB             :     /*
                                440                 :      * Pass back data for assign_log_timezone to use
 5727 tgl                       441 EUB             :      */
  177 tgl                       442 GNC        6016 :     *extra = guc_malloc(LOG, sizeof(pg_tz *));
 4385 tgl                       443 GBC        6016 :     if (!*extra)
 4385 tgl                       444 UBC           0 :         return false;
 3446 tgl                       445 GIC        6016 :     *((pg_tz **) *extra) = new_tz;
                                446                 : 
 4385                           447            6016 :     return true;
                                448                 : }
                                449                 : 
 4385 tgl                       450 ECB             : /*
                                451                 :  * assign_log_timezone: GUC assign_hook for log_timezone
 4385 tgl                       452 EUB             :  */
 4385 tgl                       453 ECB             : void
 4385 tgl                       454 GIC        6013 : assign_log_timezone(const char *newval, void *extra)
 4385 tgl                       455 ECB             : {
 4385 tgl                       456 GIC        6013 :     log_timezone = *((pg_tz **) extra);
 5727                           457            6013 : }
                                458                 : 
                                459                 : /*
                                460                 :  * show_log_timezone: GUC show_hook for log_timezone
                                461                 :  */
 5727 tgl                       462 ECB             : const char *
 5727 tgl                       463 GIC        1088 : show_log_timezone(void)
 5727 tgl                       464 ECB             : {
                                465                 :     const char *tzn;
                                466                 : 
                                467                 :     /* Always show the zone's canonical name */
 5727 tgl                       468 GIC        1088 :     tzn = pg_get_timezone_name(log_timezone);
                                469                 : 
 7843 lockhart                  470            1088 :     if (tzn != NULL)
 7632 tgl                       471 CBC        1088 :         return tzn;
                                472                 : 
 7632 tgl                       473 UIC           0 :     return "unknown";
                                474                 : }
                                475                 : 
 8423 tgl                       476 ECB             : 
                                477                 : /*
                                478                 :  * TIMEZONE_ABBREVIATIONS
                                479                 :  */
                                480                 : 
                                481                 : /*
                                482                 :  * GUC check_hook for assign_timezone_abbreviations
                                483                 :  */
                                484                 : bool
  208 tgl                       485 GNC        9732 : check_timezone_abbreviations(char **newval, void **extra, GucSource source)
                                486                 : {
                                487                 :     /*
                                488                 :      * The boot_val for timezone_abbreviations is NULL.  When we see that we
                                489                 :      * just do nothing.  If the value isn't overridden from the config file
                                490                 :      * then pg_timezone_abbrev_initialize() will eventually replace it with
                                491                 :      * "Default".  This hack has two purposes: to avoid wasting cycles loading
                                492                 :      * values that might soon be overridden from the config file, and to avoid
                                493                 :      * trying to read the timezone abbrev files during InitializeGUCOptions().
                                494                 :      * The latter doesn't work in an EXEC_BACKEND subprocess because
                                495                 :      * my_exec_path hasn't been set yet and so we can't locate PGSHAREDIR.
                                496                 :      */
                                497            9732 :     if (*newval == NULL)
                                498                 :     {
                                499            3155 :         Assert(source == PGC_S_DEFAULT);
                                500            3155 :         return true;
                                501                 :     }
                                502                 : 
                                503                 :     /* OK, load the file and produce a guc_malloc'd TimeZoneAbbrevTable */
                                504            6577 :     *extra = load_tzoffsets(*newval);
                                505                 : 
                                506                 :     /* tzparser.c returns NULL on failure, reporting via GUC_check_errmsg */
                                507            6577 :     if (!*extra)
  208 tgl                       508 UNC           0 :         return false;
                                509                 : 
  208 tgl                       510 GNC        6577 :     return true;
                                511                 : }
                                512                 : 
                                513                 : /*
                                514                 :  * GUC assign_hook for assign_timezone_abbreviations
                                515                 :  */
                                516                 : void
                                517            9644 : assign_timezone_abbreviations(const char *newval, void *extra)
                                518                 : {
                                519                 :     /* Do nothing for the boot_val default of NULL */
                                520            9644 :     if (!extra)
                                521            3155 :         return;
                                522                 : 
                                523            6489 :     InstallTimeZoneAbbrevs((TimeZoneAbbrevTable *) extra);
                                524                 : }
                                525                 : 
                                526                 : 
                                527                 : /*
 4460 rhaas                     528 ECB             :  * SET TRANSACTION READ ONLY and SET TRANSACTION READ WRITE
                                529                 :  *
                                530                 :  * We allow idempotent changes (r/w -> r/w and r/o -> r/o) at any time, and
 4460 rhaas                     531 EUB             :  * we also always allow changes from read-write to read-only.  However,
                                532                 :  * read-only may be changed to read-write only when in a top-level transaction
                                533                 :  * that has not yet taken an initial snapshot.  Can't do it in a hot standby,
                                534                 :  * either.
                                535                 :  *
                                536                 :  * If we are not in a transaction at all, just allow the change; it means
                                537                 :  * nothing since XactReadOnly will be reset by the next StartTransaction().
                                538                 :  * The IsTransactionState() test protects us against trying to check
                                539                 :  * RecoveryInProgress() in contexts where shared memory is not accessible.
                                540                 :  * (Similarly, if we're restoring state in a parallel worker, just allow
                                541                 :  * the change.)
                                542                 :  */
 4460 rhaas                     543 ECB             : bool
 4385 tgl                       544 GIC        6943 : check_transaction_read_only(bool *newval, void **extra, GucSource source)
                                545                 : {
 2588 rhaas                     546            6943 :     if (*newval == false && XactReadOnly && IsTransactionState() && !InitializingParallelWorker)
                                547                 :     {
                                548                 :         /* Can't go to r/w mode inside a r/o transaction */
 4460                           549              29 :         if (IsSubTransaction())
                                550                 :         {
 4385 tgl                       551               6 :             GUC_check_errcode(ERRCODE_ACTIVE_SQL_TRANSACTION);
                                552               6 :             GUC_check_errmsg("cannot set transaction read-write mode inside a read-only transaction");
 4460 rhaas                     553               6 :             return false;
                                554                 :         }
 4460 rhaas                     555 ECB             :         /* Top level transaction can't change to r/w after first snapshot. */
 4460 rhaas                     556 GIC          23 :         if (FirstSnapshotSet)
 4460 rhaas                     557 ECB             :         {
 4385 tgl                       558 CBC           3 :             GUC_check_errcode(ERRCODE_ACTIVE_SQL_TRANSACTION);
 4385 tgl                       559 GIC           3 :             GUC_check_errmsg("transaction read-write mode must be set before any query");
 4460 rhaas                     560               3 :             return false;
                                561                 :         }
 4460 rhaas                     562 ECB             :         /* Can't go to r/w mode while recovery is still active */
 4460 rhaas                     563 GIC          20 :         if (RecoveryInProgress())
                                564                 :         {
 3880 tgl                       565 LBC           0 :             GUC_check_errcode(ERRCODE_FEATURE_NOT_SUPPORTED);
 4385 tgl                       566 UBC           0 :             GUC_check_errmsg("cannot set transaction read-write mode during recovery");
 4460 rhaas                     567 UIC           0 :             return false;
 4460 rhaas                     568 ECB             :         }
                                569                 :     }
                                570                 : 
 4460 rhaas                     571 GIC        6934 :     return true;
                                572                 : }
                                573                 : 
                                574                 : /*
 7632 tgl                       575 ECB             :  * SET TRANSACTION ISOLATION LEVEL
                                576                 :  *
                                577                 :  * We allow idempotent changes at any time, but otherwise this can only be
 4385                           578                 :  * changed in a toplevel transaction that has not yet taken a snapshot.
 3880                           579                 :  *
                                580                 :  * As in check_transaction_read_only, allow it if not inside a transaction.
 7843 lockhart                  581                 :  */
                                582                 : bool
  208 tgl                       583 GNC        9488 : check_transaction_isolation(int *newval, void **extra, GucSource source)
                                584                 : {
 1643 peter_e                   585 GIC        9488 :     int         newXactIsoLevel = *newval;
                                586                 : 
 3880 tgl                       587            9488 :     if (newXactIsoLevel != XactIsoLevel && IsTransactionState())
                                588                 :     {
 4461 rhaas                     589            2783 :         if (FirstSnapshotSet)
                                590                 :         {
 4385 tgl                       591               1 :             GUC_check_errcode(ERRCODE_ACTIVE_SQL_TRANSACTION);
                                592               1 :             GUC_check_errmsg("SET TRANSACTION ISOLATION LEVEL must be called before any query");
                                593               1 :             return false;
                                594                 :         }
                                595                 :         /* We ignore a subtransaction setting it to the existing value. */
 4460 rhaas                     596            2782 :         if (IsSubTransaction())
                                597                 :         {
 4385 tgl                       598 UIC           0 :             GUC_check_errcode(ERRCODE_ACTIVE_SQL_TRANSACTION);
                                599               0 :             GUC_check_errmsg("SET TRANSACTION ISOLATION LEVEL must not be called in a subtransaction");
                                600               0 :             return false;
                                601                 :         }
 4444 heikki.linnakangas        602 ECB             :         /* Can't go to serializable mode while recovery is still active */
 4385 tgl                       603 GIC        2782 :         if (newXactIsoLevel == XACT_SERIALIZABLE && RecoveryInProgress())
 4444 heikki.linnakangas        604 ECB             :         {
 3880 tgl                       605 UIC           0 :             GUC_check_errcode(ERRCODE_FEATURE_NOT_SUPPORTED);
 4385                           606               0 :             GUC_check_errmsg("cannot use serializable mode in a hot standby");
 4385 tgl                       607 LBC           0 :             GUC_check_errhint("You can use REPEATABLE READ instead.");
 4444 heikki.linnakangas        608 UIC           0 :             return false;
 4444 heikki.linnakangas        609 ECB             :         }
 6856 tgl                       610                 :     }
 8454                           611                 : 
 4385 tgl                       612 GIC        9487 :     return true;
                                613                 : }
 8454 tgl                       614 ECB             : 
                                615                 : /*
 4444 heikki.linnakangas        616                 :  * SET TRANSACTION [NOT] DEFERRABLE
                                617                 :  */
                                618                 : 
                                619                 : bool
 4385 tgl                       620 GIC        6334 : check_transaction_deferrable(bool *newval, void **extra, GucSource source)
 4444 heikki.linnakangas        621 ECB             : {
 4444 heikki.linnakangas        622 GIC        6334 :     if (IsSubTransaction())
 4444 heikki.linnakangas        623 EUB             :     {
 4385 tgl                       624 UBC           0 :         GUC_check_errcode(ERRCODE_ACTIVE_SQL_TRANSACTION);
                                625               0 :         GUC_check_errmsg("SET TRANSACTION [NOT] DEFERRABLE cannot be called within a subtransaction");
 4444 heikki.linnakangas        626 UIC           0 :         return false;
                                627                 :     }
 4444 heikki.linnakangas        628 GIC        6334 :     if (FirstSnapshotSet)
 4444 heikki.linnakangas        629 ECB             :     {
 4385 tgl                       630 UIC           0 :         GUC_check_errcode(ERRCODE_ACTIVE_SQL_TRANSACTION);
                                631               0 :         GUC_check_errmsg("SET TRANSACTION [NOT] DEFERRABLE must be called before any query");
 4444 heikki.linnakangas        632               0 :         return false;
                                633                 :     }
                                634                 : 
 4444 heikki.linnakangas        635 GIC        6334 :     return true;
                                636                 : }
                                637                 : 
                                638                 : /*
                                639                 :  * Random number seed
                                640                 :  *
 4385 tgl                       641 ECB             :  * We can't roll back the random sequence on error, and we don't want
                                642                 :  * config file reloads to affect it, so we only want interactive SET SEED
 3260 bruce                     643                 :  * commands to set it.  We use the "extra" storage to ensure that rollbacks
                                644                 :  * don't try to do the operation again.
 8402 lockhart                  645                 :  */
                                646                 : 
 7632 tgl                       647                 : bool
 4385 tgl                       648 GIC        1857 : check_random_seed(double *newval, void **extra, GucSource source)
 8402 lockhart                  649 ECB             : {
  177 tgl                       650 GNC        1857 :     *extra = guc_malloc(LOG, sizeof(int));
 4385 tgl                       651 CBC        1857 :     if (!*extra)
 4385 tgl                       652 UIC           0 :         return false;
                                653                 :     /* Arm the assign only if source of value is an interactive SET */
 4385 tgl                       654 CBC        1857 :     *((int *) *extra) = (source >= PGC_S_INTERACTIVE);
                                655                 : 
 7632 tgl                       656 GBC        1857 :     return true;
 8402 lockhart                  657 EUB             : }
                                658                 : 
                                659                 : void
 4385 tgl                       660 GIC        1857 : assign_random_seed(double newval, void *extra)
 4385 tgl                       661 ECB             : {
                                662                 :     /* We'll do this at most once for any setting of the GUC variable */
 4385 tgl                       663 GBC        1857 :     if (*((int *) extra))
 4385 tgl                       664 UBC           0 :         DirectFunctionCall1(setseed, Float8GetDatum(newval));
 4385 tgl                       665 GBC        1857 :     *((int *) extra) = 0;
                                666            1857 : }
                                667                 : 
                                668                 : const char *
 7632 tgl                       669 UIC           0 : show_random_seed(void)
 8402 lockhart                  670 ECB             : {
 7632 tgl                       671 UIC           0 :     return "unavailable";
                                672                 : }
                                673                 : 
                                674                 : 
                                675                 : /*
                                676                 :  * SET CLIENT_ENCODING
                                677                 :  */
 8201 tgl                       678 ECB             : 
                                679                 : bool
 4385 tgl                       680 CBC       15595 : check_client_encoding(char **newval, void **extra, GucSource source)
                                681                 : {
 7836 bruce                     682 EUB             :     int         encoding;
 4373 tgl                       683                 :     const char *canonical_name;
 7843 lockhart                  684                 : 
                                685                 :     /* Look up the encoding by name */
 4385 tgl                       686 CBC       15595 :     encoding = pg_valid_client_encoding(*newval);
 8201 tgl                       687 GIC       15595 :     if (encoding < 0)
 4385 tgl                       688 UBC           0 :         return false;
 7522 bruce                     689 EUB             : 
 4373 tgl                       690                 :     /* Get the canonical name (no aliases, uniform case) */
 4373 tgl                       691 GIC       15595 :     canonical_name = pg_encoding_to_char(encoding);
                                692                 : 
 7522 bruce                     693 ECB             :     /*
                                694                 :      * If we are not within a transaction then PrepareClientEncoding will not
                                695                 :      * be able to look up the necessary conversion procs.  If we are still
                                696                 :      * starting up, it will return "OK" anyway, and InitializeClientEncoding
                                697                 :      * will fix things once initialization is far enough along.  After
                                698                 :      * startup, we'll fail.  This would only happen if someone tries to change
                                699                 :      * client_encoding in postgresql.conf and then SIGHUP existing sessions.
                                700                 :      * It seems like a bad idea for client_encoding to change that way anyhow,
                                701                 :      * so we don't go out of our way to support it.
                                702                 :      *
                                703                 :      * Note: in the postmaster, or any other process that never calls
                                704                 :      * InitializeClientEncoding, PrepareClientEncoding will always succeed,
                                705                 :      * and so will SetClientEncoding; but they won't do anything, which is OK.
 7632 tgl                       706                 :      */
 4385 tgl                       707 GIC       15595 :     if (PrepareClientEncoding(encoding) < 0)
 8201 tgl                       708 ECB             :     {
 4385 tgl                       709 LBC           0 :         if (IsTransactionState())
 4385 tgl                       710 EUB             :         {
                                711                 :             /* Must be a genuine no-such-conversion problem */
 4385 tgl                       712 LBC           0 :             GUC_check_errcode(ERRCODE_FEATURE_NOT_SUPPORTED);
 4385 tgl                       713 UIC           0 :             GUC_check_errdetail("Conversion between %s and %s is not supported.",
 4373 tgl                       714 ECB             :                                 canonical_name,
                                715                 :                                 GetDatabaseEncodingName());
                                716                 :         }
                                717                 :         else
 4385                           718                 :         {
                                719                 :             /* Provide a useful complaint */
 4385 tgl                       720 UIC           0 :             GUC_check_errdetail("Cannot change \"client_encoding\" now.");
 4385 tgl                       721 ECB             :         }
 4385 tgl                       722 UBC           0 :         return false;
 8201 tgl                       723 ECB             :     }
 4385                           724                 : 
                                725                 :     /*
                                726                 :      * Replace the user-supplied string with the encoding's canonical name.
 4373 tgl                       727 EUB             :      * This gets rid of aliases and case-folding variations.
                                728                 :      *
                                729                 :      * XXX Although canonicalizing seems like a good idea in the abstract, it
                                730                 :      * breaks pre-9.1 JDBC drivers, which expect that if they send "UNICODE"
                                731                 :      * as the client_encoding setting then it will read back the same way. As
                                732                 :      * a workaround, don't replace the string if it's "UNICODE".  Remove that
                                733                 :      * hack when pre-9.1 JDBC drivers are no longer in use.
                                734                 :      */
 4373 tgl                       735 GIC       15595 :     if (strcmp(*newval, canonical_name) != 0 &&
                                736              14 :         strcmp(*newval, "UNICODE") != 0)
                                737                 :     {
  177 tgl                       738 GNC          14 :         guc_free(*newval);
                                739              14 :         *newval = guc_strdup(LOG, canonical_name);
 4373 tgl                       740 GIC          14 :         if (!*newval)
 4373 tgl                       741 UIC           0 :             return false;
                                742                 :     }
                                743                 : 
 4373 tgl                       744 ECB             :     /*
                                745                 :      * Save the encoding's ID in *extra, for use by assign_client_encoding.
 4373 tgl                       746 EUB             :      */
  177 tgl                       747 GNC       15595 :     *extra = guc_malloc(LOG, sizeof(int));
 4385 tgl                       748 GIC       15595 :     if (!*extra)
 4385 tgl                       749 LBC           0 :         return false;
 4385 tgl                       750 GIC       15595 :     *((int *) *extra) = encoding;
                                751                 : 
                                752           15595 :     return true;
                                753                 : }
                                754                 : 
                                755                 : void
                                756           15503 : assign_client_encoding(const char *newval, void *extra)
                                757                 : {
                                758           15503 :     int         encoding = *((int *) extra);
                                759                 : 
                                760                 :     /*
                                761                 :      * Parallel workers send data to the leader, not the client.  They always
                                762                 :      * send data using the database encoding.
                                763                 :      */
 2474 rhaas                     764           15503 :     if (IsParallelWorker())
 2474 rhaas                     765 ECB             :     {
                                766                 :         /*
 2474 rhaas                     767 EUB             :          * During parallel worker startup, we want to accept the leader's
                                768                 :          * client_encoding setting so that anyone who looks at the value in
                                769                 :          * the worker sees the same value that they would see in the leader.
                                770                 :          */
 2474 rhaas                     771 GBC        3894 :         if (InitializingParallelWorker)
 2474 rhaas                     772 GIC        3894 :             return;
                                773                 : 
                                774                 :         /*
                                775                 :          * A change other than during startup, for example due to a SET clause
                                776                 :          * attached to a function definition, should be rejected, as there is
                                777                 :          * nothing we can do inside the worker to make it take effect.
 2474 rhaas                     778 EUB             :          */
 2474 rhaas                     779 UIC           0 :         ereport(ERROR,
 2474 rhaas                     780 EUB             :                 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
                                781                 :                  errmsg("cannot change client_encoding during a parallel operation")));
                                782                 :     }
                                783                 : 
                                784                 :     /* We do not expect an error if PrepareClientEncoding succeeded */
 4385 tgl                       785 GIC       11609 :     if (SetClientEncoding(encoding) < 0)
 4385 tgl                       786 UIC           0 :         elog(LOG, "SetClientEncoding(%d) failed", encoding);
                                787                 : }
                                788                 : 
                                789                 : 
                                790                 : /*
                                791                 :  * SET SESSION AUTHORIZATION
                                792                 :  */
 6815 tgl                       793 ECB             : 
 4385                           794                 : typedef struct
                                795                 : {
                                796                 :     /* This is the "extra" state for both SESSION AUTHORIZATION and ROLE */
                                797                 :     Oid         roleid;
                                798                 :     bool        is_superuser;
 4385 tgl                       799 EUB             : } role_auth_extra;
                                800                 : 
                                801                 : bool
 4385 tgl                       802 GIC       15805 : check_session_authorization(char **newval, void **extra, GucSource source)
                                803                 : {
                                804                 :     HeapTuple   roleTup;
 1601 andres                    805 ECB             :     Form_pg_authid roleform;
 4385 tgl                       806                 :     Oid         roleid;
 4385 tgl                       807 EUB             :     bool        is_superuser;
 4385 tgl                       808 ECB             :     role_auth_extra *myextra;
                                809                 : 
                                810                 :     /* Do nothing for the boot_val default of NULL */
 4385 tgl                       811 GIC       15805 :     if (*newval == NULL)
                                812            3155 :         return true;
                                813                 : 
 4385 tgl                       814 CBC       12650 :     if (!IsTransactionState())
                                815                 :     {
 4385 tgl                       816 ECB             :         /*
                                817                 :          * Can't do catalog lookups, so fail.  The result of this is that
                                818                 :          * session_authorization cannot be set in postgresql.conf, which seems
                                819                 :          * like a good thing anyway, so we don't work hard to avoid it.
                                820                 :          */
 4385 tgl                       821 UIC           0 :         return false;
 7632 tgl                       822 ECB             :     }
                                823                 : 
                                824                 :     /* Look up the username */
 4385 tgl                       825 GIC       12650 :     roleTup = SearchSysCache1(AUTHNAME, PointerGetDatum(*newval));
                                826           12650 :     if (!HeapTupleIsValid(roleTup))
                                827                 :     {
                                828                 :         /*
  726 tgl                       829 ECB             :          * When source == PGC_S_TEST, we don't throw a hard error for a
                                830                 :          * nonexistent user name, only a NOTICE.  See comments in guc.h.
                                831                 :          */
  726 tgl                       832 UIC           0 :         if (source == PGC_S_TEST)
                                833                 :         {
                                834               0 :             ereport(NOTICE,
                                835                 :                     (errcode(ERRCODE_UNDEFINED_OBJECT),
                                836                 :                      errmsg("role \"%s\" does not exist", *newval)));
  726 tgl                       837 UBC           0 :             return true;
                                838                 :         }
 4385 tgl                       839 UIC           0 :         GUC_check_errmsg("role \"%s\" does not exist", *newval);
                                840               0 :         return false;
                                841                 :     }
                                842                 : 
 1601 andres                    843 CBC       12650 :     roleform = (Form_pg_authid) GETSTRUCT(roleTup);
 1601 andres                    844 GBC       12650 :     roleid = roleform->oid;
 1601 andres                    845 GIC       12650 :     is_superuser = roleform->rolsuper;
                                846                 : 
 4385 tgl                       847           12650 :     ReleaseSysCache(roleTup);
                                848                 : 
                                849                 :     /* Set up "extra" struct for assign_session_authorization to use */
  177 tgl                       850 GNC       12650 :     myextra = (role_auth_extra *) guc_malloc(LOG, sizeof(role_auth_extra));
 4385 tgl                       851 GIC       12650 :     if (!myextra)
 4385 tgl                       852 UIC           0 :         return false;
 4385 tgl                       853 GIC       12650 :     myextra->roleid = roleid;
                                854           12650 :     myextra->is_superuser = is_superuser;
                                855           12650 :     *extra = (void *) myextra;
                                856                 : 
                                857           12650 :     return true;
                                858                 : }
                                859                 : 
 4385 tgl                       860 ECB             : void
 4385 tgl                       861 GIC       16227 : assign_session_authorization(const char *newval, void *extra)
                                862                 : {
                                863           16227 :     role_auth_extra *myextra = (role_auth_extra *) extra;
                                864                 : 
                                865                 :     /* Do nothing for the boot_val default of NULL */
                                866           16227 :     if (!myextra)
                                867            3155 :         return;
                                868                 : 
 4385 tgl                       869 CBC       13072 :     SetSessionAuthorization(myextra->roleid, myextra->is_superuser);
 8053 bruce                     870 ECB             : }
                                871                 : 
 6467 tgl                       872                 : 
                                873                 : /*
                                874                 :  * SET ROLE
                                875                 :  *
                                876                 :  * The SQL spec requires "SET ROLE NONE" to unset the role, so we hardwire
                                877                 :  * a translation of "none" to InvalidOid.  Otherwise this is much like
                                878                 :  * SET SESSION AUTHORIZATION.
 6467 tgl                       879 EUB             :  */
                                880                 : extern char *role_string;       /* in guc_tables.c */
                                881                 : 
                                882                 : bool
 4385 tgl                       883 CBC        2257 : check_role(char **newval, void **extra, GucSource source)
 6467 tgl                       884 ECB             : {
                                885                 :     HeapTuple   roleTup;
                                886                 :     Oid         roleid;
                                887                 :     bool        is_superuser;
                                888                 :     role_auth_extra *myextra;
                                889                 :     Form_pg_authid roleform;
 6467 tgl                       890 EUB             : 
 4385 tgl                       891 GIC        2257 :     if (strcmp(*newval, "none") == 0)
 6467 tgl                       892 EUB             :     {
                                893                 :         /* hardwired translation */
 4385 tgl                       894 GIC        1857 :         roleid = InvalidOid;
 4385 tgl                       895 GBC        1857 :         is_superuser = false;
                                896                 :     }
 4385 tgl                       897 EUB             :     else
 6467                           898                 :     {
 6467 tgl                       899 GIC         400 :         if (!IsTransactionState())
                                900                 :         {
 6467 tgl                       901 ECB             :             /*
 4385                           902                 :              * Can't do catalog lookups, so fail.  The result of this is that
 6385 bruce                     903                 :              * role cannot be set in postgresql.conf, which seems like a good
                                904                 :              * thing anyway, so we don't work hard to avoid it.
 6467 tgl                       905                 :              */
 4385 tgl                       906 UIC           0 :             return false;
                                907                 :         }
 6467 tgl                       908 ECB             : 
  726                           909                 :         /*
  726 tgl                       910 EUB             :          * When source == PGC_S_TEST, we don't throw a hard error for a
  726 tgl                       911 ECB             :          * nonexistent user name or insufficient privileges, only a NOTICE.
                                912                 :          * See comments in guc.h.
                                913                 :          */
                                914                 : 
 4385                           915                 :         /* Look up the username */
 4385 tgl                       916 GIC         400 :         roleTup = SearchSysCache1(AUTHNAME, PointerGetDatum(*newval));
 6467                           917             400 :         if (!HeapTupleIsValid(roleTup))
                                918                 :         {
  726 tgl                       919 LBC           0 :             if (source == PGC_S_TEST)
                                920                 :             {
                                921               0 :                 ereport(NOTICE,
                                922                 :                         (errcode(ERRCODE_UNDEFINED_OBJECT),
                                923                 :                          errmsg("role \"%s\" does not exist", *newval)));
                                924               0 :                 return true;
  726 tgl                       925 ECB             :             }
 4385 tgl                       926 UIC           0 :             GUC_check_errmsg("role \"%s\" does not exist", *newval);
 4385 tgl                       927 LBC           0 :             return false;
                                928                 :         }
                                929                 : 
 1601 andres                    930 GIC         400 :         roleform = (Form_pg_authid) GETSTRUCT(roleTup);
                                931             400 :         roleid = roleform->oid;
                                932             400 :         is_superuser = roleform->rolsuper;
                                933                 : 
 6467 tgl                       934             400 :         ReleaseSysCache(roleTup);
                                935                 : 
                                936                 :         /*
                                937                 :          * Verify that session user is allowed to become this role, but skip
                                938                 :          * this in parallel mode, where we must blindly recreate the parallel
                                939                 :          * leader's state.
                                940                 :          */
 2732 rhaas                     941 CBC         400 :         if (!InitializingParallelWorker &&
  142 rhaas                     942 GNC         400 :             !member_can_set_role(GetSessionUserId(), roleid))
                                943                 :         {
  726 tgl                       944 GIC           6 :             if (source == PGC_S_TEST)
                                945                 :             {
  726 tgl                       946 UIC           0 :                 ereport(NOTICE,
                                947                 :                         (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
                                948                 :                          errmsg("permission will be denied to set role \"%s\"",
  726 tgl                       949 ECB             :                                 *newval)));
  726 tgl                       950 UIC           0 :                 return true;
                                951                 :             }
 4385 tgl                       952 CBC           6 :             GUC_check_errcode(ERRCODE_INSUFFICIENT_PRIVILEGE);
                                953               6 :             GUC_check_errmsg("permission denied to set role \"%s\"",
                                954                 :                              *newval);
 4385 tgl                       955 GIC           6 :             return false;
                                956                 :         }
 6467 tgl                       957 ECB             :     }
                                958                 : 
                                959                 :     /* Set up "extra" struct for assign_role to use */
  177 tgl                       960 GNC        2251 :     myextra = (role_auth_extra *) guc_malloc(LOG, sizeof(role_auth_extra));
 4385 tgl                       961 GIC        2251 :     if (!myextra)
 4385 tgl                       962 UIC           0 :         return false;
 4385 tgl                       963 GIC        2251 :     myextra->roleid = roleid;
 4385 tgl                       964 GBC        2251 :     myextra->is_superuser = is_superuser;
 4385 tgl                       965 GIC        2251 :     *extra = (void *) myextra;
                                966                 : 
                                967            2251 :     return true;
                                968                 : }
                                969                 : 
                                970                 : void
                                971            2537 : assign_role(const char *newval, void *extra)
                                972                 : {
                                973            2537 :     role_auth_extra *myextra = (role_auth_extra *) extra;
 6467 tgl                       974 ECB             : 
 4385 tgl                       975 CBC        2537 :     SetCurrentRoleId(myextra->roleid, myextra->is_superuser);
 6467 tgl                       976 GIC        2537 : }
 6467 tgl                       977 EUB             : 
                                978                 : const char *
 6467 tgl                       979 UBC           0 : show_role(void)
                                980                 : {
                                981                 :     /*
 3260 bruce                     982 EUB             :      * Check whether SET ROLE is active; if not return "none".  This is a
                                983                 :      * kluge to deal with the fact that SET SESSION AUTHORIZATION logically
 4385 tgl                       984                 :      * resets SET ROLE to NONE, but we cannot set the GUC role variable from
                                985                 :      * assign_session_authorization (because we haven't got enough info to
                                986                 :      * call set_config_option).
                                987                 :      */
 4385 tgl                       988 LBC           0 :     if (!OidIsValid(GetCurrentRoleId()))
 6467                           989               0 :         return "none";
 6467 tgl                       990 ECB             : 
                                991                 :     /* Otherwise we can just use the GUC string */
 4385 tgl                       992 LBC           0 :     return role_string ? role_string : "none";
                                993                 : }
                                994                 : 
                                995                 : 
                                996                 : /*
                                997                 :  * PATH VARIABLES
                                998                 :  *
                                999                 :  * check_canonical_path is used for log_directory and some other GUCs where
                               1000                 :  * all we want to do is canonicalize the represented path name.
                               1001                 :  */
                               1002                 : 
                               1003                 : bool
  208 tgl                      1004 GNC        3714 : check_canonical_path(char **newval, void **extra, GucSource source)
                               1005                 : {
                               1006                 :     /*
                               1007                 :      * Since canonicalize_path never enlarges the string, we can just modify
                               1008                 :      * newval in-place.  But watch out for NULL, which is the default value
                               1009                 :      * for external_pid_file.
                               1010                 :      */
                               1011            3714 :     if (*newval)
                               1012            1857 :         canonicalize_path(*newval);
                               1013            3714 :     return true;
                               1014                 : }
                               1015                 : 
                               1016                 : 
                               1017                 : /*
                               1018                 :  * MISCELLANEOUS
                               1019                 :  */
                               1020                 : 
                               1021                 : /*
                               1022                 :  * GUC check_hook for application_name
                               1023                 :  */
                               1024                 : bool
                               1025           12138 : check_application_name(char **newval, void **extra, GucSource source)
                               1026                 : {
                               1027                 :     char       *clean;
                               1028                 :     char       *ret;
                               1029                 : 
                               1030                 :     /* Only allow clean ASCII chars in the application name */
                               1031           12138 :     clean = pg_clean_ascii(*newval, MCXT_ALLOC_NO_OOM);
                               1032           12138 :     if (!clean)
  208 tgl                      1033 UNC           0 :         return false;
                               1034                 : 
  190 peter                    1035 GNC       12138 :     ret = guc_strdup(WARNING, clean);
                               1036           12138 :     if (!ret)
                               1037                 :     {
  190 peter                    1038 UNC           0 :         pfree(clean);
  208 tgl                      1039               0 :         return false;
                               1040                 :     }
                               1041                 : 
  190 peter                    1042 GNC       12138 :     pfree(clean);
                               1043           12138 :     *newval = ret;
  208 tgl                      1044           12138 :     return true;
                               1045                 : }
                               1046                 : 
                               1047                 : /*
                               1048                 :  * GUC assign_hook for application_name
                               1049                 :  */
                               1050                 : void
                               1051           12124 : assign_application_name(const char *newval, void *extra)
                               1052                 : {
                               1053                 :     /* Update the pg_stat_activity view */
                               1054           12124 :     pgstat_report_appname(newval);
                               1055           12124 : }
                               1056                 : 
                               1057                 : /*
                               1058                 :  * GUC check_hook for cluster_name
                               1059                 :  */
                               1060                 : bool
                               1061            2357 : check_cluster_name(char **newval, void **extra, GucSource source)
                               1062                 : {
                               1063                 :     char       *clean;
                               1064                 :     char       *ret;
                               1065                 : 
                               1066                 :     /* Only allow clean ASCII chars in the cluster name */
                               1067            2357 :     clean = pg_clean_ascii(*newval, MCXT_ALLOC_NO_OOM);
                               1068            2357 :     if (!clean)
  208 tgl                      1069 UNC           0 :         return false;
                               1070                 : 
  190 peter                    1071 GNC        2357 :     ret = guc_strdup(WARNING, clean);
                               1072            2357 :     if (!ret)
                               1073                 :     {
  190 peter                    1074 UNC           0 :         pfree(clean);
  208 tgl                      1075               0 :         return false;
                               1076                 :     }
                               1077                 : 
  190 peter                    1078 GNC        2357 :     pfree(clean);
                               1079            2357 :     *newval = ret;
  208 tgl                      1080            2357 :     return true;
                               1081                 : }
                               1082                 : 
                               1083                 : /*
                               1084                 :  * GUC assign_hook for maintenance_io_concurrency
                               1085                 :  */
                               1086                 : void
                               1087            1857 : assign_maintenance_io_concurrency(int newval, void *extra)
                               1088                 : {
                               1089                 : #ifdef USE_PREFETCH
                               1090                 :     /*
                               1091                 :      * Reconfigure recovery prefetching, because a setting it depends on
                               1092                 :      * changed.
                               1093                 :      */
                               1094            1857 :     maintenance_io_concurrency = newval;
                               1095            1857 :     if (AmStartupProcess())
  208 tgl                      1096 UNC           0 :         XLogPrefetchReconfigure();
                               1097                 : #endif
  208 tgl                      1098 GNC        1857 : }
                               1099                 : 
                               1100                 : 
                               1101                 : /*
                               1102                 :  * These show hooks just exist because we want to show the values in octal.
                               1103                 :  */
                               1104                 : 
                               1105                 : /*
                               1106                 :  * GUC show_hook for data_directory_mode
                               1107                 :  */
                               1108                 : const char *
                               1109            1382 : show_data_directory_mode(void)
                               1110                 : {
                               1111                 :     static char buf[12];
                               1112                 : 
                               1113            1382 :     snprintf(buf, sizeof(buf), "%04o", data_directory_mode);
                               1114            1382 :     return buf;
                               1115                 : }
                               1116                 : 
                               1117                 : /*
                               1118                 :  * GUC show_hook for log_file_mode
                               1119                 :  */
                               1120                 : const char *
                               1121            1088 : show_log_file_mode(void)
                               1122                 : {
                               1123                 :     static char buf[12];
                               1124                 : 
                               1125            1088 :     snprintf(buf, sizeof(buf), "%04o", Log_file_mode);
                               1126            1088 :     return buf;
                               1127                 : }
                               1128                 : 
                               1129                 : /*
                               1130                 :  * GUC show_hook for unix_socket_permissions
                               1131                 :  */
                               1132                 : const char *
                               1133            1088 : show_unix_socket_permissions(void)
                               1134                 : {
                               1135                 :     static char buf[12];
                               1136                 : 
                               1137            1088 :     snprintf(buf, sizeof(buf), "%04o", Unix_socket_permissions);
                               1138            1088 :     return buf;
                               1139                 : }
                               1140                 : 
                               1141                 : 
                               1142                 : /*
                               1143                 :  * These check hooks do nothing more than reject non-default settings
                               1144                 :  * in builds that don't support them.
                               1145                 :  */
                               1146                 : 
                               1147                 : bool
                               1148            1857 : check_bonjour(bool *newval, void **extra, GucSource source)
                               1149                 : {
                               1150                 : #ifndef USE_BONJOUR
                               1151            1857 :     if (*newval)
                               1152                 :     {
  208 tgl                      1153 UNC           0 :         GUC_check_errmsg("Bonjour is not supported by this build");
                               1154               0 :         return false;
                               1155                 :     }
                               1156                 : #endif
  208 tgl                      1157 GNC        1857 :     return true;
                               1158                 : }
                               1159                 : 
                               1160                 : bool
                               1161            1863 : check_default_with_oids(bool *newval, void **extra, GucSource source)
                               1162                 : {
                               1163            1863 :     if (*newval)
                               1164                 :     {
                               1165                 :         /* check the GUC's definition for an explanation */
                               1166               3 :         GUC_check_errcode(ERRCODE_FEATURE_NOT_SUPPORTED);
                               1167               3 :         GUC_check_errmsg("tables declared WITH OIDS are not supported");
                               1168                 : 
                               1169               3 :         return false;
                               1170                 :     }
                               1171                 : 
                               1172            1860 :     return true;
                               1173                 : }
                               1174                 : 
                               1175                 : bool
                               1176            2154 : check_effective_io_concurrency(int *newval, void **extra, GucSource source)
                               1177                 : {
                               1178                 : #ifndef USE_PREFETCH
                               1179                 :     if (*newval != 0)
                               1180                 :     {
                               1181                 :         GUC_check_errdetail("effective_io_concurrency must be set to 0 on platforms that lack posix_fadvise().");
                               1182                 :         return false;
                               1183                 :     }
                               1184                 : #endif                          /* USE_PREFETCH */
                               1185            2154 :     return true;
                               1186                 : }
                               1187                 : 
                               1188                 : bool
                               1189            1857 : check_maintenance_io_concurrency(int *newval, void **extra, GucSource source)
                               1190                 : {
                               1191                 : #ifndef USE_PREFETCH
                               1192                 :     if (*newval != 0)
                               1193                 :     {
                               1194                 :         GUC_check_errdetail("maintenance_io_concurrency must be set to 0 on platforms that lack posix_fadvise().");
                               1195                 :         return false;
                               1196                 :     }
                               1197                 : #endif                          /* USE_PREFETCH */
                               1198            1857 :     return true;
                               1199                 : }
                               1200                 : 
                               1201                 : bool
                               1202            1883 : check_ssl(bool *newval, void **extra, GucSource source)
                               1203                 : {
                               1204                 : #ifndef USE_SSL
                               1205                 :     if (*newval)
                               1206                 :     {
                               1207                 :         GUC_check_errmsg("SSL is not supported by this build");
                               1208                 :         return false;
                               1209                 :     }
                               1210                 : #endif
                               1211            1883 :     return true;
                               1212                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a