Header And Logo

PostgreSQL
| The world's most advanced open source database.

Data Structures | Defines | Typedefs | Enumerations | Functions | Variables

guc.h File Reference

#include "nodes/parsenodes.h"
#include "tcop/dest.h"
#include "utils/array.h"
Include dependency graph for guc.h:

Go to the source code of this file.

Data Structures

struct  ConfigVariable
struct  config_enum_entry

Defines

#define GUC_QUALIFIER_SEPARATOR   '.'
#define GUC_LIST_INPUT   0x0001
#define GUC_LIST_QUOTE   0x0002
#define GUC_NO_SHOW_ALL   0x0004
#define GUC_NO_RESET_ALL   0x0008
#define GUC_REPORT   0x0010
#define GUC_NOT_IN_SAMPLE   0x0020
#define GUC_DISALLOW_IN_FILE   0x0040
#define GUC_CUSTOM_PLACEHOLDER   0x0080
#define GUC_SUPERUSER_ONLY   0x0100
#define GUC_IS_NAME   0x0200
#define GUC_UNIT_KB   0x0400
#define GUC_UNIT_BLOCKS   0x0800
#define GUC_UNIT_XBLOCKS   0x0C00
#define GUC_UNIT_MEMORY   0x0C00
#define GUC_UNIT_MS   0x1000
#define GUC_UNIT_S   0x2000
#define GUC_UNIT_MIN   0x4000
#define GUC_UNIT_TIME   0x7000
#define GUC_NOT_WHILE_SEC_REST   0x8000
#define GUC_check_errmsg
#define GUC_check_errdetail
#define GUC_check_errhint

Typedefs

typedef struct ConfigVariable ConfigVariable
typedef bool(* GucBoolCheckHook )(bool *newval, void **extra, GucSource source)
typedef bool(* GucIntCheckHook )(int *newval, void **extra, GucSource source)
typedef bool(* GucRealCheckHook )(double *newval, void **extra, GucSource source)
typedef bool(* GucStringCheckHook )(char **newval, void **extra, GucSource source)
typedef bool(* GucEnumCheckHook )(int *newval, void **extra, GucSource source)
typedef void(* GucBoolAssignHook )(bool newval, void *extra)
typedef void(* GucIntAssignHook )(int newval, void *extra)
typedef void(* GucRealAssignHook )(double newval, void *extra)
typedef void(* GucStringAssignHook )(const char *newval, void *extra)
typedef void(* GucEnumAssignHook )(int newval, void *extra)
typedef const char *(* GucShowHook )(void)

Enumerations

enum  GucContext {
  PGC_INTERNAL, PGC_POSTMASTER, PGC_SIGHUP, PGC_BACKEND,
  PGC_SUSET, PGC_USERSET
}
enum  GucSource {
  PGC_S_DEFAULT, PGC_S_DYNAMIC_DEFAULT, PGC_S_ENV_VAR, PGC_S_FILE,
  PGC_S_ARGV, PGC_S_GLOBAL, PGC_S_DATABASE, PGC_S_USER,
  PGC_S_DATABASE_USER, PGC_S_CLIENT, PGC_S_OVERRIDE, PGC_S_INTERACTIVE,
  PGC_S_TEST, PGC_S_SESSION
}
enum  GucAction { GUC_ACTION_SET, GUC_ACTION_LOCAL, GUC_ACTION_SAVE }

Functions

bool ParseConfigFile (const char *config_file, const char *calling_file, bool strict, int depth, int elevel, ConfigVariable **head_p, ConfigVariable **tail_p)
bool ParseConfigFp (FILE *fp, const char *config_file, int depth, int elevel, ConfigVariable **head_p, ConfigVariable **tail_p)
bool ParseConfigDirectory (const char *includedir, const char *calling_file, int depth, int elevel, ConfigVariable **head_p, ConfigVariable **tail_p)
void FreeConfigVariables (ConfigVariable *list)
void SetConfigOption (const char *name, const char *value, GucContext context, GucSource source)
void DefineCustomBoolVariable (const char *name, const char *short_desc, const char *long_desc, bool *valueAddr, bool bootValue, GucContext context, int flags, GucBoolCheckHook check_hook, GucBoolAssignHook assign_hook, GucShowHook show_hook)
void DefineCustomIntVariable (const char *name, const char *short_desc, const char *long_desc, int *valueAddr, int bootValue, int minValue, int maxValue, GucContext context, int flags, GucIntCheckHook check_hook, GucIntAssignHook assign_hook, GucShowHook show_hook)
void DefineCustomRealVariable (const char *name, const char *short_desc, const char *long_desc, double *valueAddr, double bootValue, double minValue, double maxValue, GucContext context, int flags, GucRealCheckHook check_hook, GucRealAssignHook assign_hook, GucShowHook show_hook)
void DefineCustomStringVariable (const char *name, const char *short_desc, const char *long_desc, char **valueAddr, const char *bootValue, GucContext context, int flags, GucStringCheckHook check_hook, GucStringAssignHook assign_hook, GucShowHook show_hook)
void DefineCustomEnumVariable (const char *name, const char *short_desc, const char *long_desc, int *valueAddr, int bootValue, const struct config_enum_entry *options, GucContext context, int flags, GucEnumCheckHook check_hook, GucEnumAssignHook assign_hook, GucShowHook show_hook)
void EmitWarningsOnPlaceholders (const char *className)
const char * GetConfigOption (const char *name, bool missing_ok, bool restrict_superuser)
const char * GetConfigOptionResetString (const char *name)
void ProcessConfigFile (GucContext context)
void InitializeGUCOptions (void)
bool SelectConfigFiles (const char *userDoption, const char *progname)
void ResetAllOptions (void)
void AtStart_GUC (void)
int NewGUCNestLevel (void)
void AtEOXact_GUC (bool isCommit, int nestLevel)
void BeginReportingGUCOptions (void)
void ParseLongOption (const char *string, char **name, char **value)
bool parse_int (const char *value, int *result, int flags, const char **hintmsg)
bool parse_real (const char *value, double *result)
int set_config_option (const char *name, const char *value, GucContext context, GucSource source, GucAction action, bool changeVal, int elevel)
char * GetConfigOptionByName (const char *name, const char **varname)
void GetConfigOptionByNum (int varnum, const char **values, bool *noshow)
int GetNumConfigOptions (void)
void SetPGVariable (const char *name, List *args, bool is_local)
void GetPGVariable (const char *name, DestReceiver *dest)
TupleDesc GetPGVariableResultDesc (const char *name)
void ExecSetVariableStmt (VariableSetStmt *stmt)
char * ExtractSetVariableArgs (VariableSetStmt *stmt)
void ProcessGUCArray (ArrayType *array, GucContext context, GucSource source, GucAction action)
ArrayTypeGUCArrayAdd (ArrayType *array, const char *name, const char *value)
ArrayTypeGUCArrayDelete (ArrayType *array, const char *name)
ArrayTypeGUCArrayReset (ArrayType *array)
void GUC_check_errcode (int sqlerrcode)
bool check_default_tablespace (char **newval, void **extra, GucSource source)
bool check_temp_tablespaces (char **newval, void **extra, GucSource source)
void assign_temp_tablespaces (const char *newval, void *extra)
bool check_search_path (char **newval, void **extra, GucSource source)
void assign_search_path (const char *newval, void *extra)
bool check_wal_buffers (int *newval, void **extra, GucSource source)
void assign_xlog_sync_method (int new_sync_method, void *extra)

Variables

bool log_duration
bool Debug_print_plan
bool Debug_print_parse
bool Debug_print_rewritten
bool Debug_pretty_print
bool log_parser_stats
bool log_planner_stats
bool log_executor_stats
bool log_statement_stats
bool log_btree_build_stats
PGDLLIMPORT bool check_function_bodies
bool default_with_oids
bool SQL_inheritance
int log_min_error_statement
int log_min_messages
int client_min_messages
int log_min_duration_statement
int log_temp_files
int temp_file_limit
int num_temp_buffers
char * data_directory
char * ConfigFileName
char * HbaFileName
char * IdentFileName
char * external_pid_file
char * application_name
int tcp_keepalives_idle
int tcp_keepalives_interval
int tcp_keepalives_count
PGDLLIMPORT char * GUC_check_errmsg_string
PGDLLIMPORT char * GUC_check_errdetail_string
PGDLLIMPORT char * GUC_check_errhint_string

Define Documentation

#define GUC_check_errdetail
#define GUC_check_errhint
#define GUC_check_errmsg
#define GUC_CUSTOM_PLACEHOLDER   0x0080
#define GUC_DISALLOW_IN_FILE   0x0040

Definition at line 178 of file guc.h.

#define GUC_IS_NAME   0x0200

Definition at line 181 of file guc.h.

Referenced by set_config_option().

#define GUC_LIST_INPUT   0x0001

Definition at line 172 of file guc.h.

Referenced by flatten_set_variable_args().

#define GUC_LIST_QUOTE   0x0002

Definition at line 173 of file guc.h.

Referenced by flatten_set_variable_args().

#define GUC_NO_RESET_ALL   0x0008

Definition at line 175 of file guc.h.

Referenced by ResetAllOptions().

#define GUC_NO_SHOW_ALL   0x0004
#define GUC_NOT_IN_SAMPLE   0x0020

Definition at line 177 of file guc.h.

Referenced by _PG_init(), add_placeholder_variable(), and displayStruct().

#define GUC_NOT_WHILE_SEC_REST   0x8000

Definition at line 193 of file guc.h.

Referenced by set_config_option().

#define GUC_QUALIFIER_SEPARATOR   '.'

Definition at line 167 of file guc.h.

Referenced by EmitWarningsOnPlaceholders(), and find_option().

#define GUC_REPORT   0x0010
#define GUC_SUPERUSER_ONLY   0x0100
#define GUC_UNIT_BLOCKS   0x0800

Definition at line 184 of file guc.h.

Referenced by _ShowOption(), GetConfigOptionByNum(), and parse_int().

#define GUC_UNIT_KB   0x0400

Definition at line 183 of file guc.h.

Referenced by GetConfigOptionByNum(), and parse_int().

#define GUC_UNIT_MEMORY   0x0C00

Definition at line 186 of file guc.h.

Referenced by _ShowOption(), GetConfigOptionByNum(), and parse_int().

#define GUC_UNIT_MIN   0x4000

Definition at line 190 of file guc.h.

Referenced by _ShowOption(), GetConfigOptionByNum(), and parse_int().

#define GUC_UNIT_MS   0x1000

Definition at line 188 of file guc.h.

Referenced by _PG_init(), GetConfigOptionByNum(), and parse_int().

#define GUC_UNIT_S   0x2000

Definition at line 189 of file guc.h.

Referenced by _ShowOption(), GetConfigOptionByNum(), and parse_int().

#define GUC_UNIT_TIME   0x7000

Definition at line 191 of file guc.h.

Referenced by _ShowOption(), GetConfigOptionByNum(), and parse_int().

#define GUC_UNIT_XBLOCKS   0x0C00

Definition at line 185 of file guc.h.

Referenced by _ShowOption(), GetConfigOptionByNum(), and parse_int().


Typedef Documentation

typedef void(* GucBoolAssignHook)(bool newval, void *extra)

Definition at line 148 of file guc.h.

typedef bool(* GucBoolCheckHook)(bool *newval, void **extra, GucSource source)

Definition at line 142 of file guc.h.

typedef void(* GucEnumAssignHook)(int newval, void *extra)

Definition at line 152 of file guc.h.

typedef bool(* GucEnumCheckHook)(int *newval, void **extra, GucSource source)

Definition at line 146 of file guc.h.

typedef void(* GucIntAssignHook)(int newval, void *extra)

Definition at line 149 of file guc.h.

typedef bool(* GucIntCheckHook)(int *newval, void **extra, GucSource source)

Definition at line 143 of file guc.h.

typedef void(* GucRealAssignHook)(double newval, void *extra)

Definition at line 150 of file guc.h.

typedef bool(* GucRealCheckHook)(double *newval, void **extra, GucSource source)

Definition at line 144 of file guc.h.

typedef const char*(* GucShowHook)(void)

Definition at line 154 of file guc.h.

typedef void(* GucStringAssignHook)(const char *newval, void *extra)

Definition at line 151 of file guc.h.

typedef bool(* GucStringCheckHook)(char **newval, void **extra, GucSource source)

Definition at line 145 of file guc.h.


Enumeration Type Documentation

enum GucAction
Enumerator:
GUC_ACTION_SET 
GUC_ACTION_LOCAL 
GUC_ACTION_SAVE 

Definition at line 159 of file guc.h.

{
    /* Types of set_config_option actions */
    GUC_ACTION_SET,             /* regular SET command */
    GUC_ACTION_LOCAL,           /* SET LOCAL command */
    GUC_ACTION_SAVE             /* function SET option, or temp assignment */
} GucAction;

enum GucContext
Enumerator:
PGC_INTERNAL 
PGC_POSTMASTER 
PGC_SIGHUP 
PGC_BACKEND 
PGC_SUSET 
PGC_USERSET 

Definition at line 51 of file guc.h.

{
    PGC_INTERNAL,
    PGC_POSTMASTER,
    PGC_SIGHUP,
    PGC_BACKEND,
    PGC_SUSET,
    PGC_USERSET
} GucContext;

enum GucSource
Enumerator:
PGC_S_DEFAULT 
PGC_S_DYNAMIC_DEFAULT 
PGC_S_ENV_VAR 
PGC_S_FILE 
PGC_S_ARGV 
PGC_S_GLOBAL 
PGC_S_DATABASE 
PGC_S_USER 
PGC_S_DATABASE_USER 
PGC_S_CLIENT 
PGC_S_OVERRIDE 
PGC_S_INTERACTIVE 
PGC_S_TEST 
PGC_S_SESSION 

Definition at line 83 of file guc.h.

