LCOV - differential code coverage report
Current view: top level - src/backend/utils/misc - guc_funcs.c (source / functions) Coverage Total Hit UNC GNC
Current: Differential Code Coverage HEAD vs 15 Lines: 85.4 % 378 323 55 323
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 16 16 16
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (60,120] days: 100.0 % 17 17 17
Legend: Lines: hit not hit (120,180] days: 66.7 % 12 8 4 8
(180,240] days: 85.4 % 349 298 51 298
Function coverage date bins:
(60,120] days: 100.0 % 2 2 2
(180,240] days: 100.0 % 14 14 14

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*--------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * guc_funcs.c
                                  4                 :  *
                                  5                 :  * SQL commands and SQL-accessible functions related to GUC variables.
                                  6                 :  *
                                  7                 :  *
                                  8                 :  * Copyright (c) 2000-2023, PostgreSQL Global Development Group
                                  9                 :  * Written by Peter Eisentraut <peter_e@gmx.net>.
                                 10                 :  *
                                 11                 :  * IDENTIFICATION
                                 12                 :  *    src/backend/utils/misc/guc_funcs.c
                                 13                 :  *
                                 14                 :  *--------------------------------------------------------------------
                                 15                 :  */
                                 16                 : #include "postgres.h"
                                 17                 : 
                                 18                 : #include <sys/stat.h>
                                 19                 : #include <unistd.h>
                                 20                 : 
                                 21                 : #include "access/xact.h"
                                 22                 : #include "catalog/objectaccess.h"
                                 23                 : #include "catalog/pg_authid.h"
                                 24                 : #include "catalog/pg_parameter_acl.h"
                                 25                 : #include "funcapi.h"
                                 26                 : #include "guc_internal.h"
                                 27                 : #include "parser/parse_type.h"
                                 28                 : #include "utils/acl.h"
                                 29                 : #include "utils/backend_status.h"
                                 30                 : #include "utils/builtins.h"
                                 31                 : #include "utils/guc_tables.h"
                                 32                 : #include "utils/snapmgr.h"
                                 33                 : 
                                 34                 : static char *flatten_set_variable_args(const char *name, List *args);
                                 35                 : static void ShowGUCConfigOption(const char *name, DestReceiver *dest);
                                 36                 : static void ShowAllGUCConfig(DestReceiver *dest);
                                 37                 : 
                                 38                 : 
                                 39                 : /*
                                 40                 :  * SET command
                                 41                 :  */
                                 42                 : void
  208 tgl                        43 GNC       16236 : ExecSetVariableStmt(VariableSetStmt *stmt, bool isTopLevel)
                                 44                 : {
                                 45           16236 :     GucAction   action = stmt->is_local ? GUC_ACTION_LOCAL : GUC_ACTION_SET;
                                 46                 : 
                                 47                 :     /*
                                 48                 :      * Workers synchronize these parameters at the start of the parallel
                                 49                 :      * operation; then, we block SET during the operation.
                                 50                 :      */
                                 51           16236 :     if (IsInParallelMode())
  208 tgl                        52 UNC           0 :         ereport(ERROR,
                                 53                 :                 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
                                 54                 :                  errmsg("cannot set parameters during a parallel operation")));
                                 55                 : 
  208 tgl                        56 GNC       16236 :     switch (stmt->kind)
                                 57                 :     {
                                 58           14164 :         case VAR_SET_VALUE:
                                 59                 :         case VAR_SET_CURRENT:
                                 60           14164 :             if (stmt->is_local)
                                 61             492 :                 WarnNoTransactionBlock(isTopLevel, "SET LOCAL");
                                 62           28328 :             (void) set_config_option(stmt->name,
                                 63           14164 :                                      ExtractSetVariableArgs(stmt),
                                 64           14164 :                                      (superuser() ? PGC_SUSET : PGC_USERSET),
                                 65                 :                                      PGC_S_SESSION,
                                 66                 :                                      action, true, 0, false);
                                 67           14105 :             break;
                                 68             241 :         case VAR_SET_MULTI:
                                 69                 : 
                                 70                 :             /*
                                 71                 :              * Special-case SQL syntaxes.  The TRANSACTION and SESSION
                                 72                 :              * CHARACTERISTICS cases effectively set more than one variable
                                 73                 :              * per statement.  TRANSACTION SNAPSHOT only takes one argument,
                                 74                 :              * but we put it here anyway since it's a special case and not
                                 75                 :              * related to any GUC variable.
                                 76                 :              */
                                 77             241 :             if (strcmp(stmt->name, "TRANSACTION") == 0)
                                 78                 :             {
                                 79                 :                 ListCell   *head;
                                 80                 : 
                                 81             217 :                 WarnNoTransactionBlock(isTopLevel, "SET TRANSACTION");
                                 82                 : 
                                 83             579 :                 foreach(head, stmt->args)
                                 84                 :                 {
                                 85             372 :                     DefElem    *item = (DefElem *) lfirst(head);
                                 86                 : 
                                 87             372 :                     if (strcmp(item->defname, "transaction_isolation") == 0)
                                 88             166 :                         SetPGVariable("transaction_isolation",
                                 89             166 :                                       list_make1(item->arg), stmt->is_local);
                                 90             206 :                     else if (strcmp(item->defname, "transaction_read_only") == 0)
                                 91             203 :                         SetPGVariable("transaction_read_only",
                                 92             203 :                                       list_make1(item->arg), stmt->is_local);
                                 93               3 :                     else if (strcmp(item->defname, "transaction_deferrable") == 0)
                                 94               3 :                         SetPGVariable("transaction_deferrable",
                                 95               3 :                                       list_make1(item->arg), stmt->is_local);
                                 96                 :                     else
  208 tgl                        97 UNC           0 :                         elog(ERROR, "unexpected SET TRANSACTION element: %s",
                                 98                 :                              item->defname);
                                 99                 :                 }
                                100                 :             }
  208 tgl                       101 GNC          24 :             else if (strcmp(stmt->name, "SESSION CHARACTERISTICS") == 0)
                                102                 :             {
                                103                 :                 ListCell   *head;
                                104                 : 
                                105              12 :                 foreach(head, stmt->args)
                                106                 :                 {
                                107               6 :                     DefElem    *item = (DefElem *) lfirst(head);
                                108                 : 
                                109               6 :                     if (strcmp(item->defname, "transaction_isolation") == 0)
  208 tgl                       110 UNC           0 :                         SetPGVariable("default_transaction_isolation",
                                111               0 :                                       list_make1(item->arg), stmt->is_local);
  208 tgl                       112 GNC           6 :                     else if (strcmp(item->defname, "transaction_read_only") == 0)
                                113               6 :                         SetPGVariable("default_transaction_read_only",
                                114               6 :                                       list_make1(item->arg), stmt->is_local);
  208 tgl                       115 UNC           0 :                     else if (strcmp(item->defname, "transaction_deferrable") == 0)
                                116               0 :                         SetPGVariable("default_transaction_deferrable",
                                117               0 :                                       list_make1(item->arg), stmt->is_local);
                                118                 :                     else
                                119               0 :                         elog(ERROR, "unexpected SET SESSION element: %s",
                                120                 :                              item->defname);
                                121                 :                 }
                                122                 :             }
  208 tgl                       123 GNC          18 :             else if (strcmp(stmt->name, "TRANSACTION SNAPSHOT") == 0)
                                124                 :             {
                                125              18 :                 A_Const    *con = linitial_node(A_Const, stmt->args);
                                126                 : 
                                127              18 :                 if (stmt->is_local)
  208 tgl                       128 UNC           0 :                     ereport(ERROR,
                                129                 :                             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                                130                 :                              errmsg("SET LOCAL TRANSACTION SNAPSHOT is not implemented")));
                                131                 : 
  208 tgl                       132 GNC          18 :                 WarnNoTransactionBlock(isTopLevel, "SET TRANSACTION");
                                133              18 :                 ImportSnapshot(strVal(&con->val));
                                134                 :             }
                                135                 :             else
  208 tgl                       136 UNC           0 :                 elog(ERROR, "unexpected SET MULTI element: %s",
                                137                 :                      stmt->name);
  208 tgl                       138 GNC         231 :             break;
                                139              71 :         case VAR_SET_DEFAULT:
                                140              71 :             if (stmt->is_local)
                                141               1 :                 WarnNoTransactionBlock(isTopLevel, "SET LOCAL");
                                142                 :             /* fall through */
                                143                 :         case VAR_RESET:
                                144            1831 :             (void) set_config_option(stmt->name,
                                145                 :                                      NULL,
                                146            1831 :                                      (superuser() ? PGC_SUSET : PGC_USERSET),
                                147                 :                                      PGC_S_SESSION,
                                148                 :                                      action, true, 0, false);
                                149            1816 :             break;
  208 tgl                       150 UNC           0 :         case VAR_RESET_ALL:
                                151               0 :             ResetAllOptions();
                                152               0 :             break;
                                153                 :     }
                                154                 : 
                                155                 :     /* Invoke the post-alter hook for setting this GUC variable, by name. */
  208 tgl                       156 GNC       16152 :     InvokeObjectPostAlterHookArgStr(ParameterAclRelationId, stmt->name,
                                157                 :                                     ACL_SET, stmt->kind, false);
                                158           16151 : }
                                159                 : 
                                160                 : /*
                                161                 :  * Get the value to assign for a VariableSetStmt, or NULL if it's RESET.
                                162                 :  * The result is palloc'd.
                                163                 :  *
                                164                 :  * This is exported for use by actions such as ALTER ROLE SET.
                                165                 :  */
                                166                 : char *
                                167           14822 : ExtractSetVariableArgs(VariableSetStmt *stmt)
                                168                 : {
                                169                 : 
                                170           14822 :     switch (stmt->kind)
                                171                 :     {
                                172           14808 :         case VAR_SET_VALUE:
                                173           14808 :             return flatten_set_variable_args(stmt->name, stmt->args);
  208 tgl                       174 UNC           0 :         case VAR_SET_CURRENT:
                                175                 :             {
                                176                 :                 struct config_generic *record;
                                177                 :                 char       *result;
                                178                 : 
  121 akorotkov                 179               0 :                 result = GetConfigOptionByName(stmt->name, NULL, false);
                                180               0 :                 record = find_option(stmt->name, false, false, ERROR);
                                181               0 :                 stmt->user_set = (record->scontext == PGC_USERSET);
                                182                 : 
                                183               0 :                 return result;
                                184                 :             }
  208 tgl                       185 GNC          14 :         default:
                                186              14 :             return NULL;
                                187                 :     }
                                188                 : }
                                189                 : 
                                190                 : /*
                                191                 :  * flatten_set_variable_args
                                192                 :  *      Given a parsenode List as emitted by the grammar for SET,
                                193                 :  *      convert to the flat string representation used by GUC.
                                194                 :  *
                                195                 :  * We need to be told the name of the variable the args are for, because
                                196                 :  * the flattening rules vary (ugh).
                                197                 :  *
                                198                 :  * The result is NULL if args is NIL (i.e., SET ... TO DEFAULT), otherwise
                                199                 :  * a palloc'd string.
                                200                 :  */
                                201                 : static char *
                                202           18649 : flatten_set_variable_args(const char *name, List *args)
                                203                 : {
                                204                 :     struct config_generic *record;
                                205                 :     int         flags;
                                206                 :     StringInfoData buf;
                                207                 :     ListCell   *l;
                                208                 : 
                                209                 :     /* Fast path if just DEFAULT */
                                210           18649 :     if (args == NIL)
                                211               3 :         return NULL;
                                212                 : 
                                213                 :     /*
                                214                 :      * Get flags for the variable; if it's not known, use default flags.
                                215                 :      * (Caller might throw error later, but not our business to do so here.)
                                216                 :      */
                                217           18646 :     record = find_option(name, false, true, WARNING);
                                218           18646 :     if (record)
                                219           18613 :         flags = record->flags;
                                220                 :     else
                                221              33 :         flags = 0;
                                222                 : 
                                223                 :     /* Complain if list input and non-list variable */
                                224           36112 :     if ((flags & GUC_LIST_INPUT) == 0 &&
                                225           17466 :         list_length(args) != 1)
  208 tgl                       226 UNC           0 :         ereport(ERROR,
                                227                 :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                228                 :                  errmsg("SET %s takes only one argument", name)));
                                229                 : 
  208 tgl                       230 GNC       18646 :     initStringInfo(&buf);
                                231                 : 
                                232                 :     /*
                                233                 :      * Each list member may be a plain A_Const node, or an A_Const within a
                                234                 :      * TypeCast; the latter case is supported only for ConstInterval arguments
                                235                 :      * (for SET TIME ZONE).
                                236                 :      */
                                237           37362 :     foreach(l, args)
                                238                 :     {
                                239           18716 :         Node       *arg = (Node *) lfirst(l);
                                240                 :         char       *val;
                                241           18716 :         TypeName   *typeName = NULL;
                                242                 :         A_Const    *con;
                                243                 : 
                                244           18716 :         if (l != list_head(args))
                                245              70 :             appendStringInfoString(&buf, ", ");
                                246                 : 
                                247           18716 :         if (IsA(arg, TypeCast))
                                248                 :         {
  208 tgl                       249 UNC           0 :             TypeCast   *tc = (TypeCast *) arg;
                                250                 : 
                                251               0 :             arg = tc->arg;
                                252               0 :             typeName = tc->typeName;
                                253                 :         }
                                254                 : 
  208 tgl                       255 GNC       18716 :         if (!IsA(arg, A_Const))
  208 tgl                       256 UNC           0 :             elog(ERROR, "unrecognized node type: %d", (int) nodeTag(arg));
  208 tgl                       257 GNC       18716 :         con = (A_Const *) arg;
                                258                 : 
                                259           18716 :         switch (nodeTag(&con->val))
                                260                 :         {
                                261            7237 :             case T_Integer:
                                262            7237 :                 appendStringInfo(&buf, "%d", intVal(&con->val));
                                263            7237 :                 break;
                                264             109 :             case T_Float:
                                265                 :                 /* represented as a string, so just copy it */
                                266             109 :                 appendStringInfoString(&buf, castNode(Float, &con->val)->fval);
                                267             109 :                 break;
                                268           11370 :             case T_String:
                                269           11370 :                 val = strVal(&con->val);
                                270           11370 :                 if (typeName != NULL)
                                271                 :                 {
                                272                 :                     /*
                                273                 :                      * Must be a ConstInterval argument for TIME ZONE. Coerce
                                274                 :                      * to interval and back to normalize the value and account
                                275                 :                      * for any typmod.
                                276                 :                      */
                                277                 :                     Oid         typoid;
                                278                 :                     int32       typmod;
                                279                 :                     Datum       interval;
                                280                 :                     char       *intervalout;
                                281                 : 
  208 tgl                       282 UNC           0 :                     typenameTypeIdAndMod(NULL, typeName, &typoid, &typmod);
                                283               0 :                     Assert(typoid == INTERVALOID);
                                284                 : 
                                285                 :                     interval =
                                286               0 :                         DirectFunctionCall3(interval_in,
                                287                 :                                             CStringGetDatum(val),
                                288                 :                                             ObjectIdGetDatum(InvalidOid),
                                289                 :                                             Int32GetDatum(typmod));
                                290                 : 
                                291                 :                     intervalout =
                                292               0 :                         DatumGetCString(DirectFunctionCall1(interval_out,
                                293                 :                                                             interval));
                                294               0 :                     appendStringInfo(&buf, "INTERVAL '%s'", intervalout);
                                295                 :                 }
                                296                 :                 else
                                297                 :                 {
                                298                 :                     /*
                                299                 :                      * Plain string literal or identifier.  For quote mode,
                                300                 :                      * quote it if it's not a vanilla identifier.
                                301                 :                      */
  208 tgl                       302 GNC       11370 :                     if (flags & GUC_LIST_QUOTE)
                                303             867 :                         appendStringInfoString(&buf, quote_identifier(val));
                                304                 :                     else
                                305           10503 :                         appendStringInfoString(&buf, val);
                                306                 :                 }
                                307           11370 :                 break;
  208 tgl                       308 UNC           0 :             default:
                                309               0 :                 elog(ERROR, "unrecognized node type: %d",
                                310                 :                      (int) nodeTag(&con->val));
                                311                 :                 break;
                                312                 :         }
                                313                 :     }
                                314                 : 
  208 tgl                       315 GNC       18646 :     return buf.data;
                                316                 : }
                                317                 : 
                                318                 : /*
                                319                 :  * SetPGVariable - SET command exported as an easily-C-callable function.
                                320                 :  *
                                321                 :  * This provides access to SET TO value, as well as SET TO DEFAULT (expressed
                                322                 :  * by passing args == NIL), but not SET FROM CURRENT functionality.
                                323                 :  */
                                324                 : void
                                325            3841 : SetPGVariable(const char *name, List *args, bool is_local)
                                326                 : {
                                327            3841 :     char       *argstring = flatten_set_variable_args(name, args);
                                328                 : 
                                329                 :     /* Note SET DEFAULT (argstring == NULL) is equivalent to RESET */
                                330            3841 :     (void) set_config_option(name,
                                331                 :                              argstring,
                                332            3841 :                              (superuser() ? PGC_SUSET : PGC_USERSET),
                                333                 :                              PGC_S_SESSION,
                                334                 :                              is_local ? GUC_ACTION_LOCAL : GUC_ACTION_SET,
                                335                 :                              true, 0, false);
                                336            3831 : }
                                337                 : 
                                338                 : /*
                                339                 :  * SET command wrapped as a SQL callable function.
                                340                 :  */
                                341                 : Datum
                                342            1771 : set_config_by_name(PG_FUNCTION_ARGS)
                                343                 : {
                                344                 :     char       *name;
                                345                 :     char       *value;
                                346                 :     char       *new_value;
                                347                 :     bool        is_local;
                                348                 : 
                                349            1771 :     if (PG_ARGISNULL(0))
  208 tgl                       350 UNC           0 :         ereport(ERROR,
                                351                 :                 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
                                352                 :                  errmsg("SET requires parameter name")));
                                353                 : 
                                354                 :     /* Get the GUC variable name */
  208 tgl                       355 GNC        1771 :     name = TextDatumGetCString(PG_GETARG_DATUM(0));
                                356                 : 
                                357                 :     /* Get the desired value or set to NULL for a reset request */
                                358            1771 :     if (PG_ARGISNULL(1))
  208 tgl                       359 UNC           0 :         value = NULL;
                                360                 :     else
  208 tgl                       361 GNC        1771 :         value = TextDatumGetCString(PG_GETARG_DATUM(1));
                                362                 : 
                                363                 :     /*
                                364                 :      * Get the desired state of is_local. Default to false if provided value
                                365                 :      * is NULL
                                366                 :      */
                                367            1771 :     if (PG_ARGISNULL(2))
  208 tgl                       368 UNC           0 :         is_local = false;
                                369                 :     else
  208 tgl                       370 GNC        1771 :         is_local = PG_GETARG_BOOL(2);
                                371                 : 
                                372                 :     /* Note SET DEFAULT (argstring == NULL) is equivalent to RESET */
                                373            1771 :     (void) set_config_option(name,
                                374                 :                              value,
                                375            1771 :                              (superuser() ? PGC_SUSET : PGC_USERSET),
                                376                 :                              PGC_S_SESSION,
                                377                 :                              is_local ? GUC_ACTION_LOCAL : GUC_ACTION_SET,
                                378                 :                              true, 0, false);
                                379                 : 
                                380                 :     /* get the new current value */
                                381            1770 :     new_value = GetConfigOptionByName(name, NULL, false);
                                382                 : 
                                383                 :     /* Convert return string to text */
                                384            1770 :     PG_RETURN_TEXT_P(cstring_to_text(new_value));
                                385                 : }
                                386                 : 
                                387                 : 
                                388                 : /*
                                389                 :  * SHOW command
                                390                 :  */
                                391                 : void
                                392             817 : GetPGVariable(const char *name, DestReceiver *dest)
                                393                 : {
                                394             817 :     if (guc_name_compare(name, "all") == 0)
                                395               2 :         ShowAllGUCConfig(dest);
                                396                 :     else
                                397             815 :         ShowGUCConfigOption(name, dest);
                                398             817 : }
                                399                 : 
                                400                 : /*
                                401                 :  * Get a tuple descriptor for SHOW's result
                                402                 :  */
                                403                 : TupleDesc
                                404             381 : GetPGVariableResultDesc(const char *name)
                                405                 : {
                                406                 :     TupleDesc   tupdesc;
                                407                 : 
                                408             381 :     if (guc_name_compare(name, "all") == 0)
                                409                 :     {
                                410                 :         /* need a tuple descriptor representing three TEXT columns */
  208 tgl                       411 UNC           0 :         tupdesc = CreateTemplateTupleDesc(3);
                                412               0 :         TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
                                413                 :                            TEXTOID, -1, 0);
                                414               0 :         TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting",
                                415                 :                            TEXTOID, -1, 0);
                                416               0 :         TupleDescInitEntry(tupdesc, (AttrNumber) 3, "description",
                                417                 :                            TEXTOID, -1, 0);
                                418                 :     }
                                419                 :     else
                                420                 :     {
                                421                 :         const char *varname;
                                422                 : 
                                423                 :         /* Get the canonical spelling of name */
  208 tgl                       424 GNC         381 :         (void) GetConfigOptionByName(name, &varname, false);
                                425                 : 
                                426                 :         /* need a tuple descriptor representing a single TEXT column */
                                427             368 :         tupdesc = CreateTemplateTupleDesc(1);
                                428             368 :         TupleDescInitEntry(tupdesc, (AttrNumber) 1, varname,
                                429                 :                            TEXTOID, -1, 0);
                                430                 :     }
                                431             368 :     return tupdesc;
                                432                 : }
                                433                 : 
                                434                 : /*
                                435                 :  * SHOW one variable
                                436                 :  */
                                437                 : static void
                                438             815 : ShowGUCConfigOption(const char *name, DestReceiver *dest)
                                439                 : {
                                440                 :     TupOutputState *tstate;
                                441                 :     TupleDesc   tupdesc;
                                442                 :     const char *varname;
                                443                 :     char       *value;
                                444                 : 
                                445                 :     /* Get the value and canonical spelling of name */
                                446             815 :     value = GetConfigOptionByName(name, &varname, false);
                                447                 : 
                                448                 :     /* need a tuple descriptor representing a single TEXT column */
                                449             815 :     tupdesc = CreateTemplateTupleDesc(1);
                                450             815 :     TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, varname,
                                451                 :                               TEXTOID, -1, 0);
                                452                 : 
                                453                 :     /* prepare for projection of tuples */
                                454             815 :     tstate = begin_tup_output_tupdesc(dest, tupdesc, &TTSOpsVirtual);
                                455                 : 
                                456                 :     /* Send it */
                                457             815 :     do_text_output_oneline(tstate, value);
                                458                 : 
                                459             815 :     end_tup_output(tstate);
                                460             815 : }
                                461                 : 
                                462                 : /*
                                463                 :  * SHOW ALL command
                                464                 :  */
                                465                 : static void
                                466               2 : ShowAllGUCConfig(DestReceiver *dest)
                                467                 : {
                                468                 :     struct config_generic **guc_vars;
                                469                 :     int         num_vars;
                                470                 :     TupOutputState *tstate;
                                471                 :     TupleDesc   tupdesc;
                                472                 :     Datum       values[3];
                                473               2 :     bool        isnull[3] = {false, false, false};
                                474                 : 
                                475                 :     /* collect the variables, in sorted order */
  177                           476               2 :     guc_vars = get_guc_variables(&num_vars);
                                477                 : 
                                478                 :     /* need a tuple descriptor representing three TEXT columns */
  208                           479               2 :     tupdesc = CreateTemplateTupleDesc(3);
                                480               2 :     TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "name",
                                481                 :                               TEXTOID, -1, 0);
                                482               2 :     TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "setting",
                                483                 :                               TEXTOID, -1, 0);
                                484               2 :     TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 3, "description",
                                485                 :                               TEXTOID, -1, 0);
                                486                 : 
                                487                 :     /* prepare for projection of tuples */
                                488               2 :     tstate = begin_tup_output_tupdesc(dest, tupdesc, &TTSOpsVirtual);
                                489                 : 
  177                           490             738 :     for (int i = 0; i < num_vars; i++)
                                491                 :     {
                                492             736 :         struct config_generic *conf = guc_vars[i];
                                493                 :         char       *setting;
                                494                 : 
                                495                 :         /* skip if marked NO_SHOW_ALL */
   72                           496             736 :         if (conf->flags & GUC_NO_SHOW_ALL)
                                497              12 :             continue;
                                498                 : 
                                499                 :         /* return only options visible to the current user */
                                500             724 :         if (!ConfigOptionIsVisible(conf))
  208 tgl                       501 UNC           0 :             continue;
                                502                 : 
                                503                 :         /* assign to the values array */
  208 tgl                       504 GNC         724 :         values[0] = PointerGetDatum(cstring_to_text(conf->name));
                                505                 : 
                                506             724 :         setting = ShowGUCOption(conf, true);
                                507             724 :         if (setting)
                                508                 :         {
                                509             724 :             values[1] = PointerGetDatum(cstring_to_text(setting));
                                510             724 :             isnull[1] = false;
                                511                 :         }
                                512                 :         else
                                513                 :         {
  208 tgl                       514 UNC           0 :             values[1] = PointerGetDatum(NULL);
                                515               0 :             isnull[1] = true;
                                516                 :         }
                                517                 : 
  208 tgl                       518 GNC         724 :         if (conf->short_desc)
                                519                 :         {
                                520             724 :             values[2] = PointerGetDatum(cstring_to_text(conf->short_desc));
                                521             724 :             isnull[2] = false;
                                522                 :         }
                                523                 :         else
                                524                 :         {
  208 tgl                       525 UNC           0 :             values[2] = PointerGetDatum(NULL);
                                526               0 :             isnull[2] = true;
                                527                 :         }
                                528                 : 
                                529                 :         /* send it to dest */
  208 tgl                       530 GNC         724 :         do_tup_output(tstate, values, isnull);
                                531                 : 
                                532                 :         /* clean up */
                                533             724 :         pfree(DatumGetPointer(values[0]));
                                534             724 :         if (setting)
                                535                 :         {
                                536             724 :             pfree(setting);
                                537             724 :             pfree(DatumGetPointer(values[1]));
                                538                 :         }
                                539             724 :         if (conf->short_desc)
                                540             724 :             pfree(DatumGetPointer(values[2]));
                                541                 :     }
                                542                 : 
                                543               2 :     end_tup_output(tstate);
                                544               2 : }
                                545                 : 
                                546                 : /*
                                547                 :  * Return some of the flags associated to the specified GUC in the shape of
                                548                 :  * a text array, and NULL if it does not exist.  An empty array is returned
                                549                 :  * if the GUC exists without any meaningful flags to show.
                                550                 :  */
                                551                 : Datum
                                552            1832 : pg_settings_get_flags(PG_FUNCTION_ARGS)
                                553                 : {
                                554                 : #define MAX_GUC_FLAGS   6
                                555            1832 :     char       *varname = TextDatumGetCString(PG_GETARG_DATUM(0));
                                556                 :     struct config_generic *record;
                                557            1832 :     int         cnt = 0;
                                558                 :     Datum       flags[MAX_GUC_FLAGS];
                                559                 :     ArrayType  *a;
                                560                 : 
                                561            1832 :     record = find_option(varname, false, true, ERROR);
                                562                 : 
                                563                 :     /* return NULL if no such variable */
                                564            1832 :     if (record == NULL)
                                565               3 :         PG_RETURN_NULL();
                                566                 : 
                                567            1829 :     if (record->flags & GUC_EXPLAIN)
                                568             290 :         flags[cnt++] = CStringGetTextDatum("EXPLAIN");
  194                           569            1829 :     if (record->flags & GUC_NO_RESET)
                                570              15 :         flags[cnt++] = CStringGetTextDatum("NO_RESET");
  208                           571            1829 :     if (record->flags & GUC_NO_RESET_ALL)
                                572              15 :         flags[cnt++] = CStringGetTextDatum("NO_RESET_ALL");
                                573            1829 :     if (record->flags & GUC_NO_SHOW_ALL)
  208 tgl                       574 UNC           0 :         flags[cnt++] = CStringGetTextDatum("NO_SHOW_ALL");
  208 tgl                       575 GNC        1829 :     if (record->flags & GUC_NOT_IN_SAMPLE)
                                576             245 :         flags[cnt++] = CStringGetTextDatum("NOT_IN_SAMPLE");
                                577            1829 :     if (record->flags & GUC_RUNTIME_COMPUTED)
                                578              25 :         flags[cnt++] = CStringGetTextDatum("RUNTIME_COMPUTED");
                                579                 : 
                                580            1829 :     Assert(cnt <= MAX_GUC_FLAGS);
                                581                 : 
                                582                 :     /* Returns the record as Datum */
                                583            1829 :     a = construct_array_builtin(flags, cnt, TEXTOID);
                                584            1829 :     PG_RETURN_ARRAYTYPE_P(a);
                                585                 : }
                                586                 : 
                                587                 : /*
                                588                 :  * Return whether or not the GUC variable is visible to the current user.
                                589                 :  */
                                590                 : bool
   72                           591          403330 : ConfigOptionIsVisible(struct config_generic *conf)
                                592                 : {
                                593          403330 :     if ((conf->flags & GUC_SUPERUSER_ONLY) &&
                                594           21787 :         !has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_SETTINGS))
                                595               1 :         return false;
                                596                 :     else
                                597          403329 :         return true;
                                598                 : }
                                599                 : 
                                600                 : /*
                                601                 :  * Extract fields to show in pg_settings for given variable.
                                602                 :  */
                                603                 : static void
                                604          398869 : GetConfigOptionValues(struct config_generic *conf, const char **values)
                                605                 : {
                                606                 :     char        buffer[256];
                                607                 : 
                                608                 :     /* first get the generic attributes */
                                609                 : 
                                610                 :     /* name */
  208                           611          398869 :     values[0] = conf->name;
                                612                 : 
                                613                 :     /* setting: use ShowGUCOption in order to avoid duplicating the logic */
                                614          398869 :     values[1] = ShowGUCOption(conf, false);
                                615                 : 
                                616                 :     /* unit, if any (NULL is fine) */
                                617          398869 :     values[2] = get_config_unit_name(conf->flags);
                                618                 : 
                                619                 :     /* group */
                                620          398869 :     values[3] = _(config_group_names[conf->group]);
                                621                 : 
                                622                 :     /* short_desc */
                                623          398869 :     values[4] = conf->short_desc != NULL ? _(conf->short_desc) : NULL;
                                624                 : 
                                625                 :     /* extra_desc */
                                626          398869 :     values[5] = conf->long_desc != NULL ? _(conf->long_desc) : NULL;
                                627                 : 
                                628                 :     /* context */
                                629          398869 :     values[6] = GucContext_Names[conf->context];
                                630                 : 
                                631                 :     /* vartype */
                                632          398869 :     values[7] = config_type_names[conf->vartype];
                                633                 : 
                                634                 :     /* source */
                                635          398869 :     values[8] = GucSource_Names[conf->source];
                                636                 : 
                                637                 :     /* now get the type specific attributes */
                                638          398869 :     switch (conf->vartype)
                                639                 :     {
                                640          113029 :         case PGC_BOOL:
                                641                 :             {
                                642          113029 :                 struct config_bool *lconf = (struct config_bool *) conf;
                                643                 : 
                                644                 :                 /* min_val */
                                645          113029 :                 values[9] = NULL;
                                646                 : 
                                647                 :                 /* max_val */
                                648          113029 :                 values[10] = NULL;
                                649                 : 
                                650                 :                 /* enumvals */
                                651          113029 :                 values[11] = NULL;
                                652                 : 
                                653                 :                 /* boot_val */
                                654          113029 :                 values[12] = pstrdup(lconf->boot_val ? "on" : "off");
                                655                 : 
                                656                 :                 /* reset_val */
                                657          113029 :                 values[13] = pstrdup(lconf->reset_val ? "on" : "off");
                                658                 :             }
                                659          113029 :             break;
                                660                 : 
                                661          140228 :         case PGC_INT:
                                662                 :             {
                                663          140228 :                 struct config_int *lconf = (struct config_int *) conf;
                                664                 : 
                                665                 :                 /* min_val */
                                666          140228 :                 snprintf(buffer, sizeof(buffer), "%d", lconf->min);
                                667          140228 :                 values[9] = pstrdup(buffer);
                                668                 : 
                                669                 :                 /* max_val */
                                670          140228 :                 snprintf(buffer, sizeof(buffer), "%d", lconf->max);
                                671          140228 :                 values[10] = pstrdup(buffer);
                                672                 : 
                                673                 :                 /* enumvals */
                                674          140228 :                 values[11] = NULL;
                                675                 : 
                                676                 :                 /* boot_val */
                                677          140228 :                 snprintf(buffer, sizeof(buffer), "%d", lconf->boot_val);
                                678          140228 :                 values[12] = pstrdup(buffer);
                                679                 : 
                                680                 :                 /* reset_val */
                                681          140228 :                 snprintf(buffer, sizeof(buffer), "%d", lconf->reset_val);
                                682          140228 :                 values[13] = pstrdup(buffer);
                                683                 :             }
                                684          140228 :             break;
                                685                 : 
                                686           26088 :         case PGC_REAL:
                                687                 :             {
                                688           26088 :                 struct config_real *lconf = (struct config_real *) conf;
                                689                 : 
                                690                 :                 /* min_val */
                                691           26088 :                 snprintf(buffer, sizeof(buffer), "%g", lconf->min);
                                692           26088 :                 values[9] = pstrdup(buffer);
                                693                 : 
                                694                 :                 /* max_val */
                                695           26088 :                 snprintf(buffer, sizeof(buffer), "%g", lconf->max);
                                696           26088 :                 values[10] = pstrdup(buffer);
                                697                 : 
                                698                 :                 /* enumvals */
                                699           26088 :                 values[11] = NULL;
                                700                 : 
                                701                 :                 /* boot_val */
                                702           26088 :                 snprintf(buffer, sizeof(buffer), "%g", lconf->boot_val);
                                703           26088 :                 values[12] = pstrdup(buffer);
                                704                 : 
                                705                 :                 /* reset_val */
                                706           26088 :                 snprintf(buffer, sizeof(buffer), "%g", lconf->reset_val);
                                707           26088 :                 values[13] = pstrdup(buffer);
                                708                 :             }
                                709           26088 :             break;
                                710                 : 
                                711           77143 :         case PGC_STRING:
                                712                 :             {
                                713           77143 :                 struct config_string *lconf = (struct config_string *) conf;
                                714                 : 
                                715                 :                 /* min_val */
                                716           77143 :                 values[9] = NULL;
                                717                 : 
                                718                 :                 /* max_val */
                                719           77143 :                 values[10] = NULL;
                                720                 : 
                                721                 :                 /* enumvals */
                                722           77143 :                 values[11] = NULL;
                                723                 : 
                                724                 :                 /* boot_val */
                                725           77143 :                 if (lconf->boot_val == NULL)
                                726            6522 :                     values[12] = NULL;
                                727                 :                 else
                                728           70621 :                     values[12] = pstrdup(lconf->boot_val);
                                729                 : 
                                730                 :                 /* reset_val */
                                731           77143 :                 if (lconf->reset_val == NULL)
                                732            1087 :                     values[13] = NULL;
                                733                 :                 else
                                734           76056 :                     values[13] = pstrdup(lconf->reset_val);
                                735                 :             }
                                736           77143 :             break;
                                737                 : 
                                738           42381 :         case PGC_ENUM:
                                739                 :             {
                                740           42381 :                 struct config_enum *lconf = (struct config_enum *) conf;
                                741                 : 
                                742                 :                 /* min_val */
                                743           42381 :                 values[9] = NULL;
                                744                 : 
                                745                 :                 /* max_val */
                                746           42381 :                 values[10] = NULL;
                                747                 : 
                                748                 :                 /* enumvals */
                                749                 : 
                                750                 :                 /*
                                751                 :                  * NOTE! enumvals with double quotes in them are not
                                752                 :                  * supported!
                                753                 :                  */
                                754           42381 :                 values[11] = config_enum_get_options((struct config_enum *) conf,
                                755                 :                                                      "{\"", "\"}", "\",\"");
                                756                 : 
                                757                 :                 /* boot_val */
                                758           42381 :                 values[12] = pstrdup(config_enum_lookup_by_value(lconf,
                                759                 :                                                                  lconf->boot_val));
                                760                 : 
                                761                 :                 /* reset_val */
                                762           42381 :                 values[13] = pstrdup(config_enum_lookup_by_value(lconf,
                                763                 :                                                                  lconf->reset_val));
                                764                 :             }
                                765           42381 :             break;
                                766                 : 
  208 tgl                       767 UNC           0 :         default:
                                768                 :             {
                                769                 :                 /*
                                770                 :                  * should never get here, but in case we do, set 'em to NULL
                                771                 :                  */
                                772                 : 
                                773                 :                 /* min_val */
                                774               0 :                 values[9] = NULL;
                                775                 : 
                                776                 :                 /* max_val */
                                777               0 :                 values[10] = NULL;
                                778                 : 
                                779                 :                 /* enumvals */
                                780               0 :                 values[11] = NULL;
                                781                 : 
                                782                 :                 /* boot_val */
                                783               0 :                 values[12] = NULL;
                                784                 : 
                                785                 :                 /* reset_val */
                                786               0 :                 values[13] = NULL;
                                787                 :             }
                                788               0 :             break;
                                789                 :     }
                                790                 : 
                                791                 :     /*
                                792                 :      * If the setting came from a config file, set the source location. For
                                793                 :      * security reasons, we don't show source file/line number for
                                794                 :      * insufficiently-privileged users.
                                795                 :      */
  208 tgl                       796 GNC      429060 :     if (conf->source == PGC_S_FILE &&
                                797           30191 :         has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_SETTINGS))
                                798                 :     {
                                799           30191 :         values[14] = conf->sourcefile;
                                800           30191 :         snprintf(buffer, sizeof(buffer), "%d", conf->sourceline);
                                801           30191 :         values[15] = pstrdup(buffer);
                                802                 :     }
                                803                 :     else
                                804                 :     {
                                805          368678 :         values[14] = NULL;
                                806          368678 :         values[15] = NULL;
                                807                 :     }
                                808                 : 
                                809          398869 :     values[16] = (conf->status & GUC_PENDING_RESTART) ? "t" : "f";
                                810          398869 : }
                                811                 : 
                                812                 : /*
                                813                 :  * show_config_by_name - equiv to SHOW X command but implemented as
                                814                 :  * a function.
                                815                 :  */
                                816                 : Datum
                                817             756 : show_config_by_name(PG_FUNCTION_ARGS)
                                818                 : {
                                819             756 :     char       *varname = TextDatumGetCString(PG_GETARG_DATUM(0));
                                820                 :     char       *varval;
                                821                 : 
                                822                 :     /* Get the value */
                                823             756 :     varval = GetConfigOptionByName(varname, NULL, false);
                                824                 : 
                                825                 :     /* Convert to text */
                                826             753 :     PG_RETURN_TEXT_P(cstring_to_text(varval));
                                827                 : }
                                828                 : 
                                829                 : /*
                                830                 :  * show_config_by_name_missing_ok - equiv to SHOW X command but implemented as
                                831                 :  * a function.  If X does not exist, suppress the error and just return NULL
                                832                 :  * if missing_ok is true.
                                833                 :  */
                                834                 : Datum
                                835              12 : show_config_by_name_missing_ok(PG_FUNCTION_ARGS)
                                836                 : {
                                837              12 :     char       *varname = TextDatumGetCString(PG_GETARG_DATUM(0));
                                838              12 :     bool        missing_ok = PG_GETARG_BOOL(1);
                                839                 :     char       *varval;
                                840                 : 
                                841                 :     /* Get the value */
                                842              12 :     varval = GetConfigOptionByName(varname, NULL, missing_ok);
                                843                 : 
                                844                 :     /* return NULL if no such variable */
                                845               9 :     if (varval == NULL)
                                846               3 :         PG_RETURN_NULL();
                                847                 : 
                                848                 :     /* Convert to text */
                                849               6 :     PG_RETURN_TEXT_P(cstring_to_text(varval));
                                850                 : }
                                851                 : 
                                852                 : /*
                                853                 :  * show_all_settings - equiv to SHOW ALL command but implemented as
                                854                 :  * a Table Function.
                                855                 :  */
                                856                 : #define NUM_PG_SETTINGS_ATTS    17
                                857                 : 
                                858                 : Datum
                                859          399956 : show_all_settings(PG_FUNCTION_ARGS)
                                860                 : {
                                861                 :     FuncCallContext *funcctx;
                                862                 :     struct config_generic **guc_vars;
                                863                 :     int         num_vars;
                                864                 :     TupleDesc   tupdesc;
                                865                 :     int         call_cntr;
                                866                 :     int         max_calls;
                                867                 :     AttInMetadata *attinmeta;
                                868                 :     MemoryContext oldcontext;
                                869                 : 
                                870                 :     /* stuff done only on the first call of the function */
                                871          399956 :     if (SRF_IS_FIRSTCALL())
                                872                 :     {
                                873                 :         /* create a function context for cross-call persistence */
                                874            1087 :         funcctx = SRF_FIRSTCALL_INIT();
                                875                 : 
                                876                 :         /*
                                877                 :          * switch to memory context appropriate for multiple function calls
                                878                 :          */
                                879            1087 :         oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
                                880                 : 
                                881                 :         /*
                                882                 :          * need a tuple descriptor representing NUM_PG_SETTINGS_ATTS columns
                                883                 :          * of the appropriate types
                                884                 :          */
                                885            1087 :         tupdesc = CreateTemplateTupleDesc(NUM_PG_SETTINGS_ATTS);
                                886            1087 :         TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
                                887                 :                            TEXTOID, -1, 0);
                                888            1087 :         TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting",
                                889                 :                            TEXTOID, -1, 0);
                                890            1087 :         TupleDescInitEntry(tupdesc, (AttrNumber) 3, "unit",
                                891                 :                            TEXTOID, -1, 0);
                                892            1087 :         TupleDescInitEntry(tupdesc, (AttrNumber) 4, "category",
                                893                 :                            TEXTOID, -1, 0);
                                894            1087 :         TupleDescInitEntry(tupdesc, (AttrNumber) 5, "short_desc",
                                895                 :                            TEXTOID, -1, 0);
                                896            1087 :         TupleDescInitEntry(tupdesc, (AttrNumber) 6, "extra_desc",
                                897                 :                            TEXTOID, -1, 0);
                                898            1087 :         TupleDescInitEntry(tupdesc, (AttrNumber) 7, "context",
                                899                 :                            TEXTOID, -1, 0);
                                900            1087 :         TupleDescInitEntry(tupdesc, (AttrNumber) 8, "vartype",
                                901                 :                            TEXTOID, -1, 0);
                                902            1087 :         TupleDescInitEntry(tupdesc, (AttrNumber) 9, "source",
                                903                 :                            TEXTOID, -1, 0);
                                904            1087 :         TupleDescInitEntry(tupdesc, (AttrNumber) 10, "min_val",
                                905                 :                            TEXTOID, -1, 0);
                                906            1087 :         TupleDescInitEntry(tupdesc, (AttrNumber) 11, "max_val",
                                907                 :                            TEXTOID, -1, 0);
                                908            1087 :         TupleDescInitEntry(tupdesc, (AttrNumber) 12, "enumvals",
                                909                 :                            TEXTARRAYOID, -1, 0);
                                910            1087 :         TupleDescInitEntry(tupdesc, (AttrNumber) 13, "boot_val",
                                911                 :                            TEXTOID, -1, 0);
                                912            1087 :         TupleDescInitEntry(tupdesc, (AttrNumber) 14, "reset_val",
                                913                 :                            TEXTOID, -1, 0);
                                914            1087 :         TupleDescInitEntry(tupdesc, (AttrNumber) 15, "sourcefile",
                                915                 :                            TEXTOID, -1, 0);
                                916            1087 :         TupleDescInitEntry(tupdesc, (AttrNumber) 16, "sourceline",
                                917                 :                            INT4OID, -1, 0);
                                918            1087 :         TupleDescInitEntry(tupdesc, (AttrNumber) 17, "pending_restart",
                                919                 :                            BOOLOID, -1, 0);
                                920                 : 
                                921                 :         /*
                                922                 :          * Generate attribute metadata needed later to produce tuples from raw
                                923                 :          * C strings
                                924                 :          */
                                925            1087 :         attinmeta = TupleDescGetAttInMetadata(tupdesc);
                                926            1087 :         funcctx->attinmeta = attinmeta;
                                927                 : 
                                928                 :         /* collect the variables, in sorted order */
  177                           929            1087 :         guc_vars = get_guc_variables(&num_vars);
                                930                 : 
                                931                 :         /* use user_fctx to remember the array location */
                                932            1087 :         funcctx->user_fctx = guc_vars;
                                933                 : 
                                934                 :         /* total number of tuples to be returned */
                                935            1087 :         funcctx->max_calls = num_vars;
                                936                 : 
  208                           937            1087 :         MemoryContextSwitchTo(oldcontext);
                                938                 :     }
                                939                 : 
                                940                 :     /* stuff done on every call of the function */
                                941          399956 :     funcctx = SRF_PERCALL_SETUP();
                                942                 : 
  177                           943          399956 :     guc_vars = (struct config_generic **) funcctx->user_fctx;
  208                           944          399956 :     call_cntr = funcctx->call_cntr;
                                945          399956 :     max_calls = funcctx->max_calls;
                                946          399956 :     attinmeta = funcctx->attinmeta;
                                947                 : 
   72                           948          406487 :     while (call_cntr < max_calls)    /* do when there is more left to send */
                                949                 :     {
                                950          405400 :         struct config_generic *conf = guc_vars[call_cntr];
                                951                 :         char       *values[NUM_PG_SETTINGS_ATTS];
                                952                 :         HeapTuple   tuple;
                                953                 :         Datum       result;
                                954                 : 
                                955                 :         /* skip if marked NO_SHOW_ALL or if not visible to current user */
                                956          405400 :         if ((conf->flags & GUC_NO_SHOW_ALL) ||
                                957          398869 :             !ConfigOptionIsVisible(conf))
                                958                 :         {
                                959            6531 :             call_cntr = ++funcctx->call_cntr;
                                960            6531 :             continue;
                                961                 :         }
                                962                 : 
                                963                 :         /* extract values for the current variable */
                                964          398869 :         GetConfigOptionValues(conf, (const char **) values);
                                965                 : 
                                966                 :         /* build a tuple */
  208                           967          398869 :         tuple = BuildTupleFromCStrings(attinmeta, values);
                                968                 : 
                                969                 :         /* make the tuple into a datum */
                                970          398869 :         result = HeapTupleGetDatum(tuple);
                                971                 : 
                                972          398869 :         SRF_RETURN_NEXT(funcctx, result);
                                973                 :     }
                                974                 : 
                                975                 :     /* do when there is no more left */
   72                           976            1087 :     SRF_RETURN_DONE(funcctx);
                                977                 : }
                                978                 : 
                                979                 : /*
                                980                 :  * show_all_file_settings
                                981                 :  *
                                982                 :  * Returns a table of all parameter settings in all configuration files
                                983                 :  * which includes the config file pathname, the line number, a sequence number
                                984                 :  * indicating the order in which the settings were encountered, the parameter
                                985                 :  * name and value, a bool showing if the value could be applied, and possibly
                                986                 :  * an associated error message.  (For problems such as syntax errors, the
                                987                 :  * parameter name/value might be NULL.)
                                988                 :  *
                                989                 :  * Note: no filtering is done here, instead we depend on the GRANT system
                                990                 :  * to prevent unprivileged users from accessing this function or the view
                                991                 :  * built on top of it.
                                992                 :  */
                                993                 : Datum
  208                           994               3 : show_all_file_settings(PG_FUNCTION_ARGS)
                                995                 : {
                                996                 : #define NUM_PG_FILE_SETTINGS_ATTS 7
                                997               3 :     ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
                                998                 :     ConfigVariable *conf;
                                999                 :     int         seqno;
                               1000                 : 
                               1001                 :     /* Scan the config files using current context as workspace */
                               1002               3 :     conf = ProcessConfigFileInternal(PGC_SIGHUP, false, DEBUG3);
                               1003                 : 
                               1004                 :     /* Build a tuplestore to return our results in */
  173 michael                  1005               3 :     InitMaterializedSRF(fcinfo, 0);
                               1006                 : 
                               1007                 :     /* Process the results and create a tuplestore */
  208 tgl                      1008              76 :     for (seqno = 1; conf != NULL; conf = conf->next, seqno++)
                               1009                 :     {
                               1010                 :         Datum       values[NUM_PG_FILE_SETTINGS_ATTS];
                               1011                 :         bool        nulls[NUM_PG_FILE_SETTINGS_ATTS];
                               1012                 : 
                               1013              73 :         memset(values, 0, sizeof(values));
                               1014              73 :         memset(nulls, 0, sizeof(nulls));
                               1015                 : 
                               1016                 :         /* sourcefile */
                               1017              73 :         if (conf->filename)
                               1018              73 :             values[0] = PointerGetDatum(cstring_to_text(conf->filename));
                               1019                 :         else
  208 tgl                      1020 UNC           0 :             nulls[0] = true;
                               1021                 : 
                               1022                 :         /* sourceline (not meaningful if no sourcefile) */
  208 tgl                      1023 GNC          73 :         if (conf->filename)
                               1024              73 :             values[1] = Int32GetDatum(conf->sourceline);
                               1025                 :         else
  208 tgl                      1026 UNC           0 :             nulls[1] = true;
                               1027                 : 
                               1028                 :         /* seqno */
  208 tgl                      1029 GNC          73 :         values[2] = Int32GetDatum(seqno);
                               1030                 : 
                               1031                 :         /* name */
                               1032              73 :         if (conf->name)
                               1033              73 :             values[3] = PointerGetDatum(cstring_to_text(conf->name));
                               1034                 :         else
  208 tgl                      1035 UNC           0 :             nulls[3] = true;
                               1036                 : 
                               1037                 :         /* setting */
  208 tgl                      1038 GNC          73 :         if (conf->value)
                               1039              73 :             values[4] = PointerGetDatum(cstring_to_text(conf->value));
                               1040                 :         else
  208 tgl                      1041 UNC           0 :             nulls[4] = true;
                               1042                 : 
                               1043                 :         /* applied */
  208 tgl                      1044 GNC          73 :         values[5] = BoolGetDatum(conf->applied);
                               1045                 : 
                               1046                 :         /* error */
                               1047              73 :         if (conf->errmsg)
  208 tgl                      1048 UNC           0 :             values[6] = PointerGetDatum(cstring_to_text(conf->errmsg));
                               1049                 :         else
  208 tgl                      1050 GNC          73 :             nulls[6] = true;
                               1051                 : 
                               1052                 :         /* shove row into tuplestore */
                               1053              73 :         tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
                               1054                 :     }
                               1055                 : 
                               1056               3 :     return (Datum) 0;
                               1057                 : }
        

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