{
    PGC_S_DEFAULT,              /* hard-wired default ("boot_val") */
    PGC_S_DYNAMIC_DEFAULT,      /* default computed during initialization */
    PGC_S_ENV_VAR,              /* postmaster environment variable */
    PGC_S_FILE,                 /* postgresql.conf */
    PGC_S_ARGV,                 /* postmaster command line */
    PGC_S_GLOBAL,               /* global in-database setting */
    PGC_S_DATABASE,             /* per-database setting */
    PGC_S_USER,                 /* per-user setting */
    PGC_S_DATABASE_USER,        /* per-user-and-database setting */
    PGC_S_CLIENT,               /* from client connection request */
    PGC_S_OVERRIDE,             /* special case to forcibly set default */
    PGC_S_INTERACTIVE,          /* dividing line for error reporting */
    PGC_S_TEST,                 /* test per-database or per-user setting */
    PGC_S_SESSION               /* SET command */
} GucSource;


Function Documentation

void assign_search_path ( const char *  newval,
void *  extra 
)

Definition at line 3871 of file namespace.c.

References baseSearchPathValid.

{
    /*
     * We mark the path as needing recomputation, but don't do anything until
     * it's needed.  This avoids trying to do database access during GUC
     * initialization, or outside a transaction.
     */
    baseSearchPathValid = false;
}

void assign_temp_tablespaces ( const char *  newval,
void *  extra 
)

Definition at line 1177 of file tablespace.c.

References NULL, temp_tablespaces_extra::numSpcs, SetTempTablespaces(), and temp_tablespaces_extra::tblSpcs.

{
    temp_tablespaces_extra *myextra = (temp_tablespaces_extra *) extra;

    /*
     * If check_temp_tablespaces was executed inside a transaction, then pass
     * the list it made to fd.c.  Otherwise, clear fd.c's list; we must be
     * still outside a transaction, or else restoring during transaction exit,
     * and in either case we can just let the next PrepareTempTablespaces call
     * make things sane.
     */
    if (myextra)
        SetTempTablespaces(myextra->tblSpcs, myextra->numSpcs);
    else
        SetTempTablespaces(NULL, 0);
}

void assign_xlog_sync_method ( int  new_sync_method,
void *  extra 
)

Definition at line 8291 of file xlog.c.

References ereport, errcode_for_file_access(), errmsg(), get_sync_bit(), openLogFile, openLogSegNo, PANIC, pg_fsync(), sync_method, ThisTimeLineID, XLogFileClose(), and XLogFileNameP().

{
    if (sync_method != new_sync_method)
    {
        /*
         * To ensure that no blocks escape unsynced, force an fsync on the
         * currently open log segment (if any).  Also, if the open flag is
         * changing, close the log file so it will be reopened (with new flag
         * bit) at next use.
         */
        if (openLogFile >= 0)
        {
            if (pg_fsync(openLogFile) != 0)
                ereport(PANIC,
                        (errcode_for_file_access(),
                         errmsg("could not fsync log segment %s: %m",
                                XLogFileNameP(ThisTimeLineID, openLogSegNo))));
            if (get_sync_bit(sync_method) != get_sync_bit(new_sync_method))
                XLogFileClose();
        }
    }
}

void AtEOXact_GUC ( bool  isCommit,
int  nestLevel 
)

Definition at line 4464 of file guc.c.

References Assert, config_enum::assign_hook, config_string::assign_hook, config_real::assign_hook, config_int::assign_hook, config_bool::assign_hook, config_var_val::boolval, discard_stack_value(), config_var_val::enumval, config_generic::extra, config_var_value::extra, config_generic::flags, config_enum::gen, config_string::gen, config_real::gen, config_int::gen, config_bool::gen, GUC_LOCAL, GUC_REPORT, GUC_SAVE, GUC_SET, GUC_SET_LOCAL, i, config_var_val::intval, guc_stack::masked, guc_stack::masked_scontext, guc_stack::nest_level, NULL, pfree(), PGC_BOOL, PGC_ENUM, PGC_INT, PGC_REAL, PGC_STRING, guc_stack::prev, guc_stack::prior, config_var_val::realval, ReportGUCOption(), config_generic::scontext, guc_stack::scontext, set_extra_field(), set_string_field(), config_generic::source, guc_stack::source, config_generic::stack, guc_stack::state, config_var_val::stringval, config_var_value::val, config_enum::variable, config_string::variable, config_real::variable, config_int::variable, config_bool::variable, and config_generic::vartype.

Referenced by AbortSubTransaction(), AbortTransaction(), CommitSubTransaction(), CommitTransaction(), do_analyze_rel(), execute_extension_script(), fmgr_security_definer(), index_build(), PrepareTransaction(), ProcedureCreate(), reset_transmission_modes(), restoreLocalGucs(), RI_Initial_Check(), vacuum_rel(), and validate_index().

{
    bool        still_dirty;
    int         i;

    /*
     * Note: it's possible to get here with GUCNestLevel == nestLevel-1 during
     * abort, if there is a failure during transaction start before
     * AtStart_GUC is called.
     */
    Assert(nestLevel > 0 &&
           (nestLevel <= GUCNestLevel ||
            (nestLevel == GUCNestLevel + 1 && !isCommit)));

    /* Quick exit if nothing's changed in this transaction */
    if (!guc_dirty)
    {
        GUCNestLevel = nestLevel - 1;
        return;
    }

    still_dirty = false;
    for (i = 0; i < num_guc_variables; i++)
    {
        struct config_generic *gconf = guc_variables[i];
        GucStack   *stack;

        /*
         * Process and pop each stack entry within the nest level. To simplify
         * fmgr_security_definer() and other places that use GUC_ACTION_SAVE,
         * we allow failure exit from code that uses a local nest level to be
         * recovered at the surrounding transaction or subtransaction abort;
         * so there could be more than one stack entry to pop.
         */
        while ((stack = gconf->stack) != NULL &&
               stack->nest_level >= nestLevel)
        {
            GucStack   *prev = stack->prev;
            bool        restorePrior = false;
            bool        restoreMasked = false;
            bool        changed;

            /*
             * In this next bit, if we don't set either restorePrior or
             * restoreMasked, we must "discard" any unwanted fields of the
             * stack entries to avoid leaking memory.  If we do set one of
             * those flags, unused fields will be cleaned up after restoring.
             */
            if (!isCommit)      /* if abort, always restore prior value */
                restorePrior = true;
            else if (stack->state == GUC_SAVE)
                restorePrior = true;
            else if (stack->nest_level == 1)
            {
                /* transaction commit */
                if (stack->state == GUC_SET_LOCAL)
                    restoreMasked = true;
                else if (stack->state == GUC_SET)
                {
                    /* we keep the current active value */
                    discard_stack_value(gconf, &stack->prior);
                }
                else    /* must be GUC_LOCAL */
                    restorePrior = true;
            }
            else if (prev == NULL ||
                     prev->nest_level < stack->nest_level - 1)
            {
                /* decrement entry's level and do not pop it */
                stack->nest_level--;
                continue;
            }
            else
            {
                /*
                 * We have to merge this stack entry into prev. See README for
                 * discussion of this bit.
                 */
                switch (stack->state)
                {
                    case GUC_SAVE:
                        Assert(false);  /* can't get here */

                    case GUC_SET:
                        /* next level always becomes SET */
                        discard_stack_value(gconf, &stack->prior);
                        if (prev->state == GUC_SET_LOCAL)
                            discard_stack_value(gconf, &prev->masked);
                        prev->state = GUC_SET;
                        break;

                    case GUC_LOCAL:
                        if (prev->state == GUC_SET)
                        {
                            /* LOCAL migrates down */
                            prev->masked_scontext = stack->scontext;
                            prev->masked = stack->prior;
                            prev->state = GUC_SET_LOCAL;
                        }
                        else
                        {
                            /* else just forget this stack level */
                            discard_stack_value(gconf, &stack->prior);
                        }
                        break;

                    case GUC_SET_LOCAL:
                        /* prior state at this level no longer wanted */
                        discard_stack_value(gconf, &stack->prior);
                        /* copy down the masked state */
                        prev->masked_scontext = stack->masked_scontext;
                        if (prev->state == GUC_SET_LOCAL)
                            discard_stack_value(gconf, &prev->masked);
                        prev->masked = stack->masked;
                        prev->state = GUC_SET_LOCAL;
                        break;
                }
            }

            changed = false;

            if (restorePrior || restoreMasked)
            {
                /* Perform appropriate restoration of the stacked value */
                config_var_value newvalue;
                GucSource   newsource;
                GucContext  newscontext;

                if (restoreMasked)
                {
                    newvalue = stack->masked;
                    newsource = PGC_S_SESSION;
                    newscontext = stack->masked_scontext;
                }
                else
                {
                    newvalue = stack->prior;
                    newsource = stack->source;
                    newscontext = stack->scontext;
                }

                switch (gconf->vartype)
                {
                    case PGC_BOOL:
                        {
                            struct config_bool *conf = (struct config_bool *) gconf;
                            bool        newval = newvalue.val.boolval;
                            void       *newextra = newvalue.extra;

                            if (*conf->variable != newval ||
                                conf->gen.extra != newextra)
                            {
                                if (conf->assign_hook)
                                    (*conf->assign_hook) (newval, newextra);
                                *conf->variable = newval;
                                set_extra_field(&conf->gen, &conf->gen.extra,
                                                newextra);
                                changed = true;
                            }
                            break;
                        }
                    case PGC_INT:
                        {
                            struct config_int *conf = (struct config_int *) gconf;
                            int         newval = newvalue.val.intval;
                            void       *newextra = newvalue.extra;

                            if (*conf->variable != newval ||
                                conf->gen.extra != newextra)
                            {
                                if (conf->assign_hook)
                                    (*conf->assign_hook) (newval, newextra);
                                *conf->variable = newval;
                                set_extra_field(&conf->gen, &conf->gen.extra,
                                                newextra);
                                changed = true;
                            }
                            break;
                        }
                    case PGC_REAL:
                        {
                            struct config_real *conf = (struct config_real *) gconf;
                            double      newval = newvalue.val.realval;
                            void       *newextra = newvalue.extra;

                            if (*conf->variable != newval ||
                                conf->gen.extra != newextra)
                            {
                                if (conf->assign_hook)
                                    (*conf->assign_hook) (newval, newextra);
                                *conf->variable = newval;
                                set_extra_field(&conf->gen, &conf->gen.extra,
                                                newextra);
                                changed = true;
                            }
                            break;
                        }
                    case PGC_STRING:
                        {
                            struct config_string *conf = (struct config_string *) gconf;
                            char       *newval = newvalue.val.stringval;
                            void       *newextra = newvalue.extra;

                            if (*conf->variable != newval ||
                                conf->gen.extra != newextra)
                            {
                                if (conf->assign_hook)
                                    (*conf->assign_hook) (newval, newextra);
                                set_string_field(conf, conf->variable, newval);
                                set_extra_field(&conf->gen, &conf->gen.extra,
                                                newextra);
                                changed = true;
                            }

                            /*
                             * Release stacked values if not used anymore. We
                             * could use discard_stack_value() here, but since
                             * we have type-specific code anyway, might as
                             * well inline it.
                             */
                            set_string_field(conf, &stack->prior.val.stringval, NULL);
                            set_string_field(conf, &stack->masked.val.stringval, NULL);
                            break;
                        }
                    case PGC_ENUM:
                        {
                            struct config_enum *conf = (struct config_enum *) gconf;
                            int         newval = newvalue.val.enumval;
                            void       *newextra = newvalue.extra;

                            if (*conf->variable != newval ||
                                conf->gen.extra != newextra)
                            {
                                if (conf->assign_hook)
                                    (*conf->assign_hook) (newval, newextra);
                                *conf->variable = newval;
                                set_extra_field(&conf->gen, &conf->gen.extra,
                                                newextra);
                                changed = true;
                            }
                            break;
                        }
                }

                /*
                 * Release stacked extra values if not used anymore.
                 */
                set_extra_field(gconf, &(stack->prior.extra), NULL);
                set_extra_field(gconf, &(stack->masked.extra), NULL);

                /* And restore source information */
                gconf->source = newsource;
                gconf->scontext = newscontext;
            }

            /* Finish popping the state stack */
            gconf->stack = prev;
            pfree(stack);

            /* Report new value if we changed it */
            if (changed && (gconf->flags & GUC_REPORT))
                ReportGUCOption(gconf);
        }                       /* end of stack-popping loop */

        if (stack != NULL)
            still_dirty = true;
    }

    /* If there are no remaining stack entries, we can reset guc_dirty */
    guc_dirty = still_dirty;

    /* Update nesting level */
    GUCNestLevel = nestLevel - 1;
}

void AtStart_GUC ( void   ) 

Definition at line 4430 of file guc.c.

References elog, and WARNING.

Referenced by StartTransaction().

{
    /*
     * The nest level should be 0 between transactions; if it isn't, somebody
     * didn't call AtEOXact_GUC, or called it with the wrong nestLevel.  We
     * throw a warning but make no other effort to clean up.
     */
    if (GUCNestLevel != 0)
        elog(WARNING, "GUC nest level = %d at transaction start",
             GUCNestLevel);
    GUCNestLevel = 1;
}

void BeginReportingGUCOptions ( void   ) 

Definition at line 4745 of file guc.c.

References DestRemote, config_generic::flags, FrontendProtocol, GUC_REPORT, i, PG_PROTOCOL_MAJOR, ReportGUCOption(), and whereToSendOutput.

Referenced by PostgresMain().

{
    int         i;

    /*
     * Don't do anything unless talking to an interactive frontend of protocol
     * 3.0 or later.
     */
    if (whereToSendOutput != DestRemote ||
        PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
        return;

    reporting_enabled = true;

    /* Transmit initial values of interesting variables */
    for (i = 0; i < num_guc_variables; i++)
    {
        struct config_generic *conf = guc_variables[i];

        if (conf->flags & GUC_REPORT)
            ReportGUCOption(conf);
    }
}

bool check_default_tablespace ( char **  newval,
void **  extra,
GucSource  source 
)

Definition at line 968 of file tablespace.c.

References ereport, errcode(), errmsg(), get_tablespace_oid(), GUC_check_errdetail, IsTransactionState(), NOTICE, OidIsValid, and PGC_S_TEST.

{
    /*
     * If we aren't inside a transaction, we cannot do database access so
     * cannot verify the name.  Must accept the value on faith.
     */
    if (IsTransactionState())
    {
        if (**newval != '\0' &&
            !OidIsValid(get_tablespace_oid(*newval, true)))
        {
            /*
             * When source == PGC_S_TEST, we are checking the argument of an
             * ALTER DATABASE SET or ALTER USER SET command.  pg_dumpall dumps
             * all roles before tablespaces, so if we're restoring a
             * pg_dumpall script the tablespace might not yet exist, but will
             * be created later.  Because of that, issue a NOTICE if source ==
             * PGC_S_TEST, but accept the value anyway.
             */
            if (source == PGC_S_TEST)
            {
                ereport(NOTICE,
                        (errcode(ERRCODE_UNDEFINED_OBJECT),
                         errmsg("tablespace \"%s\" does not exist",
                                *newval)));
            }
            else
            {
                GUC_check_errdetail("Tablespace \"%s\" does not exist.",
                                    *newval);
                return false;
            }
        }
    }

    return true;
}

bool check_search_path ( char **  newval,
void **  extra,
GucSource  source 
)

Definition at line 3837 of file namespace.c.

References GUC_check_errdetail, list_free(), pfree(), pstrdup(), and SplitIdentifierString().

{
    char       *rawname;
    List       *namelist;

    /* Need a modifiable copy of string */
    rawname = pstrdup(*newval);

    /* Parse string into list of identifiers */
    if (!SplitIdentifierString(rawname, ',', &namelist))
    {
        /* syntax error in name list */
        GUC_check_errdetail("List syntax is invalid.");
        pfree(rawname);
        list_free(namelist);
        return false;
    }

    /*
     * We used to try to check that the named schemas exist, but there are
     * many valid use-cases for having search_path settings that include
     * schemas that don't exist; and often, we are not inside a transaction
     * here and so can't consult the system catalogs anyway.  So now, the only
     * requirement is syntactic validity of the identifier list.
     */

    pfree(rawname);
    list_free(namelist);

    return true;
}

bool check_temp_tablespaces ( char **  newval,
void **  extra,
GucSource  source 
)

Definition at line 1067 of file tablespace.c.

References ACL_CREATE, ACL_KIND_TABLESPACE, aclcheck_error(), ACLCHECK_OK, ereport, errcode(), errmsg(), get_tablespace_oid(), GetUserId(), GUC_check_errdetail, InvalidOid, IsTransactionState(), lfirst, list_free(), list_length(), malloc, MyDatabaseTableSpace, NOTICE, temp_tablespaces_extra::numSpcs, offsetof, palloc(), pfree(), pg_tablespace_aclcheck(), PGC_S_INTERACTIVE, PGC_S_TEST, pstrdup(), SplitIdentifierString(), and temp_tablespaces_extra::tblSpcs.

{
    char       *rawname;
    List       *namelist;

    /* Need a modifiable copy of string */
    rawname = pstrdup(*newval);

    /* Parse string into list of identifiers */
    if (!SplitIdentifierString(rawname, ',', &namelist))
    {
        /* syntax error in name list */
        GUC_check_errdetail("List syntax is invalid.");
        pfree(rawname);
        list_free(namelist);
        return false;
    }

    /*
     * If we aren't inside a transaction, we cannot do database access so
     * cannot verify the individual names.  Must accept the list on faith.
     * Fortunately, there's then also no need to pass the data to fd.c.
     */
    if (IsTransactionState())
    {
        temp_tablespaces_extra *myextra;
        Oid        *tblSpcs;
        int         numSpcs;
        ListCell   *l;

        /* temporary workspace until we are done verifying the list */
        tblSpcs = (Oid *) palloc(list_length(namelist) * sizeof(Oid));
        numSpcs = 0;
        foreach(l, namelist)
        {
            char       *curname = (char *) lfirst(l);
            Oid         curoid;
            AclResult   aclresult;

            /* Allow an empty string (signifying database default) */
            if (curname[0] == '\0')
            {
                tblSpcs[numSpcs++] = InvalidOid;
                continue;
            }

            /*
             * In an interactive SET command, we ereport for bad info.  When
             * source == PGC_S_TEST, we are checking the argument of an ALTER
             * DATABASE SET or ALTER USER SET command.  pg_dumpall dumps all
             * roles before tablespaces, so if we're restoring a pg_dumpall
             * script the tablespace might not yet exist, but will be created
             * later.  Because of that, issue a NOTICE if source ==
             * PGC_S_TEST, but accept the value anyway.  Otherwise, silently
             * ignore any bad list elements.
             */
            curoid = get_tablespace_oid(curname, source <= PGC_S_TEST);
            if (curoid == InvalidOid)
            {
                if (source == PGC_S_TEST)
                    ereport(NOTICE,
                            (errcode(ERRCODE_UNDEFINED_OBJECT),
                             errmsg("tablespace \"%s\" does not exist",
                                    curname)));
                continue;
            }

            /*
             * Allow explicit specification of database's default tablespace
             * in temp_tablespaces without triggering permissions checks.
             */
            if (curoid == MyDatabaseTableSpace)
            {
                tblSpcs[numSpcs++] = InvalidOid;
                continue;
            }

            /* Check permissions, similarly complaining only if interactive */
            aclresult = pg_tablespace_aclcheck(curoid, GetUserId(),
                                               ACL_CREATE);
            if (aclresult != ACLCHECK_OK)
            {
                if (source >= PGC_S_INTERACTIVE)
                    aclcheck_error(aclresult, ACL_KIND_TABLESPACE, curname);
                continue;
            }

            tblSpcs[numSpcs++] = curoid;
        }

        /* Now prepare an "extra" struct for assign_temp_tablespaces */
        myextra = malloc(offsetof(temp_tablespaces_extra, tblSpcs) +
                         numSpcs * sizeof(Oid));
        if (!myextra)
            return false;
        myextra->numSpcs = numSpcs;
        memcpy(myextra->tblSpcs, tblSpcs, numSpcs * sizeof(Oid));
        *extra = (void *) myextra;

        pfree(tblSpcs);
    }

    pfree(rawname);
    list_free(namelist);

    return true;
}

bool check_wal_buffers ( int *  newval,
void **  extra,
GucSource  source 
)

Definition at line 3856 of file xlog.c.

References XLOGbuffers, and XLOGChooseNumBuffers().

{
    /*
     * -1 indicates a request for auto-tune.
     */
    if (*newval == -1)
    {
        /*
         * If we haven't yet changed the boot_val default of -1, just let it
         * be.  We'll fix it when XLOGShmemSize is called.
         */
        if (XLOGbuffers == -1)
            return true;

        /* Otherwise, substitute the auto-tune value */
        *newval = XLOGChooseNumBuffers();
    }

    /*
     * We clamp manually-set values to at least 4 blocks.  Prior to PostgreSQL
     * 9.1, a minimum of 4 was enforced by guc.c, but since that is no longer
     * the case, we just silently treat such values as a request for the
     * minimum.  (We could throw an error instead, but that doesn't seem very
     * helpful.)
     */
    if (*newval < 4)
        *newval = 4;

    return true;
}

void DefineCustomBoolVariable ( const char *  name,
const char *  short_desc,
const char *  long_desc,
bool valueAddr,
bool  bootValue,
GucContext  context,
int  flags,
GucBoolCheckHook  check_hook,
GucBoolAssignHook  assign_hook,
GucShowHook  show_hook 
)

Definition at line 6605 of file guc.c.

References config_bool::assign_hook, config_bool::boot_val, config_bool::check_hook, define_custom_variable(), config_bool::gen, init_custom_variable(), PGC_BOOL, config_bool::reset_val, config_bool::show_hook, and config_bool::variable.

Referenced by _PG_init().

{
    struct config_bool *var;

    var = (struct config_bool *)
        init_custom_variable(name, short_desc, long_desc, context, flags,
                             PGC_BOOL, sizeof(struct config_bool));
    var->variable = valueAddr;
    var->boot_val = bootValue;
    var->reset_val = bootValue;
    var->check_hook = check_hook;
    var->assign_hook = assign_hook;
    var->show_hook = show_hook;
    define_custom_variable(&var->gen);
}

void DefineCustomEnumVariable ( const char *  name,
const char *  short_desc,
const char *  long_desc,
int *  valueAddr,
int  bootValue,
const struct config_enum_entry options,
GucContext  context,
int  flags,
GucEnumCheckHook  check_hook,
GucEnumAssignHook  assign_hook,
GucShowHook  show_hook 
)

Definition at line 6716 of file guc.c.

References config_enum::assign_hook, config_enum::boot_val, config_enum::check_hook, define_custom_variable(), config_enum::gen, init_custom_variable(), config_enum::options, PGC_ENUM, config_enum::reset_val, config_enum::show_hook, and config_enum::variable.

Referenced by _PG_init().

{
    struct config_enum *var;

    var = (struct config_enum *)
        init_custom_variable(name, short_desc, long_desc, context, flags,
                             PGC_ENUM, sizeof(struct config_enum));
    var->variable = valueAddr;
    var->boot_val = bootValue;
    var->reset_val = bootValue;
    var->options = options;
    var->check_hook = check_hook;
    var->assign_hook = assign_hook;
    var->show_hook = show_hook;
    define_custom_variable(&var->gen);
}

void DefineCustomIntVariable ( const char *  name,
const char *  short_desc,
const char *  long_desc,
int *  valueAddr,
int  bootValue,
int  minValue,
int  maxValue,
GucContext  context,
int  flags,
GucIntCheckHook  check_hook,
GucIntAssignHook  assign_hook,
GucShowHook  show_hook 
)

Definition at line 6631 of file guc.c.

References config_int::assign_hook, config_int::boot_val, config_int::check_hook, define_custom_variable(), config_int::gen, init_custom_variable(), config_int::max, config_int::min, PGC_INT, config_int::reset_val, config_int::show_hook, and config_int::variable.

Referenced by _PG_init().

{
    struct config_int *var;

    var = (struct config_int *)
        init_custom_variable(name, short_desc, long_desc, context, flags,
                             PGC_INT, sizeof(struct config_int));
    var->variable = valueAddr;
    var->boot_val = bootValue;
    var->reset_val = bootValue;
    var->min = minValue;
    var->max = maxValue;
    var->check_hook = check_hook;
    var->assign_hook = assign_hook;
    var->show_hook = show_hook;
    define_custom_variable(&var->gen);
}

void DefineCustomRealVariable ( const char *  name,
const char *  short_desc,
const char *  long_desc,
double *  valueAddr,
double  bootValue,
double  minValue,
double  maxValue,
GucContext  context,
int  flags,
GucRealCheckHook  check_hook,
GucRealAssignHook  assign_hook,
GucShowHook  show_hook 
)

Definition at line 6661 of file guc.c.

References config_real::assign_hook, config_real::boot_val, config_real::check_hook, define_custom_variable(), config_real::gen, init_custom_variable(), config_real::max, config_real::min, PGC_REAL, config_real::reset_val, config_real::show_hook, and config_real::variable.

{
    struct config_real *var;

    var = (struct config_real *)
        init_custom_variable(name, short_desc, long_desc, context, flags,
                             PGC_REAL, sizeof(struct config_real));
    var->variable = valueAddr;
    var->boot_val = bootValue;
    var->reset_val = bootValue;
    var->min = minValue;
    var->max = maxValue;
    var->check_hook = check_hook;
    var->assign_hook = assign_hook;
    var->show_hook = show_hook;
    define_custom_variable(&var->gen);
}

void DefineCustomStringVariable ( const char *  name,
const char *  short_desc,
const char *  long_desc,
char **  valueAddr,
const char *  bootValue,
GucContext  context,
int  flags,
GucStringCheckHook  check_hook,
GucStringAssignHook  assign_hook,
GucShowHook  show_hook 
)
void EmitWarningsOnPlaceholders ( const char *  className  ) 

Definition at line 6744 of file guc.c.

References ereport, errcode(), errmsg(), config_generic::flags, GUC_CUSTOM_PLACEHOLDER, GUC_QUALIFIER_SEPARATOR, i, config_generic::name, and WARNING.

Referenced by _PG_init().

{
    int         classLen = strlen(className);
    int         i;

    for (i = 0; i < num_guc_variables; i++)
    {
        struct config_generic *var = guc_variables[i];

        if ((var->flags & GUC_CUSTOM_PLACEHOLDER) != 0 &&
            strncmp(className, var->name, classLen) == 0 &&
            var->name[classLen] == GUC_QUALIFIER_SEPARATOR)
        {
            ereport(WARNING,
                    (errcode(ERRCODE_UNDEFINED_OBJECT),
                     errmsg("unrecognized configuration parameter \"%s\"",
                            var->name)));
        }
    }
}

void ExecSetVariableStmt ( VariableSetStmt stmt  ) 

Definition at line 6191 of file guc.c.

References DefElem::arg, VariableSetStmt::args, Assert, DefElem::defname, elog, ereport, errcode(), errmsg(), ERROR, ExtractSetVariableArgs(), GUC_ACTION_LOCAL, ImportSnapshot(), VariableSetStmt::is_local, IsA, VariableSetStmt::kind, lfirst, linitial, list_make1, VariableSetStmt::name, nodeTag, NULL, PGC_S_SESSION, PGC_SUSET, PGC_USERSET, ResetAllOptions(), set_config_option(), SetPGVariable(), strVal, superuser(), T_String, A_Const::val, VAR_RESET, VAR_RESET_ALL, VAR_SET_CURRENT, VAR_SET_DEFAULT, VAR_SET_MULTI, and VAR_SET_VALUE.

Referenced by standard_ProcessUtility().

{
    GucAction   action = stmt->is_local ? GUC_ACTION_LOCAL : GUC_ACTION_SET;

    switch (stmt->kind)
    {
        case VAR_SET_VALUE:
        case VAR_SET_CURRENT:
            (void) set_config_option(stmt->name,
                                     ExtractSetVariableArgs(stmt),
                                     (superuser() ? PGC_SUSET : PGC_USERSET),
                                     PGC_S_SESSION,
                                     action,
                                     true,
                                     0);
            break;
        case VAR_SET_MULTI:

            /*
             * Special-case SQL syntaxes.  The TRANSACTION and SESSION
             * CHARACTERISTICS cases effectively set more than one variable
             * per statement.  TRANSACTION SNAPSHOT only takes one argument,
             * but we put it here anyway since it's a special case and not
             * related to any GUC variable.
             */
            if (strcmp(stmt->name, "TRANSACTION") == 0)
            {
                ListCell   *head;

                foreach(head, stmt->args)
                {
                    DefElem    *item = (DefElem *) lfirst(head);

                    if (strcmp(item->defname, "transaction_isolation") == 0)
                        SetPGVariable("transaction_isolation",
                                      list_make1(item->arg), stmt->is_local);
                    else if (strcmp(item->defname, "transaction_read_only") == 0)
                        SetPGVariable("transaction_read_only",
                                      list_make1(item->arg), stmt->is_local);
                    else if (strcmp(item->defname, "transaction_deferrable") == 0)
                        SetPGVariable("transaction_deferrable",
                                      list_make1(item->arg), stmt->is_local);
                    else
                        elog(ERROR, "unexpected SET TRANSACTION element: %s",
                             item->defname);
                }
            }
            else if (strcmp(stmt->name, "SESSION CHARACTERISTICS") == 0)
            {
                ListCell   *head;

                foreach(head, stmt->args)
                {
                    DefElem    *item = (DefElem *) lfirst(head);

                    if (strcmp(item->defname, "transaction_isolation") == 0)
                        SetPGVariable("default_transaction_isolation",
                                      list_make1(item->arg), stmt->is_local);
                    else if (strcmp(item->defname, "transaction_read_only") == 0)
                        SetPGVariable("default_transaction_read_only",
                                      list_make1(item->arg), stmt->is_local);
                    else if (strcmp(item->defname, "transaction_deferrable") == 0)
                        SetPGVariable("default_transaction_deferrable",
                                      list_make1(item->arg), stmt->is_local);
                    else
                        elog(ERROR, "unexpected SET SESSION element: %s",
                             item->defname);
                }
            }
            else if (strcmp(stmt->name, "TRANSACTION SNAPSHOT") == 0)
            {
                A_Const    *con = (A_Const *) linitial(stmt->args);

                if (stmt->is_local)
                    ereport(ERROR,
                            (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                             errmsg("SET LOCAL TRANSACTION SNAPSHOT is not implemented")));
                Assert(IsA(con, A_Const));
                Assert(nodeTag(&con->val) == T_String);
                ImportSnapshot(strVal(&con->val));
            }
            else
                elog(ERROR, "unexpected SET MULTI element: %s",
                     stmt->name);
            break;
        case VAR_SET_DEFAULT:
        case VAR_RESET:
            (void) set_config_option(stmt->name,
                                     NULL,
                                     (superuser() ? PGC_SUSET : PGC_USERSET),
                                     PGC_S_SESSION,
                                     action,
                                     true,
                                     0);
            break;
        case VAR_RESET_ALL:
            ResetAllOptions();
            break;
    }
}

char* ExtractSetVariableArgs ( VariableSetStmt stmt  ) 
void FreeConfigVariables ( ConfigVariable list  ) 
const char* GetConfigOption ( const char *  name,
bool  missing_ok,
bool  restrict_superuser 
)

Definition at line 5962 of file guc.c.

References config_enum_lookup_by_value(), ereport, errcode(), errmsg(), ERROR, find_option(), config_generic::flags, GUC_SUPERUSER_ONLY, NULL, PGC_BOOL, PGC_ENUM, PGC_INT, PGC_REAL, PGC_STRING, snprintf(), superuser(), and config_generic::vartype.

Referenced by applyRemoteGucs(), and PostmasterMain().

{
    struct config_generic *record;
    static char buffer[256];

    record = find_option(name, false, ERROR);
    if (record == NULL)
    {
        if (missing_ok)
            return NULL;
        ereport(ERROR,
                (errcode(ERRCODE_UNDEFINED_OBJECT),
                 errmsg("unrecognized configuration parameter \"%s\"",
                        name)));
    }
    if (restrict_superuser &&
        (record->flags & GUC_SUPERUSER_ONLY) &&
        !superuser())
        ereport(ERROR,
                (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
                 errmsg("must be superuser to examine \"%s\"", name)));

    switch (record->vartype)
    {
        case PGC_BOOL:
            return *((struct config_bool *) record)->variable ? "on" : "off";

        case PGC_INT:
            snprintf(buffer, sizeof(buffer), "%d",
                     *((struct config_int *) record)->variable);
            return buffer;

        case PGC_REAL:
            snprintf(buffer, sizeof(buffer), "%g",
                     *((struct config_real *) record)->variable);
            return buffer;

        case PGC_STRING:
            return *((struct config_string *) record)->variable;

        case PGC_ENUM:
            return config_enum_lookup_by_value((struct config_enum *) record,
                                 *((struct config_enum *) record)->variable);
    }
    return NULL;
}

char* GetConfigOptionByName ( const char *  name,
const char **  varname 
)

Definition at line 6910 of file guc.c.

References _ShowOption(), ereport, errcode(), errmsg(), ERROR, find_option(), config_generic::flags, GUC_SUPERUSER_ONLY, config_generic::name, NULL, and superuser().

Referenced by ExtractSetVariableArgs(), GetPGVariableResultDesc(), set_config_by_name(), show_config_by_name(), ShowGUCConfigOption(), and tsa_tsearch2().

{
    struct config_generic *record;

    record = find_option(name, false, ERROR);
    if (record == NULL)
        ereport(ERROR,
                (errcode(ERRCODE_UNDEFINED_OBJECT),
               errmsg("unrecognized configuration parameter \"%s\"", name)));
    if ((record->flags & GUC_SUPERUSER_ONLY) && !superuser())
        ereport(ERROR,
                (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
                 errmsg("must be superuser to examine \"%s\"", name)));

    if (varname)
        *varname = record->name;

    return _ShowOption(record, true);
}

void GetConfigOptionByNum ( int  varnum,
const char **  values,
bool noshow 
)

Definition at line 6935 of file guc.c.

References _ShowOption(), Assert, config_enum::boot_val, config_string::boot_val, config_real::boot_val, config_int::boot_val, config_bool::boot_val, buf, config_enum_get_options(), config_enum_lookup_by_value(), config_group_names, config_type_names, config_generic::context, config_generic::flags, config_generic::group, GUC_NO_SHOW_ALL, GUC_SUPERUSER_ONLY, GUC_UNIT_BLOCKS, GUC_UNIT_KB, GUC_UNIT_MEMORY, GUC_UNIT_MIN, GUC_UNIT_MS, GUC_UNIT_S, GUC_UNIT_TIME, GUC_UNIT_XBLOCKS, GucContext_Names, GucSource_Names, config_generic::long_desc, config_real::max, config_int::max, config_real::min, config_int::min, config_generic::name, NULL, PGC_BOOL, PGC_ENUM, PGC_INT, PGC_REAL, PGC_S_FILE, PGC_STRING, pstrdup(), config_enum::reset_val, config_string::reset_val, config_real::reset_val, config_int::reset_val, config_bool::reset_val, config_generic::short_desc, snprintf(), config_generic::source, config_generic::sourcefile, config_generic::sourceline, superuser(), and config_generic::vartype.

Referenced by show_all_settings().

{
    char        buffer[256];
    struct config_generic *conf;

    /* check requested variable number valid */
    Assert((varnum >= 0) && (varnum < num_guc_variables));

    conf = guc_variables[varnum];

    if (noshow)
    {
        if ((conf->flags & GUC_NO_SHOW_ALL) ||
            ((conf->flags & GUC_SUPERUSER_ONLY) && !superuser()))
            *noshow = true;
        else
            *noshow = false;
    }

    /* first get the generic attributes */

    /* name */
    values[0] = conf->name;

    /* setting : use _ShowOption in order to avoid duplicating the logic */
    values[1] = _ShowOption(conf, false);

    /* unit */
    if (conf->vartype == PGC_INT)
    {
        static char buf[8];

        switch (conf->flags & (GUC_UNIT_MEMORY | GUC_UNIT_TIME))
        {
            case GUC_UNIT_KB:
                values[2] = "kB";
                break;
            case GUC_UNIT_BLOCKS:
                snprintf(buf, sizeof(buf), "%dkB", BLCKSZ / 1024);
                values[2] = buf;
                break;
            case GUC_UNIT_XBLOCKS:
                snprintf(buf, sizeof(buf), "%dkB", XLOG_BLCKSZ / 1024);
                values[2] = buf;
                break;
            case GUC_UNIT_MS:
                values[2] = "ms";
                break;
            case GUC_UNIT_S:
                values[2] = "s";
                break;
            case GUC_UNIT_MIN:
                values[2] = "min";
                break;
            default:
                values[2] = "";
                break;
        }
    }
    else
        values[2] = NULL;

    /* group */
    values[3] = config_group_names[conf->group];

    /* short_desc */
    values[4] = conf->short_desc;

    /* extra_desc */
    values[5] = conf->long_desc;

    /* context */
    values[6] = GucContext_Names[conf->context];

    /* vartype */
    values[7] = config_type_names[conf->vartype];

    /* source */
    values[8] = GucSource_Names[conf->source];

    /* now get the type specifc attributes */
    switch (conf->vartype)
    {
        case PGC_BOOL:
            {
                struct config_bool *lconf = (struct config_bool *) conf;

                /* min_val */
                values[9] = NULL;

                /* max_val */
                values[10] = NULL;

                /* enumvals */
                values[11] = NULL;

                /* boot_val */
                values[12] = pstrdup(lconf->boot_val ? "on" : "off");

                /* reset_val */
                values[13] = pstrdup(lconf->reset_val ? "on" : "off");
            }
            break;

        case PGC_INT:
            {
                struct config_int *lconf = (struct config_int *) conf;

                /* min_val */
                snprintf(buffer, sizeof(buffer), "%d", lconf->min);
                values[9] = pstrdup(buffer);

                /* max_val */
                snprintf(buffer, sizeof(buffer), "%d", lconf->max);
                values[10] = pstrdup(buffer);

                /* enumvals */
                values[11] = NULL;

                /* boot_val */
                snprintf(buffer, sizeof(buffer), "%d", lconf->boot_val);
                values[12] = pstrdup(buffer);

                /* reset_val */
                snprintf(buffer, sizeof(buffer), "%d", lconf->reset_val);
                values[13] = pstrdup(buffer);
            }
            break;

        case PGC_REAL:
            {
                struct config_real *lconf = (struct config_real *) conf;

                /* min_val */
                snprintf(buffer, sizeof(buffer), "%g", lconf->min);
                values[9] = pstrdup(buffer);

                /* max_val */
                snprintf(buffer, sizeof(buffer), "%g", lconf->max);
                values[10] = pstrdup(buffer);

                /* enumvals */
                values[11] = NULL;

                /* boot_val */
                snprintf(buffer, sizeof(buffer), "%g", lconf->boot_val);
                values[12] = pstrdup(buffer);

                /* reset_val */
                snprintf(buffer, sizeof(buffer), "%g", lconf->reset_val);
                values[13] = pstrdup(buffer);
            }
            break;

        case PGC_STRING:
            {
                struct config_string *lconf = (struct config_string *) conf;

                /* min_val */
                values[9] = NULL;

                /* max_val */
                values[10] = NULL;

                /* enumvals */
                values[11] = NULL;

                /* boot_val */
                if (lconf->boot_val == NULL)
                    values[12] = NULL;
                else
                    values[12] = pstrdup(lconf->boot_val);

                /* reset_val */
                if (lconf->reset_val == NULL)
                    values[13] = NULL;
                else
                    values[13] = pstrdup(lconf->reset_val);
            }
            break;

        case PGC_ENUM:
            {
                struct config_enum *lconf = (struct config_enum *) conf;

                /* min_val */
                values[9] = NULL;

                /* max_val */
                values[10] = NULL;

                /* enumvals */

                /*
                 * NOTE! enumvals with double quotes in them are not
                 * supported!
                 */
                values[11] = config_enum_get_options((struct config_enum *) conf,
                                                     "{\"", "\"}", "\",\"");

                /* boot_val */
                values[12] = pstrdup(config_enum_lookup_by_value(lconf,
                                                           lconf->boot_val));

                /* reset_val */
                values[13] = pstrdup(config_enum_lookup_by_value(lconf,
                                                          lconf->reset_val));
            }
            break;

        default:
            {
                /*
                 * should never get here, but in case we do, set 'em to NULL
                 */

                /* min_val */
                values[9] = NULL;

                /* max_val */
                values[10] = NULL;

                /* enumvals */
                values[11] = NULL;

                /* boot_val */
                values[12] = NULL;

                /* reset_val */
                values[13] = NULL;
            }
            break;
    }

    /*
     * If the setting came from a config file, set the source location. For
     * security reasons, we don't show source file/line number for
     * non-superusers.
     */
    if (conf->source == PGC_S_FILE && superuser())
    {
        values[14] = conf->sourcefile;
        snprintf(buffer, sizeof(buffer), "%d", conf->sourceline);
        values[15] = pstrdup(buffer);
    }
    else
    {
        values[14] = NULL;
        values[15] = NULL;
    }
}

const char* GetConfigOptionResetString ( const char *  name  ) 

Definition at line 6017 of file guc.c.

References config_enum_lookup_by_value(), ereport, errcode(), errmsg(), ERROR, find_option(), config_generic::flags, GUC_SUPERUSER_ONLY, NULL, PGC_BOOL, PGC_ENUM, PGC_INT, PGC_REAL, PGC_STRING, snprintf(), superuser(), and config_generic::vartype.

Referenced by check_datestyle().

{
    struct config_generic *record;
    static char buffer[256];

    record = find_option(name, false, ERROR);
    if (record == NULL)
        ereport(ERROR,
                (errcode(ERRCODE_UNDEFINED_OBJECT),
               errmsg("unrecognized configuration parameter \"%s\"", name)));
    if ((record->flags & GUC_SUPERUSER_ONLY) && !superuser())
        ereport(ERROR,
                (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
                 errmsg("must be superuser to examine \"%s\"", name)));

    switch (record->vartype)
    {
        case PGC_BOOL:
            return ((struct config_bool *) record)->reset_val ? "on" : "off";

        case PGC_INT:
            snprintf(buffer, sizeof(buffer), "%d",
                     ((struct config_int *) record)->reset_val);
            return buffer;

        case PGC_REAL:
            snprintf(buffer, sizeof(buffer), "%g",
                     ((struct config_real *) record)->reset_val);
            return buffer;

        case PGC_STRING:
            return ((struct config_string *) record)->reset_val;

        case PGC_ENUM:
            return config_enum_lookup_by_value((struct config_enum *) record,
                                 ((struct config_enum *) record)->reset_val);
    }
    return NULL;
}

int GetNumConfigOptions ( void   ) 

Definition at line 7191 of file guc.c.

Referenced by GucInfoMain(), and show_all_settings().

{
    return num_guc_variables;
}

void GetPGVariable ( const char *  name,
DestReceiver dest 
)

Definition at line 6770 of file guc.c.

References guc_name_compare(), ShowAllGUCConfig(), and ShowGUCConfigOption().

Referenced by standard_ProcessUtility().

{
    if (guc_name_compare(name, "all") == 0)
        ShowAllGUCConfig(dest);
    else
        ShowGUCConfigOption(name, dest);
}

TupleDesc GetPGVariableResultDesc ( const char *  name  ) 

Definition at line 6779 of file guc.c.

References CreateTemplateTupleDesc(), GetConfigOptionByName(), guc_name_compare(), TEXTOID, and TupleDescInitEntry().

Referenced by UtilityTupleDescriptor().

{
    TupleDesc   tupdesc;

    if (guc_name_compare(name, "all") == 0)
    {
        /* need a tuple descriptor representing three TEXT columns */
        tupdesc = CreateTemplateTupleDesc(3, false);
        TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
                           TEXTOID, -1, 0);
        TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting",
                           TEXTOID, -1, 0);
        TupleDescInitEntry(tupdesc, (AttrNumber) 3, "description",
                           TEXTOID, -1, 0);
    }
    else
    {
        const char *varname;

        /* Get the canonical spelling of name */
        (void) GetConfigOptionByName(name, &varname);

        /* need a tuple descriptor representing a single TEXT column */
        tupdesc = CreateTemplateTupleDesc(1, false);
        TupleDescInitEntry(tupdesc, (AttrNumber) 1, varname,
                           TEXTOID, -1, 0);
    }
    return tupdesc;
}

void GUC_check_errcode ( int  sqlerrcode  ) 
ArrayType* GUCArrayAdd ( ArrayType array,
const char *  name,
const char *  value 
)

Definition at line 7829 of file guc.c.

References ARR_DIMS, ARR_ELEMTYPE, ARR_LBOUND, ARR_NDIM, array_ref(), array_set(), Assert, construct_array(), CStringGetTextDatum, find_option(), config_generic::name, palloc(), TextDatumGetCString, TEXTOID, validate_option_array_item(), and WARNING.

Referenced by AlterSetting(), and update_proconfig_value().

{
    struct config_generic *record;
    Datum       datum;
    char       *newval;
    ArrayType  *a;

    Assert(name);
    Assert(value);

    /* test if the option is valid and we're allowed to set it */
    (void) validate_option_array_item(name, value, false);

    /* normalize name (converts obsolete GUC names to modern spellings) */
    record = find_option(name, false, WARNING);
    if (record)
        name = record->name;

    /* build new item for array */
    newval = palloc(strlen(name) + 1 + strlen(value) + 1);
    sprintf(newval, "%s=%s", name, value);
    datum = CStringGetTextDatum(newval);

    if (array)
    {
        int         index;
        bool        isnull;
        int         i;

        Assert(ARR_ELEMTYPE(array) == TEXTOID);
        Assert(ARR_NDIM(array) == 1);
        Assert(ARR_LBOUND(array)[0] == 1);

        index = ARR_DIMS(array)[0] + 1; /* add after end */

        for (i = 1; i <= ARR_DIMS(array)[0]; i++)
        {
            Datum       d;
            char       *current;

            d = array_ref(array, 1, &i,
                          -1 /* varlenarray */ ,
                          -1 /* TEXT's typlen */ ,
                          false /* TEXT's typbyval */ ,
                          'i' /* TEXT's typalign */ ,
                          &isnull);
            if (isnull)
                continue;
            current = TextDatumGetCString(d);

            /* check for match up through and including '=' */
            if (strncmp(current, newval, strlen(name) + 1) == 0)
            {
                index = i;
                break;
            }
        }

        a = array_set(array, 1, &index,
                      datum,
                      false,
                      -1 /* varlena array */ ,
                      -1 /* TEXT's typlen */ ,
                      false /* TEXT's typbyval */ ,
                      'i' /* TEXT's typalign */ );
    }
    else
        a = construct_array(&datum, 1,
                            TEXTOID,
                            -1, false, 'i');

    return a;
}

ArrayType* GUCArrayDelete ( ArrayType array,
const char *  name 
)

Definition at line 7910 of file guc.c.

References ARR_DIMS, array_ref(), array_set(), Assert, construct_array(), find_option(), config_generic::name, NULL, TextDatumGetCString, TEXTOID, val, validate_option_array_item(), and WARNING.

Referenced by AlterSetting(), and update_proconfig_value().

{
    struct config_generic *record;
    ArrayType  *newarray;
    int         i;
    int         index;

    Assert(name);

    /* test if the option is valid and we're allowed to set it */
    (void) validate_option_array_item(name, NULL, false);

    /* normalize name (converts obsolete GUC names to modern spellings) */
    record = find_option(name, false, WARNING);
    if (record)
        name = record->name;

    /* if array is currently null, then surely nothing to delete */
    if (!array)
        return NULL;

    newarray = NULL;
    index = 1;

    for (i = 1; i <= ARR_DIMS(array)[0]; i++)
    {
        Datum       d;
        char       *val;
        bool        isnull;

        d = array_ref(array, 1, &i,
                      -1 /* varlenarray */ ,
                      -1 /* TEXT's typlen */ ,
                      false /* TEXT's typbyval */ ,
                      'i' /* TEXT's typalign */ ,
                      &isnull);
        if (isnull)
            continue;
        val = TextDatumGetCString(d);

        /* ignore entry if it's what we want to delete */
        if (strncmp(val, name, strlen(name)) == 0
            && val[strlen(name)] == '=')
            continue;

        /* else add it to the output array */
        if (newarray)
            newarray = array_set(newarray, 1, &index,
                                 d,
                                 false,
                                 -1 /* varlenarray */ ,
                                 -1 /* TEXT's typlen */ ,
                                 false /* TEXT's typbyval */ ,
                                 'i' /* TEXT's typalign */ );
        else
            newarray = construct_array(&d, 1,
                                       TEXTOID,
                                       -1, false, 'i');

        index++;
    }

    return newarray;
}

ArrayType* GUCArrayReset ( ArrayType array  ) 

Definition at line 7982 of file guc.c.

References ARR_DIMS, array_ref(), array_set(), construct_array(), NULL, pfree(), superuser(), TextDatumGetCString, TEXTOID, val, and validate_option_array_item().

Referenced by AlterSetting().

{
    ArrayType  *newarray;
    int         i;
    int         index;

    /* if array is currently null, nothing to do */
    if (!array)
        return NULL;

    /* if we're superuser, we can delete everything, so just do it */
    if (superuser())
        return NULL;

    newarray = NULL;
    index = 1;

    for (i = 1; i <= ARR_DIMS(array)[0]; i++)
    {
        Datum       d;
        char       *val;
        char       *eqsgn;
        bool        isnull;

        d = array_ref(array, 1, &i,
                      -1 /* varlenarray */ ,
                      -1 /* TEXT's typlen */ ,
                      false /* TEXT's typbyval */ ,
                      'i' /* TEXT's typalign */ ,
                      &isnull);
        if (isnull)
            continue;
        val = TextDatumGetCString(d);

        eqsgn = strchr(val, '=');
        *eqsgn = '\0';

        /* skip if we have permission to delete it */
        if (validate_option_array_item(val, NULL, true))
            continue;

        /* else add it to the output array */
        if (newarray)
            newarray = array_set(newarray, 1, &index,
                                 d,
                                 false,
                                 -1 /* varlenarray */ ,
                                 -1 /* TEXT's typlen */ ,
                                 false /* TEXT's typbyval */ ,
                                 'i' /* TEXT's typalign */ );
        else
            newarray = construct_array(&d, 1,
                                       TEXTOID,
                                       -1, false, 'i');

        index++;
        pfree(val);
    }

    return newarray;
}

void InitializeGUCOptions ( void   ) 

Definition at line 3876 of file guc.c.

References build_guc_variables(), i, InitializeGUCOptionsFromEnvironment(), InitializeOneGUCOption(), pg_timezone_initialize(), PGC_POSTMASTER, PGC_S_OVERRIDE, and SetConfigOption().

Referenced by AuxiliaryProcessMain(), PostgresMain(), and PostmasterMain().

{
    int         i;

    /*
     * Before log_line_prefix could possibly receive a nonempty setting, make
     * sure that timezone processing is minimally alive (see elog.c).
     */
    pg_timezone_initialize();

    /*
     * Build sorted array of all GUC variables.
     */
    build_guc_variables();

    /*
     * Load all variables with their compiled-in defaults, and initialize
     * status fields as needed.
     */
    for (i = 0; i < num_guc_variables; i++)
    {
        InitializeOneGUCOption(guc_variables[i]);
    }

    guc_dirty = false;

    reporting_enabled = false;

    /*
     * Prevent any attempt to override the transaction modes from
     * non-interactive sources.
     */
    SetConfigOption("transaction_isolation", "default",
                    PGC_POSTMASTER, PGC_S_OVERRIDE);
    SetConfigOption("transaction_read_only", "no",
                    PGC_POSTMASTER, PGC_S_OVERRIDE);
    SetConfigOption("transaction_deferrable", "no",
                    PGC_POSTMASTER, PGC_S_OVERRIDE);

    /*
     * For historical reasons, some GUC parameters can receive defaults from
     * environment variables.  Process those settings.
     */
    InitializeGUCOptionsFromEnvironment();
}

int NewGUCNestLevel ( void   ) 
bool parse_int ( const char *  value,
int *  result,
int  flags,
const char **  hintmsg 
)

Definition at line 4800 of file guc.c.

References gettext_noop, GUC_UNIT_BLOCKS, GUC_UNIT_KB, GUC_UNIT_MEMORY, GUC_UNIT_MIN, GUC_UNIT_MS, GUC_UNIT_S, GUC_UNIT_TIME, GUC_UNIT_XBLOCKS, KB_PER_GB, KB_PER_MB, and val.

Referenced by parse_one_reloption(), and set_config_option().

{
    int64       val;
    char       *endptr;

    /* To suppress compiler warnings, always set output params */
    if (result)
        *result = 0;
    if (hintmsg)
        *hintmsg = NULL;

    /* We assume here that int64 is at least as wide as long */
    errno = 0;
    val = strtol(value, &endptr, 0);

    if (endptr == value)
        return false;           /* no HINT for integer syntax error */

    if (errno == ERANGE || val != (int64) ((int32) val))
    {
        if (hintmsg)
            *hintmsg = gettext_noop("Value exceeds integer range.");
        return false;
    }

    /* allow whitespace between integer and unit */
    while (isspace((unsigned char) *endptr))
        endptr++;

    /* Handle possible unit */
    if (*endptr != '\0')
    {
        /*
         * Note: the multiple-switch coding technique here is a bit tedious,
         * but seems necessary to avoid intermediate-value overflows.
         */
        if (flags & GUC_UNIT_MEMORY)
        {
            /* Set hint for use if no match or trailing garbage */
            if (hintmsg)
                *hintmsg = gettext_noop("Valid units for this parameter are \"kB\", \"MB\", and \"GB\".");

#if BLCKSZ < 1024 || BLCKSZ > (1024*1024)
#error BLCKSZ must be between 1KB and 1MB
#endif
#if XLOG_BLCKSZ < 1024 || XLOG_BLCKSZ > (1024*1024)
#error XLOG_BLCKSZ must be between 1KB and 1MB
#endif

            if (strncmp(endptr, "kB", 2) == 0)
            {
                endptr += 2;
                switch (flags & GUC_UNIT_MEMORY)
                {
                    case GUC_UNIT_BLOCKS:
                        val /= (BLCKSZ / 1024);
                        break;
                    case GUC_UNIT_XBLOCKS:
                        val /= (XLOG_BLCKSZ / 1024);
                        break;
                }
            }
            else if (strncmp(endptr, "MB", 2) == 0)
            {
                endptr += 2;
                switch (flags & GUC_UNIT_MEMORY)
                {
                    case GUC_UNIT_KB:
                        val *= KB_PER_MB;
                        break;
                    case GUC_UNIT_BLOCKS:
                        val *= KB_PER_MB / (BLCKSZ / 1024);
                        break;
                    case GUC_UNIT_XBLOCKS:
                        val *= KB_PER_MB / (XLOG_BLCKSZ / 1024);
                        break;
                }
            }
            else if (strncmp(endptr, "GB", 2) == 0)
            {
                endptr += 2;
                switch (flags & GUC_UNIT_MEMORY)
                {
                    case GUC_UNIT_KB:
                        val *= KB_PER_GB;
                        break;
                    case GUC_UNIT_BLOCKS:
                        val *= KB_PER_GB / (BLCKSZ / 1024);
                        break;
                    case GUC_UNIT_XBLOCKS:
                        val *= KB_PER_GB / (XLOG_BLCKSZ / 1024);
                        break;
                }
            }
        }
        else if (flags & GUC_UNIT_TIME)
        {
            /* Set hint for use if no match or trailing garbage */
            if (hintmsg)
                *hintmsg = gettext_noop("Valid units for this parameter are \"ms\", \"s\", \"min\", \"h\", and \"d\".");

            if (strncmp(endptr, "ms", 2) == 0)
            {
                endptr += 2;
                switch (flags & GUC_UNIT_TIME)
                {
                    case GUC_UNIT_S:
                        val /= MS_PER_S;
                        break;
                    case GUC_UNIT_MIN:
                        val /= MS_PER_MIN;
                        break;
                }
            }
            else if (strncmp(endptr, "s", 1) == 0)
            {
                endptr += 1;
                switch (flags & GUC_UNIT_TIME)
                {
                    case GUC_UNIT_MS:
                        val *= MS_PER_S;
                        break;
                    case GUC_UNIT_MIN:
                        val /= S_PER_MIN;
                        break;
                }
            }
            else if (strncmp(endptr, "min", 3) == 0)
            {
                endptr += 3;
                switch (flags & GUC_UNIT_TIME)
                {
                    case GUC_UNIT_MS:
                        val *= MS_PER_MIN;
                        break;
                    case GUC_UNIT_S:
                        val *= S_PER_MIN;
                        break;
                }
            }
            else if (strncmp(endptr, "h", 1) == 0)
            {
                endptr += 1;
                switch (flags & GUC_UNIT_TIME)
                {
                    case GUC_UNIT_MS:
                        val *= MS_PER_H;
                        break;
                    case GUC_UNIT_S:
                        val *= S_PER_H;
                        break;
                    case GUC_UNIT_MIN:
                        val *= MIN_PER_H;
                        break;
                }
            }
            else if (strncmp(endptr, "d", 1) == 0)
            {
                endptr += 1;
                switch (flags & GUC_UNIT_TIME)
                {
                    case GUC_UNIT_MS:
                        val *= MS_PER_D;
                        break;
                    case GUC_UNIT_S:
                        val *= S_PER_D;
                        break;
                    case GUC_UNIT_MIN:
                        val *= MIN_PER_D;
                        break;
                }
            }
        }

        /* allow whitespace after unit */
        while (isspace((unsigned char) *endptr))
            endptr++;

        if (*endptr != '\0')
            return false;       /* appropriate hint, if any, already set */

        /* Check for overflow due to units conversion */
        if (val != (int64) ((int32) val))
        {
            if (hintmsg)
                *hintmsg = gettext_noop("Value exceeds integer range.");
            return false;
        }
    }

    if (result)
        *result = (int) val;
    return true;
}

bool parse_real ( const char *  value,
double *  result 
)

Definition at line 5003 of file guc.c.

References val.

Referenced by parse_one_reloption(), and set_config_option().

{
    double      val;
    char       *endptr;

    if (result)
        *result = 0;            /* suppress compiler warning */

    errno = 0;
    val = strtod(value, &endptr);
    if (endptr == value || errno == ERANGE)
        return false;

    /* allow whitespace after number */
    while (isspace((unsigned char) *endptr))
        endptr++;
    if (*endptr != '\0')
        return false;

    if (result)
        *result = val;
    return true;
}

bool ParseConfigDirectory ( const char *  includedir,
const char *  calling_file,
int  depth,
int  elevel,
ConfigVariable **  head_p,
ConfigVariable **  tail_p 
)
bool ParseConfigFile ( const char *  config_file,
const char *  calling_file,
bool  strict,
int  depth,
int  elevel,
ConfigVariable **  head_p,
ConfigVariable **  tail_p 
)
bool ParseConfigFp ( FILE *  fp,
const char *  config_file,
int  depth,
int  elevel,
ConfigVariable **  head_p,
ConfigVariable **  tail_p 
)
void ParseLongOption ( const char *  string,
char **  name,
char **  value 
)

Definition at line 7733 of file guc.c.

References AssertArg, FATAL, guc_malloc(), guc_strdup(), and strlcpy().

Referenced by AuxiliaryProcessMain(), PostmasterMain(), process_postgres_switches(), and ProcessGUCArray().

{
    size_t      equal_pos;
    char       *cp;

    AssertArg(string);
    AssertArg(name);
    AssertArg(value);

    equal_pos = strcspn(string, "=");

    if (string[equal_pos] == '=')
    {
        *name = guc_malloc(FATAL, equal_pos + 1);
        strlcpy(*name, string, equal_pos + 1);

        *value = guc_strdup(FATAL, &string[equal_pos + 1]);
    }
    else
    {
        /* no equal sign in string */
        *name = guc_strdup(FATAL, string);
        *value = NULL;
    }

    for (cp = *name; *cp; cp++)
        if (*cp == '-')
            *cp = '_';
}

void ProcessConfigFile ( GucContext  context  ) 
void ProcessGUCArray ( ArrayType array,
GucContext  context,
GucSource  source,
GucAction  action 
)

Definition at line 7771 of file guc.c.

References ARR_DIMS, ARR_ELEMTYPE, ARR_LBOUND, ARR_NDIM, array_ref(), Assert, ereport, errcode(), errmsg(), free, name, NULL, ParseLongOption(), pfree(), set_config_option(), TextDatumGetCString, TEXTOID, value, and WARNING.

Referenced by ApplySetting(), fmgr_security_definer(), and ProcedureCreate().

{
    int         i;

    Assert(array != NULL);
    Assert(ARR_ELEMTYPE(array) == TEXTOID);
    Assert(ARR_NDIM(array) == 1);
    Assert(ARR_LBOUND(array)[0] == 1);

    for (i = 1; i <= ARR_DIMS(array)[0]; i++)
    {
        Datum       d;
        bool        isnull;
        char       *s;
        char       *name;
        char       *value;

        d = array_ref(array, 1, &i,
                      -1 /* varlenarray */ ,
                      -1 /* TEXT's typlen */ ,
                      false /* TEXT's typbyval */ ,
                      'i' /* TEXT's typalign */ ,
                      &isnull);

        if (isnull)
            continue;

        s = TextDatumGetCString(d);

        ParseLongOption(s, &name, &value);
        if (!value)
        {
            ereport(WARNING,
                    (errcode(ERRCODE_SYNTAX_ERROR),
                     errmsg("could not parse setting for parameter \"%s\"",
                            name)));
            free(name);
            continue;
        }

        (void) set_config_option(name, value,
                                 context, source,
                                 action, true, 0);

        free(name);
        if (value)
            free(value);
        pfree(s);
    }
}

void ResetAllOptions ( void   ) 

Definition at line 4249 of file guc.c.

References config_enum::assign_hook, config_string::assign_hook, config_real::assign_hook, config_int::assign_hook, config_bool::assign_hook, config_generic::context, config_generic::extra, config_generic::flags, config_enum::gen, config_string::gen, config_real::gen, config_int::gen, config_bool::gen, GUC_ACTION_SET, GUC_NO_RESET_ALL, GUC_REPORT, i, PGC_BOOL, PGC_ENUM, PGC_INT, PGC_REAL, PGC_S_OVERRIDE, PGC_STRING, PGC_SUSET, PGC_USERSET, push_old_value(), ReportGUCOption(), config_enum::reset_extra, config_string::reset_extra, config_real::reset_extra, config_int::reset_extra, config_bool::reset_extra, config_generic::reset_scontext, config_generic::reset_source, config_enum::reset_val, config_string::reset_val, config_real::reset_val, config_int::reset_val, config_bool::reset_val, config_generic::scontext, set_extra_field(), set_string_field(), config_generic::source, config_enum::variable, config_string::variable, config_real::variable, config_int::variable, config_bool::variable, and config_generic::vartype.

Referenced by DiscardAll(), and ExecSetVariableStmt().

{
    int         i;

    for (i = 0; i < num_guc_variables; i++)
    {
        struct config_generic *gconf = guc_variables[i];

        /* Don't reset non-SET-able values */
        if (gconf->context != PGC_SUSET &&
            gconf->context != PGC_USERSET)
            continue;
        /* Don't reset if special exclusion from RESET ALL */
        if (gconf->flags & GUC_NO_RESET_ALL)
            continue;
        /* No need to reset if wasn't SET */
        if (gconf->source <= PGC_S_OVERRIDE)
            continue;

        /* Save old value to support transaction abort */
        push_old_value(gconf, GUC_ACTION_SET);

        switch (gconf->vartype)
        {
            case PGC_BOOL:
                {
                    struct config_bool *conf = (struct config_bool *) gconf;

                    if (conf->assign_hook)
                        (*conf->assign_hook) (conf->reset_val,
                                              conf->reset_extra);
                    *conf->variable = conf->reset_val;
                    set_extra_field(&conf->gen, &conf->gen.extra,
                                    conf->reset_extra);
                    break;
                }
            case PGC_INT:
                {
                    struct config_int *conf = (struct config_int *) gconf;

                    if (conf->assign_hook)
                        (*conf->assign_hook) (conf->reset_val,
                                              conf->reset_extra);
                    *conf->variable = conf->reset_val;
                    set_extra_field(&conf->gen, &conf->gen.extra,
                                    conf->reset_extra);
                    break;
                }
            case PGC_REAL:
                {
                    struct config_real *conf = (struct config_real *) gconf;

                    if (conf->assign_hook)
                        (*conf->assign_hook) (conf->reset_val,
                                              conf->reset_extra);
                    *conf->variable = conf->reset_val;
                    set_extra_field(&conf->gen, &conf->gen.extra,
                                    conf->reset_extra);
                    break;
                }
            case PGC_STRING:
                {
                    struct config_string *conf = (struct config_string *) gconf;

                    if (conf->assign_hook)
                        (*conf->assign_hook) (conf->reset_val,
                                              conf->reset_extra);
                    set_string_field(conf, conf->variable, conf->reset_val);
                    set_extra_field(&conf->gen, &conf->gen.extra,
                                    conf->reset_extra);
                    break;
                }
            case PGC_ENUM:
                {
                    struct config_enum *conf = (struct config_enum *) gconf;

                    if (conf->assign_hook)
                        (*conf->assign_hook) (conf->reset_val,
                                              conf->reset_extra);
                    *conf->variable = conf->reset_val;
                    set_extra_field(&conf->gen, &conf->gen.extra,
                                    conf->reset_extra);
                    break;
                }
        }

        gconf->source = gconf->reset_source;
        gconf->scontext = gconf->reset_scontext;

        if (gconf->flags & GUC_REPORT)
            ReportGUCOption(gconf);
    }
}

bool SelectConfigFiles ( const char *  userDoption,
const char *  progname 
)

Definition at line 4098 of file guc.c.

References CONFIG_FILENAME, ConfigFileName, data_directory, DataDir, FATAL, free, guc_malloc(), HBA_FILENAME, HbaFileName, IDENT_FILENAME, IdentFileName, make_absolute_path(), pg_timezone_abbrev_initialize(), PGC_POSTMASTER, PGC_S_OVERRIDE, ProcessConfigFile(), SetConfigOption(), SetDataDir(), strerror(), and write_stderr.

Referenced by AuxiliaryProcessMain(), PostgresMain(), and PostmasterMain().

{
    char       *configdir;
    char       *fname;
    struct stat stat_buf;

    /* configdir is -D option, or $PGDATA if no -D */
    if (userDoption)
        configdir = make_absolute_path(userDoption);
    else
        configdir = make_absolute_path(getenv("PGDATA"));

    /*
     * Find the configuration file: if config_file was specified on the
     * command line, use it, else use configdir/postgresql.conf.  In any case
     * ensure the result is an absolute path, so that it will be interpreted
     * the same way by future backends.
     */
    if (ConfigFileName)
        fname = make_absolute_path(ConfigFileName);
    else if (configdir)
    {
        fname = guc_malloc(FATAL,
                           strlen(configdir) + strlen(CONFIG_FILENAME) + 2);
        sprintf(fname, "%s/%s", configdir, CONFIG_FILENAME);
    }
    else
    {
        write_stderr("%s does not know where to find the server configuration file.\n"
                     "You must specify the --config-file or -D invocation "
                     "option or set the PGDATA environment variable.\n",
                     progname);
        return false;
    }

    /*
     * Set the ConfigFileName GUC variable to its final value, ensuring that
     * it can't be overridden later.
     */
    SetConfigOption("config_file", fname, PGC_POSTMASTER, PGC_S_OVERRIDE);
    free(fname);

    /*
     * Now read the config file for the first time.
     */
    if (stat(ConfigFileName, &stat_buf) != 0)
    {
        write_stderr("%s cannot access the server configuration file \"%s\": %s\n",
                     progname, ConfigFileName, strerror(errno));
        free(configdir);
        return false;
    }

    ProcessConfigFile(PGC_POSTMASTER);

    /*
     * If the data_directory GUC variable has been set, use that as DataDir;
     * otherwise use configdir if set; else punt.
     *
     * Note: SetDataDir will copy and absolute-ize its argument, so we don't
     * have to.
     */
    if (data_directory)
        SetDataDir(data_directory);
    else if (configdir)
        SetDataDir(configdir);
    else
    {
        write_stderr("%s does not know where to find the database system data.\n"
                     "This can be specified as \"data_directory\" in \"%s\", "
                     "or by the -D invocation option, or by the "
                     "PGDATA environment variable.\n",
                     progname, ConfigFileName);
        return false;
    }

    /*
     * Reflect the final DataDir value back into the data_directory GUC var.
     * (If you are wondering why we don't just make them a single variable,
     * it's because the EXEC_BACKEND case needs DataDir to be transmitted to
     * child backends specially.  XXX is that still true?  Given that we now
     * chdir to DataDir, EXEC_BACKEND can read the config file without knowing
     * DataDir in advance.)
     */
    SetConfigOption("data_directory", DataDir, PGC_POSTMASTER, PGC_S_OVERRIDE);

    /*
     * If timezone_abbreviations wasn't set in the configuration file, install
     * the default value.  We do it this way because we can't safely install a
     * "real" value until my_exec_path is set, which may not have happened
     * when InitializeGUCOptions runs, so the bootstrap default value cannot
     * be the real desired default.
     */
    pg_timezone_abbrev_initialize();

    /*
     * Figure out where pg_hba.conf is, and make sure the path is absolute.
     */
    if (HbaFileName)
        fname = make_absolute_path(HbaFileName);
    else if (configdir)
    {
        fname = guc_malloc(FATAL,
                           strlen(configdir) + strlen(HBA_FILENAME) + 2);
        sprintf(fname, "%s/%s", configdir, HBA_FILENAME);
    }
    else
    {
        write_stderr("%s does not know where to find the \"hba\" configuration file.\n"
                     "This can be specified as \"hba_file\" in \"%s\", "
                     "or by the -D invocation option, or by the "
                     "PGDATA environment variable.\n",
                     progname, ConfigFileName);
        return false;
    }
    SetConfigOption("hba_file", fname, PGC_POSTMASTER, PGC_S_OVERRIDE);
    free(fname);

    /*
     * Likewise for pg_ident.conf.
     */
    if (IdentFileName)
        fname = make_absolute_path(IdentFileName);
    else if (configdir)
    {
        fname = guc_malloc(FATAL,
                           strlen(configdir) + strlen(IDENT_FILENAME) + 2);
        sprintf(fname, "%s/%s", configdir, IDENT_FILENAME);
    }
    else
    {
        write_stderr("%s does not know where to find the \"ident\" configuration file.\n"
                     "This can be specified as \"ident_file\" in \"%s\", "
                     "or by the -D invocation option, or by the "
                     "PGDATA environment variable.\n",
                     progname, ConfigFileName);
        return false;
    }
    SetConfigOption("ident_file", fname, PGC_POSTMASTER, PGC_S_OVERRIDE);
    free(fname);

    free(configdir);

    return true;
}

int set_config_option ( const char *  name,
const char *  value,
GucContext  context,
GucSource  source,
GucAction  action,
bool  changeVal,
int  elevel 
)

Definition at line 5162 of file guc.c.

References _, config_enum::assign_hook, config_string::assign_hook, config_real::assign_hook, config_int::assign_hook, config_bool::assign_hook, config_var_val::boolval, config_enum::boot_val, config_string::boot_val, config_real::boot_val, config_int::boot_val, config_bool::boot_val, call_bool_check_hook(), call_enum_check_hook(), call_int_check_hook(), call_real_check_hook(), call_string_check_hook(), config_enum_get_options(), config_enum_lookup_by_name(), config_generic::context, DEBUG3, elog, config_var_val::enumval, ereport, errcode(), errhint(), errmsg(), config_var_value::extra, config_generic::extra, extra_field_used(), find_option(), config_generic::flags, free, config_enum::gen, config_string::gen, config_real::gen, config_int::gen, config_bool::gen, GUC_IS_NAME, GUC_NOT_WHILE_SEC_REST, GUC_REPORT, guc_strdup(), InLocalUserIdChange(), InSecurityRestrictedOperation(), config_var_val::intval, IsUnderPostmaster, config_real::max, config_int::max, config_real::min, config_int::min, NULL, parse_bool(), parse_int(), parse_real(), pfree(), PGC_BACKEND, PGC_BOOL, PGC_ENUM, PGC_INT, PGC_INTERNAL, PGC_POSTMASTER, PGC_REAL, PGC_S_CLIENT, PGC_S_DATABASE, PGC_S_DATABASE_USER, PGC_S_DEFAULT, PGC_S_FILE, PGC_S_GLOBAL, PGC_S_USER, PGC_SIGHUP, PGC_STRING, PGC_SUSET, PGC_USERSET, guc_stack::prev, guc_stack::prior, push_old_value(), config_var_val::realval, ReportGUCOption(), config_enum::reset_extra, config_string::reset_extra, config_real::reset_extra, config_int::reset_extra, config_bool::reset_extra, config_generic::reset_scontext, config_generic::reset_source, config_enum::reset_val, config_string::reset_val, config_real::reset_val, config_int::reset_val, config_bool::reset_val, guc_stack::scontext, config_generic::scontext, set_extra_field(), set_string_field(), guc_stack::source, config_generic::source, config_generic::stack, string_field_used(), config_var_val::stringval, truncate_identifier(), config_var_value::val, config_enum::variable, config_string::variable, config_real::variable, config_int::variable, config_bool::variable, and config_generic::vartype.

Referenced by applyRemoteGucs(), define_custom_variable(), ExecSetVariableStmt(), execute_extension_script(), ProcessGUCArray(), reapply_stacked_values(), RI_Initial_Check(), set_config_by_name(), set_transmission_modes(), SetConfigOption(), SetPGVariable(), and validate_option_array_item().

{
    struct config_generic *record;
    bool        prohibitValueChange = false;
    bool        makeDefault;

    if (elevel == 0)
    {
        if (source == PGC_S_DEFAULT || source == PGC_S_FILE)
        {
            /*
             * To avoid cluttering the log, only the postmaster bleats loudly
             * about problems with the config file.
             */
            elevel = IsUnderPostmaster ? DEBUG3 : LOG;
        }
        else if (source == PGC_S_GLOBAL || source == PGC_S_DATABASE || source == PGC_S_USER ||
                 source == PGC_S_DATABASE_USER)
            elevel = WARNING;
        else
            elevel = ERROR;
    }

    record = find_option(name, true, elevel);
    if (record == NULL)
    {
        ereport(elevel,
                (errcode(ERRCODE_UNDEFINED_OBJECT),
               errmsg("unrecognized configuration parameter \"%s\"", name)));
        return 0;
    }

    /*
     * Check if the option can be set at this time. See guc.h for the precise
     * rules.
     */
    switch (record->context)
    {
        case PGC_INTERNAL:
            if (context != PGC_INTERNAL)
            {
                ereport(elevel,
                        (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
                         errmsg("parameter \"%s\" cannot be changed",
                                name)));
                return 0;
            }
            break;
        case PGC_POSTMASTER:
            if (context == PGC_SIGHUP)
            {
                /*
                 * We are re-reading a PGC_POSTMASTER variable from
                 * postgresql.conf.  We can't change the setting, so we should
                 * give a warning if the DBA tries to change it.  However,
                 * because of variant formats, canonicalization by check
                 * hooks, etc, we can't just compare the given string directly
                 * to what's stored.  Set a flag to check below after we have
                 * the final storable value.
                 */
                prohibitValueChange = true;
            }
            else if (context != PGC_POSTMASTER)
            {
                ereport(elevel,
                        (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
                         errmsg("parameter \"%s\" cannot be changed without restarting the server",
                                name)));
                return 0;
            }
            break;
        case PGC_SIGHUP:
            if (context != PGC_SIGHUP && context != PGC_POSTMASTER)
            {
                ereport(elevel,
                        (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
                         errmsg("parameter \"%s\" cannot be changed now",
                                name)));
                return 0;
            }

            /*
             * Hmm, the idea of the SIGHUP context is "ought to be global, but
             * can be changed after postmaster start". But there's nothing
             * that prevents a crafty administrator from sending SIGHUP
             * signals to individual backends only.
             */
            break;
        case PGC_BACKEND:
            if (context == PGC_SIGHUP)
            {
                /*
                 * If a PGC_BACKEND parameter is changed in the config file,
                 * we want to accept the new value in the postmaster (whence
                 * it will propagate to subsequently-started backends), but
                 * ignore it in existing backends.  This is a tad klugy, but
                 * necessary because we don't re-read the config file during
                 * backend start.
                 */
                if (IsUnderPostmaster)
                    return -1;
            }
            else if (context != PGC_POSTMASTER && context != PGC_BACKEND &&
                     source != PGC_S_CLIENT)
            {
                ereport(elevel,
                        (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
                         errmsg("parameter \"%s\" cannot be set after connection start",
                                name)));
                return 0;
            }
            break;
        case PGC_SUSET:
            if (context == PGC_USERSET || context == PGC_BACKEND)
            {
                ereport(elevel,
                        (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
                         errmsg("permission denied to set parameter \"%s\"",
                                name)));
                return 0;
            }
            break;
        case PGC_USERSET:
            /* always okay */
            break;
    }

    /*
     * Disallow changing GUC_NOT_WHILE_SEC_REST values if we are inside a
     * security restriction context.  We can reject this regardless of the GUC
     * context or source, mainly because sources that it might be reasonable
     * to override for won't be seen while inside a function.
     *
     * Note: variables marked GUC_NOT_WHILE_SEC_REST should usually be marked
     * GUC_NO_RESET_ALL as well, because ResetAllOptions() doesn't check this.
     * An exception might be made if the reset value is assumed to be "safe".
     *
     * Note: this flag is currently used for "session_authorization" and
     * "role".  We need to prohibit changing these inside a local userid
     * context because when we exit it, GUC won't be notified, leaving things
     * out of sync.  (This could be fixed by forcing a new GUC nesting level,
     * but that would change behavior in possibly-undesirable ways.)  Also, we
     * prohibit changing these in a security-restricted operation because
     * otherwise RESET could be used to regain the session user's privileges.
     */
    if (record->flags & GUC_NOT_WHILE_SEC_REST)
    {
        if (InLocalUserIdChange())
        {
            /*
             * Phrasing of this error message is historical, but it's the most
             * common case.
             */
            ereport(elevel,
                    (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
                     errmsg("cannot set parameter \"%s\" within security-definer function",
                            name)));
            return 0;
        }
        if (InSecurityRestrictedOperation())
        {
            ereport(elevel,
                    (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
                     errmsg("cannot set parameter \"%s\" within security-restricted operation",
                            name)));
            return 0;
        }
    }

    /*
     * Should we set reset/stacked values?  (If so, the behavior is not
     * transactional.)  This is done either when we get a default value from
     * the database's/user's/client's default settings or when we reset a
     * value to its default.
     */
    makeDefault = changeVal && (source <= PGC_S_OVERRIDE) &&
        ((value != NULL) || source == PGC_S_DEFAULT);

    /*
     * Ignore attempted set if overridden by previously processed setting.
     * However, if changeVal is false then plow ahead anyway since we are
     * trying to find out if the value is potentially good, not actually use
     * it. Also keep going if makeDefault is true, since we may want to set
     * the reset/stacked values even if we can't set the variable itself.
     */
    if (record->source > source)
    {
        if (changeVal && !makeDefault)
        {
            elog(DEBUG3, "\"%s\": setting ignored because previous source is higher priority",
                 name);
            return -1;
        }
        changeVal = false;
    }

    /*
     * Evaluate value and set variable.
     */
    switch (record->vartype)
    {
        case PGC_BOOL:
            {
                struct config_bool *conf = (struct config_bool *) record;
                bool        newval;
                void       *newextra = NULL;

                if (value)
                {
                    if (!parse_bool(value, &newval))
                    {
                        ereport(elevel,
                                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                          errmsg("parameter \"%s\" requires a Boolean value",
                                 name)));
                        return 0;
                    }
                    if (!call_bool_check_hook(conf, &newval, &newextra,
                                              source, elevel))
                        return 0;
                }
                else if (source == PGC_S_DEFAULT)
                {
                    newval = conf->boot_val;
                    if (!call_bool_check_hook(conf, &newval, &newextra,
                                              source, elevel))
                        return 0;
                }
                else
                {
                    newval = conf->reset_val;
                    newextra = conf->reset_extra;
                    source = conf->gen.reset_source;
                    context = conf->gen.reset_scontext;
                }

                if (prohibitValueChange)
                {
                    if (*conf->variable != newval)
                    {
                        ereport(elevel,
                                (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
                                 errmsg("parameter \"%s\" cannot be changed without restarting the server",
                                        name)));
                        return 0;
                    }
                    return -1;
                }

                if (changeVal)
                {
                    /* Save old value to support transaction abort */
                    if (!makeDefault)
                        push_old_value(&conf->gen, action);

                    if (conf->assign_hook)
                        (*conf->assign_hook) (newval, newextra);
                    *conf->variable = newval;
                    set_extra_field(&conf->gen, &conf->gen.extra,
                                    newextra);
                    conf->gen.source = source;
                    conf->gen.scontext = context;
                }
                if (makeDefault)
                {
                    GucStack   *stack;

                    if (conf->gen.reset_source <= source)
                    {
                        conf->reset_val = newval;
                        set_extra_field(&conf->gen, &conf->reset_extra,
                                        newextra);
                        conf->gen.reset_source = source;
                        conf->gen.reset_scontext = context;
                    }
                    for (stack = conf->gen.stack; stack; stack = stack->prev)
                    {
                        if (stack->source <= source)
                        {
                            stack->prior.val.boolval = newval;
                            set_extra_field(&conf->gen, &stack->prior.extra,
                                            newextra);
                            stack->source = source;
                            stack->scontext = context;
                        }
                    }
                }

                /* Perhaps we didn't install newextra anywhere */
                if (newextra && !extra_field_used(&conf->gen, newextra))
                    free(newextra);
                break;
            }

        case PGC_INT:
            {
                struct config_int *conf = (struct config_int *) record;
                int         newval;
                void       *newextra = NULL;

                if (value)
                {
                    const char *hintmsg;

                    if (!parse_int(value, &newval, conf->gen.flags, &hintmsg))
                    {
                        ereport(elevel,
                                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                         errmsg("invalid value for parameter \"%s\": \"%s\"",
                                name, value),
                                 hintmsg ? errhint("%s", _(hintmsg)) : 0));
                        return 0;
                    }
                    if (newval < conf->min || newval > conf->max)
                    {
                        ereport(elevel,
                                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                 errmsg("%d is outside the valid range for parameter \"%s\" (%d .. %d)",
                                        newval, name, conf->min, conf->max)));
                        return 0;
                    }
                    if (!call_int_check_hook(conf, &newval, &newextra,
                                             source, elevel))
                        return 0;
                }
                else if (source == PGC_S_DEFAULT)
                {
                    newval = conf->boot_val;
                    if (!call_int_check_hook(conf, &newval, &newextra,
                                             source, elevel))
                        return 0;
                }
                else
                {
                    newval = conf->reset_val;
                    newextra = conf->reset_extra;
                    source = conf->gen.reset_source;
                    context = conf->gen.reset_scontext;
                }

                if (prohibitValueChange)
                {
                    if (*conf->variable != newval)
                    {
                        ereport(elevel,
                                (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
                                 errmsg("parameter \"%s\" cannot be changed without restarting the server",
                                        name)));
                        return 0;
                    }
                    return -1;
                }

                if (changeVal)
                {
                    /* Save old value to support transaction abort */
                    if (!makeDefault)
                        push_old_value(&conf->gen, action);

                    if (conf->assign_hook)
                        (*conf->assign_hook) (newval, newextra);
                    *conf->variable = newval;
                    set_extra_field(&conf->gen, &conf->gen.extra,
                                    newextra);
                    conf->gen.source = source;
                    conf->gen.scontext = context;
                }
                if (makeDefault)
                {
                    GucStack   *stack;

                    if (conf->gen.reset_source <= source)
                    {
                        conf->reset_val = newval;
                        set_extra_field(&conf->gen, &conf->reset_extra,
                                        newextra);
                        conf->gen.reset_source = source;
                        conf->gen.reset_scontext = context;
                    }
                    for (stack = conf->gen.stack; stack; stack = stack->prev)
                    {
                        if (stack->source <= source)
                        {
                            stack->prior.val.intval = newval;
                            set_extra_field(&conf->gen, &stack->prior.extra,
                                            newextra);
                            stack->source = source;
                            stack->scontext = context;
                        }
                    }
                }

                /* Perhaps we didn't install newextra anywhere */
                if (newextra && !extra_field_used(&conf->gen, newextra))
                    free(newextra);
                break;
            }

        case PGC_REAL:
            {
                struct config_real *conf = (struct config_real *) record;
                double      newval;
                void       *newextra = NULL;

                if (value)
                {
                    if (!parse_real(value, &newval))
                    {
                        ereport(elevel,
                                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                          errmsg("parameter \"%s\" requires a numeric value",
                                 name)));
                        return 0;
                    }
                    if (newval < conf->min || newval > conf->max)
                    {
                        ereport(elevel,
                                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                 errmsg("%g is outside the valid range for parameter \"%s\" (%g .. %g)",
                                        newval, name, conf->min, conf->max)));
                        return 0;
                    }
                    if (!call_real_check_hook(conf, &newval, &newextra,
                                              source, elevel))
                        return 0;
                }
                else if (source == PGC_S_DEFAULT)
                {
                    newval = conf->boot_val;
                    if (!call_real_check_hook(conf, &newval, &newextra,
                                              source, elevel))
                        return 0;
                }
                else
                {
                    newval = conf->reset_val;
                    newextra = conf->reset_extra;
                    source = conf->gen.reset_source;
                    context = conf->gen.reset_scontext;
                }

                if (prohibitValueChange)
                {
                    if (*conf->variable != newval)
                    {
                        ereport(elevel,
                                (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
                                 errmsg("parameter \"%s\" cannot be changed without restarting the server",
                                        name)));
                        return 0;
                    }
                    return -1;
                }

                if (changeVal)
                {
                    /* Save old value to support transaction abort */
                    if (!makeDefault)
                        push_old_value(&conf->gen, action);

                    if (conf->assign_hook)
                        (*conf->assign_hook) (newval, newextra);
                    *conf->variable = newval;
                    set_extra_field(&conf->gen, &conf->gen.extra,
                                    newextra);
                    conf->gen.source = source;
                    conf->gen.scontext = context;
                }
                if (makeDefault)
                {
                    GucStack   *stack;

                    if (conf->gen.reset_source <= source)
                    {
                        conf->reset_val = newval;
                        set_extra_field(&conf->gen, &conf->reset_extra,
                                        newextra);
                        conf->gen.reset_source = source;
                        conf->gen.reset_scontext = context;
                    }
                    for (stack = conf->gen.stack; stack; stack = stack->prev)
                    {
                        if (stack->source <= source)
                        {
                            stack->prior.val.realval = newval;
                            set_extra_field(&conf->gen, &stack->prior.extra,
                                            newextra);
                            stack->source = source;
                            stack->scontext = context;
                        }
                    }
                }

                /* Perhaps we didn't install newextra anywhere */
                if (newextra && !extra_field_used(&conf->gen, newextra))
                    free(newextra);
                break;
            }

        case PGC_STRING:
            {
                struct config_string *conf = (struct config_string *) record;
                char       *newval;
                void       *newextra = NULL;

                if (value)
                {
                    /*
                     * The value passed by the caller could be transient, so
                     * we always strdup it.
                     */
                    newval = guc_strdup(elevel, value);
                    if (newval == NULL)
                        return 0;

                    /*
                     * The only built-in "parsing" check we have is to apply
                     * truncation if GUC_IS_NAME.
                     */
                    if (conf->gen.flags & GUC_IS_NAME)
                        truncate_identifier(newval, strlen(newval), true);

                    if (!call_string_check_hook(conf, &newval, &newextra,
                                                source, elevel))
                    {
                        free(newval);
                        return 0;
                    }
                }
                else if (source == PGC_S_DEFAULT)
                {
                    /* non-NULL boot_val must always get strdup'd */
                    if (conf->boot_val != NULL)
                    {
                        newval = guc_strdup(elevel, conf->boot_val);
                        if (newval == NULL)
                            return 0;
                    }
                    else
                        newval = NULL;

                    if (!call_string_check_hook(conf, &newval, &newextra,
                                                source, elevel))
                    {
                        free(newval);
                        return 0;
                    }
                }
                else
                {
                    /*
                     * strdup not needed, since reset_val is already under
                     * guc.c's control
                     */
                    newval = conf->reset_val;
                    newextra = conf->reset_extra;
                    source = conf->gen.reset_source;
                    context = conf->gen.reset_scontext;
                }

                if (prohibitValueChange)
                {
                    /* newval shouldn't be NULL, so we're a bit sloppy here */
                    if (*conf->variable == NULL || newval == NULL ||
                        strcmp(*conf->variable, newval) != 0)
                    {
                        ereport(elevel,
                                (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
                                 errmsg("parameter \"%s\" cannot be changed without restarting the server",
                                        name)));
                        return 0;
                    }
                    return -1;
                }

                if (changeVal)
                {
                    /* Save old value to support transaction abort */
                    if (!makeDefault)
                        push_old_value(&conf->gen, action);

                    if (conf->assign_hook)
                        (*conf->assign_hook) (newval, newextra);
                    set_string_field(conf, conf->variable, newval);
                    set_extra_field(&conf->gen, &conf->gen.extra,
                                    newextra);
                    conf->gen.source = source;
                    conf->gen.scontext = context;
                }

                if (makeDefault)
                {
                    GucStack   *stack;

                    if (conf->gen.reset_source <= source)
                    {
                        set_string_field(conf, &conf->reset_val, newval);
                        set_extra_field(&conf->gen, &conf->reset_extra,
                                        newextra);
                        conf->gen.reset_source = source;
                        conf->gen.reset_scontext = context;
                    }
                    for (stack = conf->gen.stack; stack; stack = stack->prev)
                    {
                        if (stack->source <= source)
                        {
                            set_string_field(conf, &stack->prior.val.stringval,
                                             newval);
                            set_extra_field(&conf->gen, &stack->prior.extra,
                                            newextra);
                            stack->source = source;
                            stack->scontext = context;
                        }
                    }
                }

                /* Perhaps we didn't install newval anywhere */
                if (newval && !string_field_used(conf, newval))
                    free(newval);
                /* Perhaps we didn't install newextra anywhere */
                if (newextra && !extra_field_used(&conf->gen, newextra))
                    free(newextra);
                break;
            }

        case PGC_ENUM:
            {
                struct config_enum *conf = (struct config_enum *) record;
                int         newval;
                void       *newextra = NULL;

                if (value)
                {
                    if (!config_enum_lookup_by_name(conf, value, &newval))
                    {
                        char       *hintmsg;

                        hintmsg = config_enum_get_options(conf,
                                                        "Available values: ",
                                                          ".", ", ");

                        ereport(elevel,
                                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                         errmsg("invalid value for parameter \"%s\": \"%s\"",
                                name, value),
                                 hintmsg ? errhint("%s", _(hintmsg)) : 0));

                        if (hintmsg)
                            pfree(hintmsg);
                        return 0;
                    }
                    if (!call_enum_check_hook(conf, &newval, &newextra,
                                              source, elevel))
                        return 0;
                }
                else if (source == PGC_S_DEFAULT)
                {
                    newval = conf->boot_val;
                    if (!call_enum_check_hook(conf, &newval, &newextra,
                                              source, elevel))
                        return 0;
                }
                else
                {
                    newval = conf->reset_val;
                    newextra = conf->reset_extra;
                    source = conf->gen.reset_source;
                    context = conf->gen.reset_scontext;
                }

                if (prohibitValueChange)
                {
                    if (*conf->variable != newval)
                    {
                        ereport(elevel,
                                (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
                                 errmsg("parameter \"%s\" cannot be changed without restarting the server",
                                        name)));
                        return 0;
                    }
                    return -1;
                }

                if (changeVal)
                {
                    /* Save old value to support transaction abort */
                    if (!makeDefault)
                        push_old_value(&conf->gen, action);

                    if (conf->assign_hook)
                        (*conf->assign_hook) (newval, newextra);
                    *conf->variable = newval;
                    set_extra_field(&conf->gen, &conf->gen.extra,
                                    newextra);
                    conf->gen.source = source;
                    conf->gen.scontext = context;
                }
                if (makeDefault)
                {
                    GucStack   *stack;

                    if (conf->gen.reset_source <= source)
                    {
                        conf->reset_val = newval;
                        set_extra_field(&conf->gen, &conf->reset_extra,
                                        newextra);
                        conf->gen.reset_source = source;
                        conf->gen.reset_scontext = context;
                    }
                    for (stack = conf->gen.stack; stack; stack = stack->prev)
                    {
                        if (stack->source <= source)
                        {
                            stack->prior.val.enumval = newval;
                            set_extra_field(&conf->gen, &stack->prior.extra,
                                            newextra);
                            stack->source = source;
                            stack->scontext = context;
                        }
                    }
                }

                /* Perhaps we didn't install newextra anywhere */
                if (newextra && !extra_field_used(&conf->gen, newextra))
                    free(newextra);
                break;
            }
    }

    if (changeVal && (record->flags & GUC_REPORT))
        ReportGUCOption(record);

    return changeVal ? 1 : -1;
}

void SetConfigOption ( const char *  name,
const char *  value,
GucContext  context,
GucSource  source 
)
void SetPGVariable ( const char *  name,
List args,
bool  is_local 
)

Definition at line 6319 of file guc.c.

References flatten_set_variable_args(), GUC_ACTION_LOCAL, PGC_SUSET, PGC_USERSET, set_config_option(), and superuser().

Referenced by DiscardAll(), ExecSetVariableStmt(), and standard_ProcessUtility().

{
    char       *argstring = flatten_set_variable_args(name, args);

    /* Note SET DEFAULT (argstring == NULL) is equivalent to RESET */
    (void) set_config_option(name,
                             argstring,
                             (superuser() ? PGC_SUSET : PGC_USERSET),
                             PGC_S_SESSION,
                             is_local ? GUC_ACTION_LOCAL : GUC_ACTION_SET,
                             true,
                             0);
}


Variable Documentation

Definition at line 427 of file guc.c.

Referenced by SelectConfigFiles().

Definition at line 426 of file guc.c.

Referenced by SelectConfigFiles().

Definition at line 399 of file guc.c.

Referenced by pg_plan_query(), and pg_rewrite_query().

Definition at line 397 of file guc.c.

Referenced by pg_rewrite_query().

Definition at line 396 of file guc.c.

Referenced by pg_plan_query().

Definition at line 398 of file guc.c.

Referenced by pg_rewrite_query().

Definition at line 410 of file guc.c.

Referenced by interpretOidsOption().

Definition at line 430 of file guc.c.

Referenced by PostmasterMain(), and unlink_external_pid_file().

PGDLLIMPORT char* GUC_check_errdetail_string
PGDLLIMPORT char* GUC_check_errhint_string
PGDLLIMPORT char* GUC_check_errmsg_string
char* HbaFileName

Definition at line 428 of file guc.c.

Referenced by load_hba(), parse_hba_auth_opt(), parse_hba_line(), and SelectConfigFiles().

Definition at line 429 of file guc.c.

Referenced by load_ident(), and SelectConfigFiles().

Definition at line 406 of file guc.c.

Referenced by _bt_leafbuild(), and btbuild().

Definition at line 395 of file guc.c.

Referenced by check_log_duration().

Definition at line 403 of file guc.c.

Referenced by check_log_stats(), PortalRun(), and PortalRunMulti().

Definition at line 418 of file guc.c.

Referenced by check_log_duration().

Definition at line 415 of file guc.c.

Referenced by send_message_to_server_log(), and write_csvlog().

Definition at line 402 of file guc.c.

Referenced by check_log_stats(), and pg_plan_query().

Definition at line 419 of file guc.c.

Referenced by FileClose().

Definition at line 424 of file guc.c.

Referenced by InitLocalBuffers().

Definition at line 411 of file guc.c.

Referenced by interpretInhOption().

Definition at line 438 of file guc.c.

Referenced by StreamConnection().

Definition at line 436 of file guc.c.

Referenced by StreamConnection().

Definition at line 437 of file guc.c.

Referenced by StreamConnection().

Definition at line 422 of file guc.c.

Referenced by FileWrite().