00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "postgres.h"
00018
00019 #include <ctype.h>
00020 #include <float.h>
00021 #include <math.h>
00022 #include <limits.h>
00023 #include <unistd.h>
00024 #include <sys/stat.h>
00025 #ifdef HAVE_SYSLOG
00026 #include <syslog.h>
00027 #endif
00028
00029 #include "access/gin.h"
00030 #include "access/transam.h"
00031 #include "access/twophase.h"
00032 #include "access/xact.h"
00033 #include "catalog/namespace.h"
00034 #include "commands/async.h"
00035 #include "commands/prepare.h"
00036 #include "commands/vacuum.h"
00037 #include "commands/variable.h"
00038 #include "commands/trigger.h"
00039 #include "funcapi.h"
00040 #include "libpq/auth.h"
00041 #include "libpq/be-fsstubs.h"
00042 #include "libpq/libpq.h"
00043 #include "libpq/pqformat.h"
00044 #include "miscadmin.h"
00045 #include "optimizer/cost.h"
00046 #include "optimizer/geqo.h"
00047 #include "optimizer/paths.h"
00048 #include "optimizer/planmain.h"
00049 #include "parser/parse_expr.h"
00050 #include "parser/parse_type.h"
00051 #include "parser/parser.h"
00052 #include "parser/scansup.h"
00053 #include "pgstat.h"
00054 #include "postmaster/autovacuum.h"
00055 #include "postmaster/bgworker.h"
00056 #include "postmaster/bgwriter.h"
00057 #include "postmaster/postmaster.h"
00058 #include "postmaster/syslogger.h"
00059 #include "postmaster/walwriter.h"
00060 #include "replication/syncrep.h"
00061 #include "replication/walreceiver.h"
00062 #include "replication/walsender.h"
00063 #include "storage/bufmgr.h"
00064 #include "storage/standby.h"
00065 #include "storage/fd.h"
00066 #include "storage/proc.h"
00067 #include "storage/predicate.h"
00068 #include "tcop/tcopprot.h"
00069 #include "tsearch/ts_cache.h"
00070 #include "utils/builtins.h"
00071 #include "utils/bytea.h"
00072 #include "utils/guc_tables.h"
00073 #include "utils/memutils.h"
00074 #include "utils/pg_locale.h"
00075 #include "utils/plancache.h"
00076 #include "utils/portal.h"
00077 #include "utils/ps_status.h"
00078 #include "utils/snapmgr.h"
00079 #include "utils/tzparser.h"
00080 #include "utils/xml.h"
00081
00082 #ifndef PG_KRB_SRVTAB
00083 #define PG_KRB_SRVTAB ""
00084 #endif
00085 #ifndef PG_KRB_SRVNAM
00086 #define PG_KRB_SRVNAM ""
00087 #endif
00088
00089 #define CONFIG_FILENAME "postgresql.conf"
00090 #define HBA_FILENAME "pg_hba.conf"
00091 #define IDENT_FILENAME "pg_ident.conf"
00092
00093 #ifdef EXEC_BACKEND
00094 #define CONFIG_EXEC_PARAMS "global/config_exec_params"
00095 #define CONFIG_EXEC_PARAMS_NEW "global/config_exec_params.new"
00096 #endif
00097
00098
00099
00100 #if SIZEOF_SIZE_T > 4 && SIZEOF_LONG > 4
00101 #define MAX_KILOBYTES INT_MAX
00102 #else
00103 #define MAX_KILOBYTES (INT_MAX / 1024)
00104 #endif
00105
00106 #define KB_PER_MB (1024)
00107 #define KB_PER_GB (1024*1024)
00108
00109 #define MS_PER_S 1000
00110 #define S_PER_MIN 60
00111 #define MS_PER_MIN (1000 * 60)
00112 #define MIN_PER_H 60
00113 #define S_PER_H (60 * 60)
00114 #define MS_PER_H (1000 * 60 * 60)
00115 #define MIN_PER_D (60 * 24)
00116 #define S_PER_D (60 * 60 * 24)
00117 #define MS_PER_D (1000 * 60 * 60 * 24)
00118
00119
00120 extern bool Log_disconnections;
00121 extern int CommitDelay;
00122 extern int CommitSiblings;
00123 extern char *default_tablespace;
00124 extern char *temp_tablespaces;
00125 extern bool ignore_checksum_failure;
00126 extern bool synchronize_seqscans;
00127 extern int ssl_renegotiation_limit;
00128 extern char *SSLCipherSuites;
00129
00130 #ifdef TRACE_SORT
00131 extern bool trace_sort;
00132 #endif
00133 #ifdef TRACE_SYNCSCAN
00134 extern bool trace_syncscan;
00135 #endif
00136 #ifdef DEBUG_BOUNDED_SORT
00137 extern bool optimize_bounded_sort;
00138 #endif
00139
00140 static int GUC_check_errcode_value;
00141
00142
00143 char *GUC_check_errmsg_string;
00144 char *GUC_check_errdetail_string;
00145 char *GUC_check_errhint_string;
00146
00147
00148 static void set_config_sourcefile(const char *name, char *sourcefile,
00149 int sourceline);
00150 static bool call_bool_check_hook(struct config_bool * conf, bool *newval,
00151 void **extra, GucSource source, int elevel);
00152 static bool call_int_check_hook(struct config_int * conf, int *newval,
00153 void **extra, GucSource source, int elevel);
00154 static bool call_real_check_hook(struct config_real * conf, double *newval,
00155 void **extra, GucSource source, int elevel);
00156 static bool call_string_check_hook(struct config_string * conf, char **newval,
00157 void **extra, GucSource source, int elevel);
00158 static bool call_enum_check_hook(struct config_enum * conf, int *newval,
00159 void **extra, GucSource source, int elevel);
00160
00161 static bool check_log_destination(char **newval, void **extra, GucSource source);
00162 static void assign_log_destination(const char *newval, void *extra);
00163
00164 #ifdef HAVE_SYSLOG
00165 static int syslog_facility = LOG_LOCAL0;
00166 #else
00167 static int syslog_facility = 0;
00168 #endif
00169
00170 static void assign_syslog_facility(int newval, void *extra);
00171 static void assign_syslog_ident(const char *newval, void *extra);
00172 static void assign_session_replication_role(int newval, void *extra);
00173 static bool check_temp_buffers(int *newval, void **extra, GucSource source);
00174 static bool check_phony_autocommit(bool *newval, void **extra, GucSource source);
00175 static bool check_debug_assertions(bool *newval, void **extra, GucSource source);
00176 static bool check_bonjour(bool *newval, void **extra, GucSource source);
00177 static bool check_ssl(bool *newval, void **extra, GucSource source);
00178 static bool check_stage_log_stats(bool *newval, void **extra, GucSource source);
00179 static bool check_log_stats(bool *newval, void **extra, GucSource source);
00180 static bool check_canonical_path(char **newval, void **extra, GucSource source);
00181 static bool check_timezone_abbreviations(char **newval, void **extra, GucSource source);
00182 static void assign_timezone_abbreviations(const char *newval, void *extra);
00183 static void pg_timezone_abbrev_initialize(void);
00184 static const char *show_archive_command(void);
00185 static void assign_tcp_keepalives_idle(int newval, void *extra);
00186 static void assign_tcp_keepalives_interval(int newval, void *extra);
00187 static void assign_tcp_keepalives_count(int newval, void *extra);
00188 static const char *show_tcp_keepalives_idle(void);
00189 static const char *show_tcp_keepalives_interval(void);
00190 static const char *show_tcp_keepalives_count(void);
00191 static bool check_maxconnections(int *newval, void **extra, GucSource source);
00192 static bool check_autovacuum_max_workers(int *newval, void **extra, GucSource source);
00193 static bool check_effective_io_concurrency(int *newval, void **extra, GucSource source);
00194 static void assign_effective_io_concurrency(int newval, void *extra);
00195 static void assign_pgstat_temp_directory(const char *newval, void *extra);
00196 static bool check_application_name(char **newval, void **extra, GucSource source);
00197 static void assign_application_name(const char *newval, void *extra);
00198 static const char *show_unix_socket_permissions(void);
00199 static const char *show_log_file_mode(void);
00200
00201 static char *config_enum_get_options(struct config_enum * record,
00202 const char *prefix, const char *suffix,
00203 const char *separator);
00204
00205
00206
00207
00208
00209
00210
00211
00212 static const struct config_enum_entry bytea_output_options[] = {
00213 {"escape", BYTEA_OUTPUT_ESCAPE, false},
00214 {"hex", BYTEA_OUTPUT_HEX, false},
00215 {NULL, 0, false}
00216 };
00217
00218
00219
00220
00221
00222 static const struct config_enum_entry client_message_level_options[] = {
00223 {"debug", DEBUG2, true},
00224 {"debug5", DEBUG5, false},
00225 {"debug4", DEBUG4, false},
00226 {"debug3", DEBUG3, false},
00227 {"debug2", DEBUG2, false},
00228 {"debug1", DEBUG1, false},
00229 {"log", LOG, false},
00230 {"info", INFO, true},
00231 {"notice", NOTICE, false},
00232 {"warning", WARNING, false},
00233 {"error", ERROR, false},
00234 {"fatal", FATAL, true},
00235 {"panic", PANIC, true},
00236 {NULL, 0, false}
00237 };
00238
00239 static const struct config_enum_entry server_message_level_options[] = {
00240 {"debug", DEBUG2, true},
00241 {"debug5", DEBUG5, false},
00242 {"debug4", DEBUG4, false},
00243 {"debug3", DEBUG3, false},
00244 {"debug2", DEBUG2, false},
00245 {"debug1", DEBUG1, false},
00246 {"info", INFO, false},
00247 {"notice", NOTICE, false},
00248 {"warning", WARNING, false},
00249 {"error", ERROR, false},
00250 {"log", LOG, false},
00251 {"fatal", FATAL, false},
00252 {"panic", PANIC, false},
00253 {NULL, 0, false}
00254 };
00255
00256 static const struct config_enum_entry intervalstyle_options[] = {
00257 {"postgres", INTSTYLE_POSTGRES, false},
00258 {"postgres_verbose", INTSTYLE_POSTGRES_VERBOSE, false},
00259 {"sql_standard", INTSTYLE_SQL_STANDARD, false},
00260 {"iso_8601", INTSTYLE_ISO_8601, false},
00261 {NULL, 0, false}
00262 };
00263
00264 static const struct config_enum_entry log_error_verbosity_options[] = {
00265 {"terse", PGERROR_TERSE, false},
00266 {"default", PGERROR_DEFAULT, false},
00267 {"verbose", PGERROR_VERBOSE, false},
00268 {NULL, 0, false}
00269 };
00270
00271 static const struct config_enum_entry log_statement_options[] = {
00272 {"none", LOGSTMT_NONE, false},
00273 {"ddl", LOGSTMT_DDL, false},
00274 {"mod", LOGSTMT_MOD, false},
00275 {"all", LOGSTMT_ALL, false},
00276 {NULL, 0, false}
00277 };
00278
00279 static const struct config_enum_entry isolation_level_options[] = {
00280 {"serializable", XACT_SERIALIZABLE, false},
00281 {"repeatable read", XACT_REPEATABLE_READ, false},
00282 {"read committed", XACT_READ_COMMITTED, false},
00283 {"read uncommitted", XACT_READ_UNCOMMITTED, false},
00284 {NULL, 0}
00285 };
00286
00287 static const struct config_enum_entry session_replication_role_options[] = {
00288 {"origin", SESSION_REPLICATION_ROLE_ORIGIN, false},
00289 {"replica", SESSION_REPLICATION_ROLE_REPLICA, false},
00290 {"local", SESSION_REPLICATION_ROLE_LOCAL, false},
00291 {NULL, 0, false}
00292 };
00293
00294 static const struct config_enum_entry syslog_facility_options[] = {
00295 #ifdef HAVE_SYSLOG
00296 {"local0", LOG_LOCAL0, false},
00297 {"local1", LOG_LOCAL1, false},
00298 {"local2", LOG_LOCAL2, false},
00299 {"local3", LOG_LOCAL3, false},
00300 {"local4", LOG_LOCAL4, false},
00301 {"local5", LOG_LOCAL5, false},
00302 {"local6", LOG_LOCAL6, false},
00303 {"local7", LOG_LOCAL7, false},
00304 #else
00305 {"none", 0, false},
00306 #endif
00307 {NULL, 0}
00308 };
00309
00310 static const struct config_enum_entry track_function_options[] = {
00311 {"none", TRACK_FUNC_OFF, false},
00312 {"pl", TRACK_FUNC_PL, false},
00313 {"all", TRACK_FUNC_ALL, false},
00314 {NULL, 0, false}
00315 };
00316
00317 static const struct config_enum_entry xmlbinary_options[] = {
00318 {"base64", XMLBINARY_BASE64, false},
00319 {"hex", XMLBINARY_HEX, false},
00320 {NULL, 0, false}
00321 };
00322
00323 static const struct config_enum_entry xmloption_options[] = {
00324 {"content", XMLOPTION_CONTENT, false},
00325 {"document", XMLOPTION_DOCUMENT, false},
00326 {NULL, 0, false}
00327 };
00328
00329
00330
00331
00332
00333 static const struct config_enum_entry backslash_quote_options[] = {
00334 {"safe_encoding", BACKSLASH_QUOTE_SAFE_ENCODING, false},
00335 {"on", BACKSLASH_QUOTE_ON, false},
00336 {"off", BACKSLASH_QUOTE_OFF, false},
00337 {"true", BACKSLASH_QUOTE_ON, true},
00338 {"false", BACKSLASH_QUOTE_OFF, true},
00339 {"yes", BACKSLASH_QUOTE_ON, true},
00340 {"no", BACKSLASH_QUOTE_OFF, true},
00341 {"1", BACKSLASH_QUOTE_ON, true},
00342 {"0", BACKSLASH_QUOTE_OFF, true},
00343 {NULL, 0, false}
00344 };
00345
00346
00347
00348
00349
00350 static const struct config_enum_entry constraint_exclusion_options[] = {
00351 {"partition", CONSTRAINT_EXCLUSION_PARTITION, false},
00352 {"on", CONSTRAINT_EXCLUSION_ON, false},
00353 {"off", CONSTRAINT_EXCLUSION_OFF, false},
00354 {"true", CONSTRAINT_EXCLUSION_ON, true},
00355 {"false", CONSTRAINT_EXCLUSION_OFF, true},
00356 {"yes", CONSTRAINT_EXCLUSION_ON, true},
00357 {"no", CONSTRAINT_EXCLUSION_OFF, true},
00358 {"1", CONSTRAINT_EXCLUSION_ON, true},
00359 {"0", CONSTRAINT_EXCLUSION_OFF, true},
00360 {NULL, 0, false}
00361 };
00362
00363
00364
00365
00366
00367 static const struct config_enum_entry synchronous_commit_options[] = {
00368 {"local", SYNCHRONOUS_COMMIT_LOCAL_FLUSH, false},
00369 {"remote_write", SYNCHRONOUS_COMMIT_REMOTE_WRITE, false},
00370 {"on", SYNCHRONOUS_COMMIT_ON, false},
00371 {"off", SYNCHRONOUS_COMMIT_OFF, false},
00372 {"true", SYNCHRONOUS_COMMIT_ON, true},
00373 {"false", SYNCHRONOUS_COMMIT_OFF, true},
00374 {"yes", SYNCHRONOUS_COMMIT_ON, true},
00375 {"no", SYNCHRONOUS_COMMIT_OFF, true},
00376 {"1", SYNCHRONOUS_COMMIT_ON, true},
00377 {"0", SYNCHRONOUS_COMMIT_OFF, true},
00378 {NULL, 0, false}
00379 };
00380
00381
00382
00383
00384 extern const struct config_enum_entry wal_level_options[];
00385 extern const struct config_enum_entry sync_method_options[];
00386
00387
00388
00389
00390 #ifdef USE_ASSERT_CHECKING
00391 bool assert_enabled = true;
00392 #else
00393 bool assert_enabled = false;
00394 #endif
00395 bool log_duration = false;
00396 bool Debug_print_plan = false;
00397 bool Debug_print_parse = false;
00398 bool Debug_print_rewritten = false;
00399 bool Debug_pretty_print = true;
00400
00401 bool log_parser_stats = false;
00402 bool log_planner_stats = false;
00403 bool log_executor_stats = false;
00404 bool log_statement_stats = false;
00405
00406 bool log_btree_build_stats = false;
00407 char *event_source;
00408
00409 bool check_function_bodies = true;
00410 bool default_with_oids = false;
00411 bool SQL_inheritance = true;
00412
00413 bool Password_encryption = true;
00414
00415 int log_min_error_statement = ERROR;
00416 int log_min_messages = WARNING;
00417 int client_min_messages = NOTICE;
00418 int log_min_duration_statement = -1;
00419 int log_temp_files = -1;
00420 int trace_recovery_messages = LOG;
00421
00422 int temp_file_limit = -1;
00423
00424 int num_temp_buffers = 1024;
00425
00426 char *data_directory;
00427 char *ConfigFileName;
00428 char *HbaFileName;
00429 char *IdentFileName;
00430 char *external_pid_file;
00431
00432 char *pgstat_temp_directory;
00433
00434 char *application_name;
00435
00436 int tcp_keepalives_idle;
00437 int tcp_keepalives_interval;
00438 int tcp_keepalives_count;
00439
00440
00441
00442
00443
00444
00445 static char *log_destination_string;
00446
00447 static char *syslog_ident_str;
00448 static bool phony_autocommit;
00449 static bool session_auth_is_superuser;
00450 static double phony_random_seed;
00451 static char *client_encoding_string;
00452 static char *datestyle_string;
00453 static char *locale_collate;
00454 static char *locale_ctype;
00455 static char *server_encoding_string;
00456 static char *server_version_string;
00457 static int server_version_num;
00458 static char *timezone_string;
00459 static char *log_timezone_string;
00460 static char *timezone_abbreviations_string;
00461 static char *XactIsoLevel_string;
00462 static char *session_authorization_string;
00463 static int max_function_args;
00464 static int max_index_keys;
00465 static int max_identifier_length;
00466 static int block_size;
00467 static int segment_size;
00468 static int wal_block_size;
00469 static int wal_segment_size;
00470 static bool integer_datetimes;
00471 static int effective_io_concurrency;
00472
00473
00474 char *role_string;
00475
00476
00477
00478
00479
00480
00481
00482 const char *const GucContext_Names[] =
00483 {
00484 "internal",
00485 "postmaster",
00486 "sighup",
00487 "backend",
00488 "superuser",
00489 "user"
00490 };
00491
00492
00493
00494
00495
00496
00497 const char *const GucSource_Names[] =
00498 {
00499 "default",
00500 "default",
00501 "environment variable",
00502 "configuration file",
00503 "command line",
00504 "global",
00505 "database",
00506 "user",
00507 "database user",
00508 "client",
00509 "override",
00510 "interactive",
00511 "test",
00512 "session"
00513 };
00514
00515
00516
00517
00518 const char *const config_group_names[] =
00519 {
00520
00521 gettext_noop("Ungrouped"),
00522
00523 gettext_noop("File Locations"),
00524
00525 gettext_noop("Connections and Authentication"),
00526
00527 gettext_noop("Connections and Authentication / Connection Settings"),
00528
00529 gettext_noop("Connections and Authentication / Security and Authentication"),
00530
00531 gettext_noop("Resource Usage"),
00532
00533 gettext_noop("Resource Usage / Memory"),
00534
00535 gettext_noop("Resource Usage / Disk"),
00536
00537 gettext_noop("Resource Usage / Kernel Resources"),
00538
00539 gettext_noop("Resource Usage / Cost-Based Vacuum Delay"),
00540
00541 gettext_noop("Resource Usage / Background Writer"),
00542
00543 gettext_noop("Resource Usage / Asynchronous Behavior"),
00544
00545 gettext_noop("Write-Ahead Log"),
00546
00547 gettext_noop("Write-Ahead Log / Settings"),
00548
00549 gettext_noop("Write-Ahead Log / Checkpoints"),
00550
00551 gettext_noop("Write-Ahead Log / Archiving"),
00552
00553 gettext_noop("Replication"),
00554
00555 gettext_noop("Replication / Sending Servers"),
00556
00557 gettext_noop("Replication / Master Server"),
00558
00559 gettext_noop("Replication / Standby Servers"),
00560
00561 gettext_noop("Query Tuning"),
00562
00563 gettext_noop("Query Tuning / Planner Method Configuration"),
00564
00565 gettext_noop("Query Tuning / Planner Cost Constants"),
00566
00567 gettext_noop("Query Tuning / Genetic Query Optimizer"),
00568
00569 gettext_noop("Query Tuning / Other Planner Options"),
00570
00571 gettext_noop("Reporting and Logging"),
00572
00573 gettext_noop("Reporting and Logging / Where to Log"),
00574
00575 gettext_noop("Reporting and Logging / When to Log"),
00576
00577 gettext_noop("Reporting and Logging / What to Log"),
00578
00579 gettext_noop("Statistics"),
00580
00581 gettext_noop("Statistics / Monitoring"),
00582
00583 gettext_noop("Statistics / Query and Index Statistics Collector"),
00584
00585 gettext_noop("Autovacuum"),
00586
00587 gettext_noop("Client Connection Defaults"),
00588
00589 gettext_noop("Client Connection Defaults / Statement Behavior"),
00590
00591 gettext_noop("Client Connection Defaults / Locale and Formatting"),
00592
00593 gettext_noop("Client Connection Defaults / Other Defaults"),
00594
00595 gettext_noop("Lock Management"),
00596
00597 gettext_noop("Version and Platform Compatibility"),
00598
00599 gettext_noop("Version and Platform Compatibility / Previous PostgreSQL Versions"),
00600
00601 gettext_noop("Version and Platform Compatibility / Other Platforms and Clients"),
00602
00603 gettext_noop("Error Handling"),
00604
00605 gettext_noop("Preset Options"),
00606
00607 gettext_noop("Customized Options"),
00608
00609 gettext_noop("Developer Options"),
00610
00611 NULL
00612 };
00613
00614
00615
00616
00617
00618
00619 const char *const config_type_names[] =
00620 {
00621 "bool",
00622 "integer",
00623 "real",
00624 "string",
00625 "enum"
00626 };
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659 static struct config_bool ConfigureNamesBool[] =
00660 {
00661 {
00662 {"enable_seqscan", PGC_USERSET, QUERY_TUNING_METHOD,
00663 gettext_noop("Enables the planner's use of sequential-scan plans."),
00664 NULL
00665 },
00666 &enable_seqscan,
00667 true,
00668 NULL, NULL, NULL
00669 },
00670 {
00671 {"enable_indexscan", PGC_USERSET, QUERY_TUNING_METHOD,
00672 gettext_noop("Enables the planner's use of index-scan plans."),
00673 NULL
00674 },
00675 &enable_indexscan,
00676 true,
00677 NULL, NULL, NULL
00678 },
00679 {
00680 {"enable_indexonlyscan", PGC_USERSET, QUERY_TUNING_METHOD,
00681 gettext_noop("Enables the planner's use of index-only-scan plans."),
00682 NULL
00683 },
00684 &enable_indexonlyscan,
00685 true,
00686 NULL, NULL, NULL
00687 },
00688 {
00689 {"enable_bitmapscan", PGC_USERSET, QUERY_TUNING_METHOD,
00690 gettext_noop("Enables the planner's use of bitmap-scan plans."),
00691 NULL
00692 },
00693 &enable_bitmapscan,
00694 true,
00695 NULL, NULL, NULL
00696 },
00697 {
00698 {"enable_tidscan", PGC_USERSET, QUERY_TUNING_METHOD,
00699 gettext_noop("Enables the planner's use of TID scan plans."),
00700 NULL
00701 },
00702 &enable_tidscan,
00703 true,
00704 NULL, NULL, NULL
00705 },
00706 {
00707 {"enable_sort", PGC_USERSET, QUERY_TUNING_METHOD,
00708 gettext_noop("Enables the planner's use of explicit sort steps."),
00709 NULL
00710 },
00711 &enable_sort,
00712 true,
00713 NULL, NULL, NULL
00714 },
00715 {
00716 {"enable_hashagg", PGC_USERSET, QUERY_TUNING_METHOD,
00717 gettext_noop("Enables the planner's use of hashed aggregation plans."),
00718 NULL
00719 },
00720 &enable_hashagg,
00721 true,
00722 NULL, NULL, NULL
00723 },
00724 {
00725 {"enable_material", PGC_USERSET, QUERY_TUNING_METHOD,
00726 gettext_noop("Enables the planner's use of materialization."),
00727 NULL
00728 },
00729 &enable_material,
00730 true,
00731 NULL, NULL, NULL
00732 },
00733 {
00734 {"enable_nestloop", PGC_USERSET, QUERY_TUNING_METHOD,
00735 gettext_noop("Enables the planner's use of nested-loop join plans."),
00736 NULL
00737 },
00738 &enable_nestloop,
00739 true,
00740 NULL, NULL, NULL
00741 },
00742 {
00743 {"enable_mergejoin", PGC_USERSET, QUERY_TUNING_METHOD,
00744 gettext_noop("Enables the planner's use of merge join plans."),
00745 NULL
00746 },
00747 &enable_mergejoin,
00748 true,
00749 NULL, NULL, NULL
00750 },
00751 {
00752 {"enable_hashjoin", PGC_USERSET, QUERY_TUNING_METHOD,
00753 gettext_noop("Enables the planner's use of hash join plans."),
00754 NULL
00755 },
00756 &enable_hashjoin,
00757 true,
00758 NULL, NULL, NULL
00759 },
00760 {
00761 {"geqo", PGC_USERSET, QUERY_TUNING_GEQO,
00762 gettext_noop("Enables genetic query optimization."),
00763 gettext_noop("This algorithm attempts to do planning without "
00764 "exhaustive searching.")
00765 },
00766 &enable_geqo,
00767 true,
00768 NULL, NULL, NULL
00769 },
00770 {
00771
00772 {"is_superuser", PGC_INTERNAL, UNGROUPED,
00773 gettext_noop("Shows whether the current user is a superuser."),
00774 NULL,
00775 GUC_REPORT | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
00776 },
00777 &session_auth_is_superuser,
00778 false,
00779 NULL, NULL, NULL
00780 },
00781 {
00782 {"bonjour", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
00783 gettext_noop("Enables advertising the server via Bonjour."),
00784 NULL
00785 },
00786 &enable_bonjour,
00787 false,
00788 check_bonjour, NULL, NULL
00789 },
00790 {
00791 {"ssl", PGC_POSTMASTER, CONN_AUTH_SECURITY,
00792 gettext_noop("Enables SSL connections."),
00793 NULL
00794 },
00795 &EnableSSL,
00796 false,
00797 check_ssl, NULL, NULL
00798 },
00799 {
00800 {"fsync", PGC_SIGHUP, WAL_SETTINGS,
00801 gettext_noop("Forces synchronization of updates to disk."),
00802 gettext_noop("The server will use the fsync() system call in several places to make "
00803 "sure that updates are physically written to disk. This insures "
00804 "that a database cluster will recover to a consistent state after "
00805 "an operating system or hardware crash.")
00806 },
00807 &enableFsync,
00808 true,
00809 NULL, NULL, NULL
00810 },
00811 {
00812 {"ignore_checksum_failure", PGC_SUSET, DEVELOPER_OPTIONS,
00813 gettext_noop("Continues processing after a checksum failure."),
00814 gettext_noop("Detection of a checksum failure normally causes PostgreSQL to "
00815 "report an error, aborting the current transaction. Setting "
00816 "ignore_checksum_failure to true causes the system to ignore the failure "
00817 "(but still report a warning), and continue processing. This "
00818 "behavior could cause crashes or other serious problems. Only "
00819 "has an effect if checksums are enabled."),
00820 GUC_NOT_IN_SAMPLE
00821 },
00822 &ignore_checksum_failure,
00823 false,
00824 NULL, NULL, NULL
00825 },
00826 {
00827 {"zero_damaged_pages", PGC_SUSET, DEVELOPER_OPTIONS,
00828 gettext_noop("Continues processing past damaged page headers."),
00829 gettext_noop("Detection of a damaged page header normally causes PostgreSQL to "
00830 "report an error, aborting the current transaction. Setting "
00831 "zero_damaged_pages to true causes the system to instead report a "
00832 "warning, zero out the damaged page, and continue processing. This "
00833 "behavior will destroy data, namely all the rows on the damaged page."),
00834 GUC_NOT_IN_SAMPLE
00835 },
00836 &zero_damaged_pages,
00837 false,
00838 NULL, NULL, NULL
00839 },
00840 {
00841 {"full_page_writes", PGC_SIGHUP, WAL_SETTINGS,
00842 gettext_noop("Writes full pages to WAL when first modified after a checkpoint."),
00843 gettext_noop("A page write in process during an operating system crash might be "
00844 "only partially written to disk. During recovery, the row changes "
00845 "stored in WAL are not enough to recover. This option writes "
00846 "pages when first modified after a checkpoint to WAL so full recovery "
00847 "is possible.")
00848 },
00849 &fullPageWrites,
00850 true,
00851 NULL, NULL, NULL
00852 },
00853 {
00854 {"log_checkpoints", PGC_SIGHUP, LOGGING_WHAT,
00855 gettext_noop("Logs each checkpoint."),
00856 NULL
00857 },
00858 &log_checkpoints,
00859 false,
00860 NULL, NULL, NULL
00861 },
00862 {
00863 {"log_connections", PGC_BACKEND, LOGGING_WHAT,
00864 gettext_noop("Logs each successful connection."),
00865 NULL
00866 },
00867 &Log_connections,
00868 false,
00869 NULL, NULL, NULL
00870 },
00871 {
00872 {"log_disconnections", PGC_BACKEND, LOGGING_WHAT,
00873 gettext_noop("Logs end of a session, including duration."),
00874 NULL
00875 },
00876 &Log_disconnections,
00877 false,
00878 NULL, NULL, NULL
00879 },
00880 {
00881 {"debug_assertions", PGC_USERSET, DEVELOPER_OPTIONS,
00882 gettext_noop("Turns on various assertion checks."),
00883 gettext_noop("This is a debugging aid."),
00884 GUC_NOT_IN_SAMPLE
00885 },
00886 &assert_enabled,
00887 #ifdef USE_ASSERT_CHECKING
00888 true,
00889 #else
00890 false,
00891 #endif
00892 check_debug_assertions, NULL, NULL
00893 },
00894
00895 {
00896 {"exit_on_error", PGC_USERSET, ERROR_HANDLING_OPTIONS,
00897 gettext_noop("Terminate session on any error."),
00898 NULL
00899 },
00900 &ExitOnAnyError,
00901 false,
00902 NULL, NULL, NULL
00903 },
00904 {
00905 {"restart_after_crash", PGC_SIGHUP, ERROR_HANDLING_OPTIONS,
00906 gettext_noop("Reinitialize server after backend crash."),
00907 NULL
00908 },
00909 &restart_after_crash,
00910 true,
00911 NULL, NULL, NULL
00912 },
00913
00914 {
00915 {"log_duration", PGC_SUSET, LOGGING_WHAT,
00916 gettext_noop("Logs the duration of each completed SQL statement."),
00917 NULL
00918 },
00919 &log_duration,
00920 false,
00921 NULL, NULL, NULL
00922 },
00923 {
00924 {"debug_print_parse", PGC_USERSET, LOGGING_WHAT,
00925 gettext_noop("Logs each query's parse tree."),
00926 NULL
00927 },
00928 &Debug_print_parse,
00929 false,
00930 NULL, NULL, NULL
00931 },
00932 {
00933 {"debug_print_rewritten", PGC_USERSET, LOGGING_WHAT,
00934 gettext_noop("Logs each query's rewritten parse tree."),
00935 NULL
00936 },
00937 &Debug_print_rewritten,
00938 false,
00939 NULL, NULL, NULL
00940 },
00941 {
00942 {"debug_print_plan", PGC_USERSET, LOGGING_WHAT,
00943 gettext_noop("Logs each query's execution plan."),
00944 NULL
00945 },
00946 &Debug_print_plan,
00947 false,
00948 NULL, NULL, NULL
00949 },
00950 {
00951 {"debug_pretty_print", PGC_USERSET, LOGGING_WHAT,
00952 gettext_noop("Indents parse and plan tree displays."),
00953 NULL
00954 },
00955 &Debug_pretty_print,
00956 true,
00957 NULL, NULL, NULL
00958 },
00959 {
00960 {"log_parser_stats", PGC_SUSET, STATS_MONITORING,
00961 gettext_noop("Writes parser performance statistics to the server log."),
00962 NULL
00963 },
00964 &log_parser_stats,
00965 false,
00966 check_stage_log_stats, NULL, NULL
00967 },
00968 {
00969 {"log_planner_stats", PGC_SUSET, STATS_MONITORING,
00970 gettext_noop("Writes planner performance statistics to the server log."),
00971 NULL
00972 },
00973 &log_planner_stats,
00974 false,
00975 check_stage_log_stats, NULL, NULL
00976 },
00977 {
00978 {"log_executor_stats", PGC_SUSET, STATS_MONITORING,
00979 gettext_noop("Writes executor performance statistics to the server log."),
00980 NULL
00981 },
00982 &log_executor_stats,
00983 false,
00984 check_stage_log_stats, NULL, NULL
00985 },
00986 {
00987 {"log_statement_stats", PGC_SUSET, STATS_MONITORING,
00988 gettext_noop("Writes cumulative performance statistics to the server log."),
00989 NULL
00990 },
00991 &log_statement_stats,
00992 false,
00993 check_log_stats, NULL, NULL
00994 },
00995 #ifdef BTREE_BUILD_STATS
00996 {
00997 {"log_btree_build_stats", PGC_SUSET, DEVELOPER_OPTIONS,
00998 gettext_noop("No description available."),
00999 NULL,
01000 GUC_NOT_IN_SAMPLE
01001 },
01002 &log_btree_build_stats,
01003 false,
01004 NULL, NULL, NULL
01005 },
01006 #endif
01007
01008 {
01009 {"track_activities", PGC_SUSET, STATS_COLLECTOR,
01010 gettext_noop("Collects information about executing commands."),
01011 gettext_noop("Enables the collection of information on the currently "
01012 "executing command of each session, along with "
01013 "the time at which that command began execution.")
01014 },
01015 &pgstat_track_activities,
01016 true,
01017 NULL, NULL, NULL
01018 },
01019 {
01020 {"track_counts", PGC_SUSET, STATS_COLLECTOR,
01021 gettext_noop("Collects statistics on database activity."),
01022 NULL
01023 },
01024 &pgstat_track_counts,
01025 true,
01026 NULL, NULL, NULL
01027 },
01028 {
01029 {"track_io_timing", PGC_SUSET, STATS_COLLECTOR,
01030 gettext_noop("Collects timing statistics for database I/O activity."),
01031 NULL
01032 },
01033 &track_io_timing,
01034 false,
01035 NULL, NULL, NULL
01036 },
01037
01038 {
01039 {"update_process_title", PGC_SUSET, STATS_COLLECTOR,
01040 gettext_noop("Updates the process title to show the active SQL command."),
01041 gettext_noop("Enables updating of the process title every time a new SQL command is received by the server.")
01042 },
01043 &update_process_title,
01044 true,
01045 NULL, NULL, NULL
01046 },
01047
01048 {
01049 {"autovacuum", PGC_SIGHUP, AUTOVACUUM,
01050 gettext_noop("Starts the autovacuum subprocess."),
01051 NULL
01052 },
01053 &autovacuum_start_daemon,
01054 true,
01055 NULL, NULL, NULL
01056 },
01057
01058 {
01059 {"trace_notify", PGC_USERSET, DEVELOPER_OPTIONS,
01060 gettext_noop("Generates debugging output for LISTEN and NOTIFY."),
01061 NULL,
01062 GUC_NOT_IN_SAMPLE
01063 },
01064 &Trace_notify,
01065 false,
01066 NULL, NULL, NULL
01067 },
01068
01069 #ifdef LOCK_DEBUG
01070 {
01071 {"trace_locks", PGC_SUSET, DEVELOPER_OPTIONS,
01072 gettext_noop("No description available."),
01073 NULL,
01074 GUC_NOT_IN_SAMPLE
01075 },
01076 &Trace_locks,
01077 false,
01078 NULL, NULL, NULL
01079 },
01080 {
01081 {"trace_userlocks", PGC_SUSET, DEVELOPER_OPTIONS,
01082 gettext_noop("No description available."),
01083 NULL,
01084 GUC_NOT_IN_SAMPLE
01085 },
01086 &Trace_userlocks,
01087 false,
01088 NULL, NULL, NULL
01089 },
01090 {
01091 {"trace_lwlocks", PGC_SUSET, DEVELOPER_OPTIONS,
01092 gettext_noop("No description available."),
01093 NULL,
01094 GUC_NOT_IN_SAMPLE
01095 },
01096 &Trace_lwlocks,
01097 false,
01098 NULL, NULL, NULL
01099 },
01100 {
01101 {"debug_deadlocks", PGC_SUSET, DEVELOPER_OPTIONS,
01102 gettext_noop("No description available."),
01103 NULL,
01104 GUC_NOT_IN_SAMPLE
01105 },
01106 &Debug_deadlocks,
01107 false,
01108 NULL, NULL, NULL
01109 },
01110 #endif
01111
01112 {
01113 {"log_lock_waits", PGC_SUSET, LOGGING_WHAT,
01114 gettext_noop("Logs long lock waits."),
01115 NULL
01116 },
01117 &log_lock_waits,
01118 false,
01119 NULL, NULL, NULL
01120 },
01121
01122 {
01123 {"log_hostname", PGC_SIGHUP, LOGGING_WHAT,
01124 gettext_noop("Logs the host name in the connection logs."),
01125 gettext_noop("By default, connection logs only show the IP address "
01126 "of the connecting host. If you want them to show the host name you "
01127 "can turn this on, but depending on your host name resolution "
01128 "setup it might impose a non-negligible performance penalty.")
01129 },
01130 &log_hostname,
01131 false,
01132 NULL, NULL, NULL
01133 },
01134 {
01135 {"sql_inheritance", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
01136 gettext_noop("Causes subtables to be included by default in various commands."),
01137 NULL
01138 },
01139 &SQL_inheritance,
01140 true,
01141 NULL, NULL, NULL
01142 },
01143 {
01144 {"password_encryption", PGC_USERSET, CONN_AUTH_SECURITY,
01145 gettext_noop("Encrypt passwords."),
01146 gettext_noop("When a password is specified in CREATE USER or "
01147 "ALTER USER without writing either ENCRYPTED or UNENCRYPTED, "
01148 "this parameter determines whether the password is to be encrypted.")
01149 },
01150 &Password_encryption,
01151 true,
01152 NULL, NULL, NULL
01153 },
01154 {
01155 {"transform_null_equals", PGC_USERSET, COMPAT_OPTIONS_CLIENT,
01156 gettext_noop("Treats \"expr=NULL\" as \"expr IS NULL\"."),
01157 gettext_noop("When turned on, expressions of the form expr = NULL "
01158 "(or NULL = expr) are treated as expr IS NULL, that is, they "
01159 "return true if expr evaluates to the null value, and false "
01160 "otherwise. The correct behavior of expr = NULL is to always "
01161 "return null (unknown).")
01162 },
01163 &Transform_null_equals,
01164 false,
01165 NULL, NULL, NULL
01166 },
01167 {
01168 {"db_user_namespace", PGC_SIGHUP, CONN_AUTH_SECURITY,
01169 gettext_noop("Enables per-database user names."),
01170 NULL
01171 },
01172 &Db_user_namespace,
01173 false,
01174 NULL, NULL, NULL
01175 },
01176 {
01177
01178 {"autocommit", PGC_USERSET, CLIENT_CONN_STATEMENT,
01179 gettext_noop("This parameter doesn't do anything."),
01180 gettext_noop("It's just here so that we won't choke on SET AUTOCOMMIT TO ON from 7.3-vintage clients."),
01181 GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE
01182 },
01183 &phony_autocommit,
01184 true,
01185 check_phony_autocommit, NULL, NULL
01186 },
01187 {
01188 {"default_transaction_read_only", PGC_USERSET, CLIENT_CONN_STATEMENT,
01189 gettext_noop("Sets the default read-only status of new transactions."),
01190 NULL
01191 },
01192 &DefaultXactReadOnly,
01193 false,
01194 NULL, NULL, NULL
01195 },
01196 {
01197 {"transaction_read_only", PGC_USERSET, CLIENT_CONN_STATEMENT,
01198 gettext_noop("Sets the current transaction's read-only status."),
01199 NULL,
01200 GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
01201 },
01202 &XactReadOnly,
01203 false,
01204 check_transaction_read_only, NULL, NULL
01205 },
01206 {
01207 {"default_transaction_deferrable", PGC_USERSET, CLIENT_CONN_STATEMENT,
01208 gettext_noop("Sets the default deferrable status of new transactions."),
01209 NULL
01210 },
01211 &DefaultXactDeferrable,
01212 false,
01213 NULL, NULL, NULL
01214 },
01215 {
01216 {"transaction_deferrable", PGC_USERSET, CLIENT_CONN_STATEMENT,
01217 gettext_noop("Whether to defer a read-only serializable transaction until it can be executed with no possible serialization failures."),
01218 NULL,
01219 GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
01220 },
01221 &XactDeferrable,
01222 false,
01223 check_transaction_deferrable, NULL, NULL
01224 },
01225 {
01226 {"check_function_bodies", PGC_USERSET, CLIENT_CONN_STATEMENT,
01227 gettext_noop("Check function bodies during CREATE FUNCTION."),
01228 NULL
01229 },
01230 &check_function_bodies,
01231 true,
01232 NULL, NULL, NULL
01233 },
01234 {
01235 {"array_nulls", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
01236 gettext_noop("Enable input of NULL elements in arrays."),
01237 gettext_noop("When turned on, unquoted NULL in an array input "
01238 "value means a null value; "
01239 "otherwise it is taken literally.")
01240 },
01241 &Array_nulls,
01242 true,
01243 NULL, NULL, NULL
01244 },
01245 {
01246 {"default_with_oids", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
01247 gettext_noop("Create new tables with OIDs by default."),
01248 NULL
01249 },
01250 &default_with_oids,
01251 false,
01252 NULL, NULL, NULL
01253 },
01254 {
01255 {"logging_collector", PGC_POSTMASTER, LOGGING_WHERE,
01256 gettext_noop("Start a subprocess to capture stderr output and/or csvlogs into log files."),
01257 NULL
01258 },
01259 &Logging_collector,
01260 false,
01261 NULL, NULL, NULL
01262 },
01263 {
01264 {"log_truncate_on_rotation", PGC_SIGHUP, LOGGING_WHERE,
01265 gettext_noop("Truncate existing log files of same name during log rotation."),
01266 NULL
01267 },
01268 &Log_truncate_on_rotation,
01269 false,
01270 NULL, NULL, NULL
01271 },
01272
01273 #ifdef TRACE_SORT
01274 {
01275 {"trace_sort", PGC_USERSET, DEVELOPER_OPTIONS,
01276 gettext_noop("Emit information about resource usage in sorting."),
01277 NULL,
01278 GUC_NOT_IN_SAMPLE
01279 },
01280 &trace_sort,
01281 false,
01282 NULL, NULL, NULL
01283 },
01284 #endif
01285
01286 #ifdef TRACE_SYNCSCAN
01287
01288 {
01289 {"trace_syncscan", PGC_USERSET, DEVELOPER_OPTIONS,
01290 gettext_noop("Generate debugging output for synchronized scanning."),
01291 NULL,
01292 GUC_NOT_IN_SAMPLE
01293 },
01294 &trace_syncscan,
01295 false,
01296 NULL, NULL, NULL
01297 },
01298 #endif
01299
01300 #ifdef DEBUG_BOUNDED_SORT
01301
01302 {
01303 {
01304 "optimize_bounded_sort", PGC_USERSET, QUERY_TUNING_METHOD,
01305 gettext_noop("Enable bounded sorting using heap sort."),
01306 NULL,
01307 GUC_NOT_IN_SAMPLE
01308 },
01309 &optimize_bounded_sort,
01310 true,
01311 NULL, NULL, NULL
01312 },
01313 #endif
01314
01315 #ifdef WAL_DEBUG
01316 {
01317 {"wal_debug", PGC_SUSET, DEVELOPER_OPTIONS,
01318 gettext_noop("Emit WAL-related debugging output."),
01319 NULL,
01320 GUC_NOT_IN_SAMPLE
01321 },
01322 &XLOG_DEBUG,
01323 false,
01324 NULL, NULL, NULL
01325 },
01326 #endif
01327
01328 {
01329 {"integer_datetimes", PGC_INTERNAL, PRESET_OPTIONS,
01330 gettext_noop("Datetimes are integer based."),
01331 NULL,
01332 GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
01333 },
01334 &integer_datetimes,
01335 #ifdef HAVE_INT64_TIMESTAMP
01336 true,
01337 #else
01338 false,
01339 #endif
01340 NULL, NULL, NULL
01341 },
01342
01343 {
01344 {"krb_caseins_users", PGC_SIGHUP, CONN_AUTH_SECURITY,
01345 gettext_noop("Sets whether Kerberos and GSSAPI user names should be treated as case-insensitive."),
01346 NULL
01347 },
01348 &pg_krb_caseins_users,
01349 false,
01350 NULL, NULL, NULL
01351 },
01352
01353 {
01354 {"escape_string_warning", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
01355 gettext_noop("Warn about backslash escapes in ordinary string literals."),
01356 NULL
01357 },
01358 &escape_string_warning,
01359 true,
01360 NULL, NULL, NULL
01361 },
01362
01363 {
01364 {"standard_conforming_strings", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
01365 gettext_noop("Causes '...' strings to treat backslashes literally."),
01366 NULL,
01367 GUC_REPORT
01368 },
01369 &standard_conforming_strings,
01370 true,
01371 NULL, NULL, NULL
01372 },
01373
01374 {
01375 {"synchronize_seqscans", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
01376 gettext_noop("Enable synchronized sequential scans."),
01377 NULL
01378 },
01379 &synchronize_seqscans,
01380 true,
01381 NULL, NULL, NULL
01382 },
01383
01384 {
01385 {"archive_mode", PGC_POSTMASTER, WAL_ARCHIVING,
01386 gettext_noop("Allows archiving of WAL files using archive_command."),
01387 NULL
01388 },
01389 &XLogArchiveMode,
01390 false,
01391 NULL, NULL, NULL
01392 },
01393
01394 {
01395 {"hot_standby", PGC_POSTMASTER, REPLICATION_STANDBY,
01396 gettext_noop("Allows connections and queries during recovery."),
01397 NULL
01398 },
01399 &EnableHotStandby,
01400 false,
01401 NULL, NULL, NULL
01402 },
01403
01404 {
01405 {"hot_standby_feedback", PGC_SIGHUP, REPLICATION_STANDBY,
01406 gettext_noop("Allows feedback from a hot standby to the primary that will avoid query conflicts."),
01407 NULL
01408 },
01409 &hot_standby_feedback,
01410 false,
01411 NULL, NULL, NULL
01412 },
01413
01414 {
01415 {"allow_system_table_mods", PGC_POSTMASTER, DEVELOPER_OPTIONS,
01416 gettext_noop("Allows modifications of the structure of system tables."),
01417 NULL,
01418 GUC_NOT_IN_SAMPLE
01419 },
01420 &allowSystemTableMods,
01421 false,
01422 NULL, NULL, NULL
01423 },
01424
01425 {
01426 {"ignore_system_indexes", PGC_BACKEND, DEVELOPER_OPTIONS,
01427 gettext_noop("Disables reading from system indexes."),
01428 gettext_noop("It does not prevent updating the indexes, so it is safe "
01429 "to use. The worst consequence is slowness."),
01430 GUC_NOT_IN_SAMPLE
01431 },
01432 &IgnoreSystemIndexes,
01433 false,
01434 NULL, NULL, NULL
01435 },
01436
01437 {
01438 {"lo_compat_privileges", PGC_SUSET, COMPAT_OPTIONS_PREVIOUS,
01439 gettext_noop("Enables backward compatibility mode for privilege checks on large objects."),
01440 gettext_noop("Skips privilege checks when reading or modifying large objects, "
01441 "for compatibility with PostgreSQL releases prior to 9.0.")
01442 },
01443 &lo_compat_privileges,
01444 false,
01445 NULL, NULL, NULL
01446 },
01447
01448 {
01449 {"quote_all_identifiers", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
01450 gettext_noop("When generating SQL fragments, quote all identifiers."),
01451 NULL,
01452 },
01453 "e_all_identifiers,
01454 false,
01455 NULL, NULL, NULL
01456 },
01457
01458
01459 {
01460 {NULL, 0, 0, NULL, NULL}, NULL, false, NULL, NULL, NULL
01461 }
01462 };
01463
01464
01465 static struct config_int ConfigureNamesInt[] =
01466 {
01467 {
01468 {"archive_timeout", PGC_SIGHUP, WAL_ARCHIVING,
01469 gettext_noop("Forces a switch to the next xlog file if a "
01470 "new file has not been started within N seconds."),
01471 NULL,
01472 GUC_UNIT_S
01473 },
01474 &XLogArchiveTimeout,
01475 0, 0, INT_MAX / 2,
01476 NULL, NULL, NULL
01477 },
01478 {
01479 {"post_auth_delay", PGC_BACKEND, DEVELOPER_OPTIONS,
01480 gettext_noop("Waits N seconds on connection startup after authentication."),
01481 gettext_noop("This allows attaching a debugger to the process."),
01482 GUC_NOT_IN_SAMPLE | GUC_UNIT_S
01483 },
01484 &PostAuthDelay,
01485 0, 0, INT_MAX / 1000000,
01486 NULL, NULL, NULL
01487 },
01488 {
01489 {"default_statistics_target", PGC_USERSET, QUERY_TUNING_OTHER,
01490 gettext_noop("Sets the default statistics target."),
01491 gettext_noop("This applies to table columns that have not had a "
01492 "column-specific target set via ALTER TABLE SET STATISTICS.")
01493 },
01494 &default_statistics_target,
01495 100, 1, 10000,
01496 NULL, NULL, NULL
01497 },
01498 {
01499 {"from_collapse_limit", PGC_USERSET, QUERY_TUNING_OTHER,
01500 gettext_noop("Sets the FROM-list size beyond which subqueries "
01501 "are not collapsed."),
01502 gettext_noop("The planner will merge subqueries into upper "
01503 "queries if the resulting FROM list would have no more than "
01504 "this many items.")
01505 },
01506 &from_collapse_limit,
01507 8, 1, INT_MAX,
01508 NULL, NULL, NULL
01509 },
01510 {
01511 {"join_collapse_limit", PGC_USERSET, QUERY_TUNING_OTHER,
01512 gettext_noop("Sets the FROM-list size beyond which JOIN "
01513 "constructs are not flattened."),
01514 gettext_noop("The planner will flatten explicit JOIN "
01515 "constructs into lists of FROM items whenever a "
01516 "list of no more than this many items would result.")
01517 },
01518 &join_collapse_limit,
01519 8, 1, INT_MAX,
01520 NULL, NULL, NULL
01521 },
01522 {
01523 {"geqo_threshold", PGC_USERSET, QUERY_TUNING_GEQO,
01524 gettext_noop("Sets the threshold of FROM items beyond which GEQO is used."),
01525 NULL
01526 },
01527 &geqo_threshold,
01528 12, 2, INT_MAX,
01529 NULL, NULL, NULL
01530 },
01531 {
01532 {"geqo_effort", PGC_USERSET, QUERY_TUNING_GEQO,
01533 gettext_noop("GEQO: effort is used to set the default for other GEQO parameters."),
01534 NULL
01535 },
01536 &Geqo_effort,
01537 DEFAULT_GEQO_EFFORT, MIN_GEQO_EFFORT, MAX_GEQO_EFFORT,
01538 NULL, NULL, NULL
01539 },
01540 {
01541 {"geqo_pool_size", PGC_USERSET, QUERY_TUNING_GEQO,
01542 gettext_noop("GEQO: number of individuals in the population."),
01543 gettext_noop("Zero selects a suitable default value.")
01544 },
01545 &Geqo_pool_size,
01546 0, 0, INT_MAX,
01547 NULL, NULL, NULL
01548 },
01549 {
01550 {"geqo_generations", PGC_USERSET, QUERY_TUNING_GEQO,
01551 gettext_noop("GEQO: number of iterations of the algorithm."),
01552 gettext_noop("Zero selects a suitable default value.")
01553 },
01554 &Geqo_generations,
01555 0, 0, INT_MAX,
01556 NULL, NULL, NULL
01557 },
01558
01559 {
01560
01561 {"deadlock_timeout", PGC_SUSET, LOCK_MANAGEMENT,
01562 gettext_noop("Sets the time to wait on a lock before checking for deadlock."),
01563 NULL,
01564 GUC_UNIT_MS
01565 },
01566 &DeadlockTimeout,
01567 1000, 1, INT_MAX,
01568 NULL, NULL, NULL
01569 },
01570
01571 {
01572 {"max_standby_archive_delay", PGC_SIGHUP, REPLICATION_STANDBY,
01573 gettext_noop("Sets the maximum delay before canceling queries when a hot standby server is processing archived WAL data."),
01574 NULL,
01575 GUC_UNIT_MS
01576 },
01577 &max_standby_archive_delay,
01578 30 * 1000, -1, INT_MAX,
01579 NULL, NULL, NULL
01580 },
01581
01582 {
01583 {"max_standby_streaming_delay", PGC_SIGHUP, REPLICATION_STANDBY,
01584 gettext_noop("Sets the maximum delay before canceling queries when a hot standby server is processing streamed WAL data."),
01585 NULL,
01586 GUC_UNIT_MS
01587 },
01588 &max_standby_streaming_delay,
01589 30 * 1000, -1, INT_MAX,
01590 NULL, NULL, NULL
01591 },
01592
01593 {
01594 {"wal_receiver_status_interval", PGC_SIGHUP, REPLICATION_STANDBY,
01595 gettext_noop("Sets the maximum interval between WAL receiver status reports to the primary."),
01596 NULL,
01597 GUC_UNIT_S
01598 },
01599 &wal_receiver_status_interval,
01600 10, 0, INT_MAX / 1000,
01601 NULL, NULL, NULL
01602 },
01603
01604 {
01605 {"wal_receiver_timeout", PGC_SIGHUP, REPLICATION_STANDBY,
01606 gettext_noop("Sets the maximum wait time to receive data from master."),
01607 NULL,
01608 GUC_UNIT_MS
01609 },
01610 &wal_receiver_timeout,
01611 60 * 1000, 0, INT_MAX,
01612 NULL, NULL, NULL
01613 },
01614
01615 {
01616 {"max_connections", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
01617 gettext_noop("Sets the maximum number of concurrent connections."),
01618 NULL
01619 },
01620 &MaxConnections,
01621 100, 1, MAX_BACKENDS,
01622 check_maxconnections, NULL, NULL
01623 },
01624
01625 {
01626 {"superuser_reserved_connections", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
01627 gettext_noop("Sets the number of connection slots reserved for superusers."),
01628 NULL
01629 },
01630 &ReservedBackends,
01631 3, 0, MAX_BACKENDS,
01632 NULL, NULL, NULL
01633 },
01634
01635
01636
01637
01638
01639 {
01640 {"shared_buffers", PGC_POSTMASTER, RESOURCES_MEM,
01641 gettext_noop("Sets the number of shared memory buffers used by the server."),
01642 NULL,
01643 GUC_UNIT_BLOCKS
01644 },
01645 &NBuffers,
01646 1024, 16, INT_MAX / 2,
01647 NULL, NULL, NULL
01648 },
01649
01650 {
01651 {"temp_buffers", PGC_USERSET, RESOURCES_MEM,
01652 gettext_noop("Sets the maximum number of temporary buffers used by each session."),
01653 NULL,
01654 GUC_UNIT_BLOCKS
01655 },
01656 &num_temp_buffers,
01657 1024, 100, INT_MAX / 2,
01658 check_temp_buffers, NULL, NULL
01659 },
01660
01661 {
01662 {"port", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
01663 gettext_noop("Sets the TCP port the server listens on."),
01664 NULL
01665 },
01666 &PostPortNumber,
01667 DEF_PGPORT, 1, 65535,
01668 NULL, NULL, NULL
01669 },
01670
01671 {
01672 {"unix_socket_permissions", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
01673 gettext_noop("Sets the access permissions of the Unix-domain socket."),
01674 gettext_noop("Unix-domain sockets use the usual Unix file system "
01675 "permission set. The parameter value is expected "
01676 "to be a numeric mode specification in the form "
01677 "accepted by the chmod and umask system calls. "
01678 "(To use the customary octal format the number must "
01679 "start with a 0 (zero).)")
01680 },
01681 &Unix_socket_permissions,
01682 0777, 0000, 0777,
01683 NULL, NULL, show_unix_socket_permissions
01684 },
01685
01686 {
01687 {"log_file_mode", PGC_SIGHUP, LOGGING_WHERE,
01688 gettext_noop("Sets the file permissions for log files."),
01689 gettext_noop("The parameter value is expected "
01690 "to be a numeric mode specification in the form "
01691 "accepted by the chmod and umask system calls. "
01692 "(To use the customary octal format the number must "
01693 "start with a 0 (zero).)")
01694 },
01695 &Log_file_mode,
01696 0600, 0000, 0777,
01697 NULL, NULL, show_log_file_mode
01698 },
01699
01700 {
01701 {"work_mem", PGC_USERSET, RESOURCES_MEM,
01702 gettext_noop("Sets the maximum memory to be used for query workspaces."),
01703 gettext_noop("This much memory can be used by each internal "
01704 "sort operation and hash table before switching to "
01705 "temporary disk files."),
01706 GUC_UNIT_KB
01707 },
01708 &work_mem,
01709 1024, 64, MAX_KILOBYTES,
01710 NULL, NULL, NULL
01711 },
01712
01713 {
01714 {"maintenance_work_mem", PGC_USERSET, RESOURCES_MEM,
01715 gettext_noop("Sets the maximum memory to be used for maintenance operations."),
01716 gettext_noop("This includes operations such as VACUUM and CREATE INDEX."),
01717 GUC_UNIT_KB
01718 },
01719 &maintenance_work_mem,
01720 16384, 1024, MAX_KILOBYTES,
01721 NULL, NULL, NULL
01722 },
01723
01724
01725
01726
01727
01728
01729 {
01730 {"max_stack_depth", PGC_SUSET, RESOURCES_MEM,
01731 gettext_noop("Sets the maximum stack depth, in kilobytes."),
01732 NULL,
01733 GUC_UNIT_KB
01734 },
01735 &max_stack_depth,
01736 100, 100, MAX_KILOBYTES,
01737 check_max_stack_depth, assign_max_stack_depth, NULL
01738 },
01739
01740 {
01741 {"temp_file_limit", PGC_SUSET, RESOURCES_DISK,
01742 gettext_noop("Limits the total size of all temporary files used by each session."),
01743 gettext_noop("-1 means no limit."),
01744 GUC_UNIT_KB
01745 },
01746 &temp_file_limit,
01747 -1, -1, INT_MAX,
01748 NULL, NULL, NULL
01749 },
01750
01751 {
01752 {"vacuum_cost_page_hit", PGC_USERSET, RESOURCES_VACUUM_DELAY,
01753 gettext_noop("Vacuum cost for a page found in the buffer cache."),
01754 NULL
01755 },
01756 &VacuumCostPageHit,
01757 1, 0, 10000,
01758 NULL, NULL, NULL
01759 },
01760
01761 {
01762 {"vacuum_cost_page_miss", PGC_USERSET, RESOURCES_VACUUM_DELAY,
01763 gettext_noop("Vacuum cost for a page not found in the buffer cache."),
01764 NULL
01765 },
01766 &VacuumCostPageMiss,
01767 10, 0, 10000,
01768 NULL, NULL, NULL
01769 },
01770
01771 {
01772 {"vacuum_cost_page_dirty", PGC_USERSET, RESOURCES_VACUUM_DELAY,
01773 gettext_noop("Vacuum cost for a page dirtied by vacuum."),
01774 NULL
01775 },
01776 &VacuumCostPageDirty,
01777 20, 0, 10000,
01778 NULL, NULL, NULL
01779 },
01780
01781 {
01782 {"vacuum_cost_limit", PGC_USERSET, RESOURCES_VACUUM_DELAY,
01783 gettext_noop("Vacuum cost amount available before napping."),
01784 NULL
01785 },
01786 &VacuumCostLimit,
01787 200, 1, 10000,
01788 NULL, NULL, NULL
01789 },
01790
01791 {
01792 {"vacuum_cost_delay", PGC_USERSET, RESOURCES_VACUUM_DELAY,
01793 gettext_noop("Vacuum cost delay in milliseconds."),
01794 NULL,
01795 GUC_UNIT_MS
01796 },
01797 &VacuumCostDelay,
01798 0, 0, 100,
01799 NULL, NULL, NULL
01800 },
01801
01802 {
01803 {"autovacuum_vacuum_cost_delay", PGC_SIGHUP, AUTOVACUUM,
01804 gettext_noop("Vacuum cost delay in milliseconds, for autovacuum."),
01805 NULL,
01806 GUC_UNIT_MS
01807 },
01808 &autovacuum_vac_cost_delay,
01809 20, -1, 100,
01810 NULL, NULL, NULL
01811 },
01812
01813 {
01814 {"autovacuum_vacuum_cost_limit", PGC_SIGHUP, AUTOVACUUM,
01815 gettext_noop("Vacuum cost amount available before napping, for autovacuum."),
01816 NULL
01817 },
01818 &autovacuum_vac_cost_limit,
01819 -1, -1, 10000,
01820 NULL, NULL, NULL
01821 },
01822
01823 {
01824 {"max_files_per_process", PGC_POSTMASTER, RESOURCES_KERNEL,
01825 gettext_noop("Sets the maximum number of simultaneously open files for each server process."),
01826 NULL
01827 },
01828 &max_files_per_process,
01829 1000, 25, INT_MAX,
01830 NULL, NULL, NULL
01831 },
01832
01833
01834
01835
01836 {
01837 {"max_prepared_transactions", PGC_POSTMASTER, RESOURCES_MEM,
01838 gettext_noop("Sets the maximum number of simultaneously prepared transactions."),
01839 NULL
01840 },
01841 &max_prepared_xacts,
01842 0, 0, MAX_BACKENDS,
01843 NULL, NULL, NULL
01844 },
01845
01846 #ifdef LOCK_DEBUG
01847 {
01848 {"trace_lock_oidmin", PGC_SUSET, DEVELOPER_OPTIONS,
01849 gettext_noop("No description available."),
01850 NULL,
01851 GUC_NOT_IN_SAMPLE
01852 },
01853 &Trace_lock_oidmin,
01854 FirstNormalObjectId, 0, INT_MAX,
01855 NULL, NULL, NULL
01856 },
01857 {
01858 {"trace_lock_table", PGC_SUSET, DEVELOPER_OPTIONS,
01859 gettext_noop("No description available."),
01860 NULL,
01861 GUC_NOT_IN_SAMPLE
01862 },
01863 &Trace_lock_table,
01864 0, 0, INT_MAX,
01865 NULL, NULL, NULL
01866 },
01867 #endif
01868
01869 {
01870 {"statement_timeout", PGC_USERSET, CLIENT_CONN_STATEMENT,
01871 gettext_noop("Sets the maximum allowed duration of any statement."),
01872 gettext_noop("A value of 0 turns off the timeout."),
01873 GUC_UNIT_MS
01874 },
01875 &StatementTimeout,
01876 0, 0, INT_MAX,
01877 NULL, NULL, NULL
01878 },
01879
01880 {
01881 {"lock_timeout", PGC_USERSET, CLIENT_CONN_STATEMENT,
01882 gettext_noop("Sets the maximum allowed duration of any wait for a lock."),
01883 gettext_noop("A value of 0 turns off the timeout."),
01884 GUC_UNIT_MS
01885 },
01886 &LockTimeout,
01887 0, 0, INT_MAX,
01888 NULL, NULL, NULL
01889 },
01890
01891 {
01892 {"vacuum_freeze_min_age", PGC_USERSET, CLIENT_CONN_STATEMENT,
01893 gettext_noop("Minimum age at which VACUUM should freeze a table row."),
01894 NULL
01895 },
01896 &vacuum_freeze_min_age,
01897 50000000, 0, 1000000000,
01898 NULL, NULL, NULL
01899 },
01900
01901 {
01902 {"vacuum_freeze_table_age", PGC_USERSET, CLIENT_CONN_STATEMENT,
01903 gettext_noop("Age at which VACUUM should scan whole table to freeze tuples."),
01904 NULL
01905 },
01906 &vacuum_freeze_table_age,
01907 150000000, 0, 2000000000,
01908 NULL, NULL, NULL
01909 },
01910
01911 {
01912 {"vacuum_defer_cleanup_age", PGC_SIGHUP, REPLICATION_MASTER,
01913 gettext_noop("Number of transactions by which VACUUM and HOT cleanup should be deferred, if any."),
01914 NULL
01915 },
01916 &vacuum_defer_cleanup_age,
01917 0, 0, 1000000,
01918 NULL, NULL, NULL
01919 },
01920
01921
01922
01923
01924 {
01925 {"max_locks_per_transaction", PGC_POSTMASTER, LOCK_MANAGEMENT,
01926 gettext_noop("Sets the maximum number of locks per transaction."),
01927 gettext_noop("The shared lock table is sized on the assumption that "
01928 "at most max_locks_per_transaction * max_connections distinct "
01929 "objects will need to be locked at any one time.")
01930 },
01931 &max_locks_per_xact,
01932 64, 10, INT_MAX,
01933 NULL, NULL, NULL
01934 },
01935
01936 {
01937 {"max_pred_locks_per_transaction", PGC_POSTMASTER, LOCK_MANAGEMENT,
01938 gettext_noop("Sets the maximum number of predicate locks per transaction."),
01939 gettext_noop("The shared predicate lock table is sized on the assumption that "
01940 "at most max_pred_locks_per_transaction * max_connections distinct "
01941 "objects will need to be locked at any one time.")
01942 },
01943 &max_predicate_locks_per_xact,
01944 64, 10, INT_MAX,
01945 NULL, NULL, NULL
01946 },
01947
01948 {
01949 {"authentication_timeout", PGC_SIGHUP, CONN_AUTH_SECURITY,
01950 gettext_noop("Sets the maximum allowed time to complete client authentication."),
01951 NULL,
01952 GUC_UNIT_S
01953 },
01954 &AuthenticationTimeout,
01955 60, 1, 600,
01956 NULL, NULL, NULL
01957 },
01958
01959 {
01960
01961 {"pre_auth_delay", PGC_SIGHUP, DEVELOPER_OPTIONS,
01962 gettext_noop("Waits N seconds on connection startup before authentication."),
01963 gettext_noop("This allows attaching a debugger to the process."),
01964 GUC_NOT_IN_SAMPLE | GUC_UNIT_S
01965 },
01966 &PreAuthDelay,
01967 0, 0, 60,
01968 NULL, NULL, NULL
01969 },
01970
01971 {
01972 {"wal_keep_segments", PGC_SIGHUP, REPLICATION_SENDING,
01973 gettext_noop("Sets the number of WAL files held for standby servers."),
01974 NULL
01975 },
01976 &wal_keep_segments,
01977 0, 0, INT_MAX,
01978 NULL, NULL, NULL
01979 },
01980
01981 {
01982 {"checkpoint_segments", PGC_SIGHUP, WAL_CHECKPOINTS,
01983 gettext_noop("Sets the maximum distance in log segments between automatic WAL checkpoints."),
01984 NULL
01985 },
01986 &CheckPointSegments,
01987 3, 1, INT_MAX,
01988 NULL, NULL, NULL
01989 },
01990
01991 {
01992 {"checkpoint_timeout", PGC_SIGHUP, WAL_CHECKPOINTS,
01993 gettext_noop("Sets the maximum time between automatic WAL checkpoints."),
01994 NULL,
01995 GUC_UNIT_S
01996 },
01997 &CheckPointTimeout,
01998 300, 30, 3600,
01999 NULL, NULL, NULL
02000 },
02001
02002 {
02003 {"checkpoint_warning", PGC_SIGHUP, WAL_CHECKPOINTS,
02004 gettext_noop("Enables warnings if checkpoint segments are filled more "
02005 "frequently than this."),
02006 gettext_noop("Write a message to the server log if checkpoints "
02007 "caused by the filling of checkpoint segment files happens more "
02008 "frequently than this number of seconds. Zero turns off the warning."),
02009 GUC_UNIT_S
02010 },
02011 &CheckPointWarning,
02012 30, 0, INT_MAX,
02013 NULL, NULL, NULL
02014 },
02015
02016 {
02017 {"wal_buffers", PGC_POSTMASTER, WAL_SETTINGS,
02018 gettext_noop("Sets the number of disk-page buffers in shared memory for WAL."),
02019 NULL,
02020 GUC_UNIT_XBLOCKS
02021 },
02022 &XLOGbuffers,
02023 -1, -1, INT_MAX,
02024 check_wal_buffers, NULL, NULL
02025 },
02026
02027 {
02028 {"wal_writer_delay", PGC_SIGHUP, WAL_SETTINGS,
02029 gettext_noop("WAL writer sleep time between WAL flushes."),
02030 NULL,
02031 GUC_UNIT_MS
02032 },
02033 &WalWriterDelay,
02034 200, 1, 10000,
02035 NULL, NULL, NULL
02036 },
02037
02038 {
02039
02040 {"max_wal_senders", PGC_POSTMASTER, REPLICATION_SENDING,
02041 gettext_noop("Sets the maximum number of simultaneously running WAL sender processes."),
02042 NULL
02043 },
02044 &max_wal_senders,
02045 0, 0, MAX_BACKENDS,
02046 NULL, NULL, NULL
02047 },
02048
02049 {
02050 {"wal_sender_timeout", PGC_SIGHUP, REPLICATION_SENDING,
02051 gettext_noop("Sets the maximum time to wait for WAL replication."),
02052 NULL,
02053 GUC_UNIT_MS
02054 },
02055 &wal_sender_timeout,
02056 60 * 1000, 0, INT_MAX,
02057 NULL, NULL, NULL
02058 },
02059
02060 {
02061 {"commit_delay", PGC_SUSET, WAL_SETTINGS,
02062 gettext_noop("Sets the delay in microseconds between transaction commit and "
02063 "flushing WAL to disk."),
02064 NULL
02065
02066 },
02067 &CommitDelay,
02068 0, 0, 100000,
02069 NULL, NULL, NULL
02070 },
02071
02072 {
02073 {"commit_siblings", PGC_USERSET, WAL_SETTINGS,
02074 gettext_noop("Sets the minimum concurrent open transactions before performing "
02075 "commit_delay."),
02076 NULL
02077 },
02078 &CommitSiblings,
02079 5, 0, 1000,
02080 NULL, NULL, NULL
02081 },
02082
02083 {
02084 {"extra_float_digits", PGC_USERSET, CLIENT_CONN_LOCALE,
02085 gettext_noop("Sets the number of digits displayed for floating-point values."),
02086 gettext_noop("This affects real, double precision, and geometric data types. "
02087 "The parameter value is added to the standard number of digits "
02088 "(FLT_DIG or DBL_DIG as appropriate).")
02089 },
02090 &extra_float_digits,
02091 0, -15, 3,
02092 NULL, NULL, NULL
02093 },
02094
02095 {
02096 {"log_min_duration_statement", PGC_SUSET, LOGGING_WHEN,
02097 gettext_noop("Sets the minimum execution time above which "
02098 "statements will be logged."),
02099 gettext_noop("Zero prints all queries. -1 turns this feature off."),
02100 GUC_UNIT_MS
02101 },
02102 &log_min_duration_statement,
02103 -1, -1, INT_MAX,
02104 NULL, NULL, NULL
02105 },
02106
02107 {
02108 {"log_autovacuum_min_duration", PGC_SIGHUP, LOGGING_WHAT,
02109 gettext_noop("Sets the minimum execution time above which "
02110 "autovacuum actions will be logged."),
02111 gettext_noop("Zero prints all actions. -1 turns autovacuum logging off."),
02112 GUC_UNIT_MS
02113 },
02114 &Log_autovacuum_min_duration,
02115 -1, -1, INT_MAX,
02116 NULL, NULL, NULL
02117 },
02118
02119 {
02120 {"bgwriter_delay", PGC_SIGHUP, RESOURCES_BGWRITER,
02121 gettext_noop("Background writer sleep time between rounds."),
02122 NULL,
02123 GUC_UNIT_MS
02124 },
02125 &BgWriterDelay,
02126 200, 10, 10000,
02127 NULL, NULL, NULL
02128 },
02129
02130 {
02131 {"bgwriter_lru_maxpages", PGC_SIGHUP, RESOURCES_BGWRITER,
02132 gettext_noop("Background writer maximum number of LRU pages to flush per round."),
02133 NULL
02134 },
02135 &bgwriter_lru_maxpages,
02136 100, 0, 1000,
02137 NULL, NULL, NULL
02138 },
02139
02140 {
02141 {"effective_io_concurrency",
02142 #ifdef USE_PREFETCH
02143 PGC_USERSET,
02144 #else
02145 PGC_INTERNAL,
02146 #endif
02147 RESOURCES_ASYNCHRONOUS,
02148 gettext_noop("Number of simultaneous requests that can be handled efficiently by the disk subsystem."),
02149 gettext_noop("For RAID arrays, this should be approximately the number of drive spindles in the array.")
02150 },
02151 &effective_io_concurrency,
02152 #ifdef USE_PREFETCH
02153 1, 0, 1000,
02154 #else
02155 0, 0, 0,
02156 #endif
02157 check_effective_io_concurrency, assign_effective_io_concurrency, NULL
02158 },
02159
02160 {
02161 {"log_rotation_age", PGC_SIGHUP, LOGGING_WHERE,
02162 gettext_noop("Automatic log file rotation will occur after N minutes."),
02163 NULL,
02164 GUC_UNIT_MIN
02165 },
02166 &Log_RotationAge,
02167 HOURS_PER_DAY * MINS_PER_HOUR, 0, INT_MAX / SECS_PER_MINUTE,
02168 NULL, NULL, NULL
02169 },
02170
02171 {
02172 {"log_rotation_size", PGC_SIGHUP, LOGGING_WHERE,
02173 gettext_noop("Automatic log file rotation will occur after N kilobytes."),
02174 NULL,
02175 GUC_UNIT_KB
02176 },
02177 &Log_RotationSize,
02178 10 * 1024, 0, INT_MAX / 1024,
02179 NULL, NULL, NULL
02180 },
02181
02182 {
02183 {"max_function_args", PGC_INTERNAL, PRESET_OPTIONS,
02184 gettext_noop("Shows the maximum number of function arguments."),
02185 NULL,
02186 GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
02187 },
02188 &max_function_args,
02189 FUNC_MAX_ARGS, FUNC_MAX_ARGS, FUNC_MAX_ARGS,
02190 NULL, NULL, NULL
02191 },
02192
02193 {
02194 {"max_index_keys", PGC_INTERNAL, PRESET_OPTIONS,
02195 gettext_noop("Shows the maximum number of index keys."),
02196 NULL,
02197 GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
02198 },
02199 &max_index_keys,
02200 INDEX_MAX_KEYS, INDEX_MAX_KEYS, INDEX_MAX_KEYS,
02201 NULL, NULL, NULL
02202 },
02203
02204 {
02205 {"max_identifier_length", PGC_INTERNAL, PRESET_OPTIONS,
02206 gettext_noop("Shows the maximum identifier length."),
02207 NULL,
02208 GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
02209 },
02210 &max_identifier_length,
02211 NAMEDATALEN - 1, NAMEDATALEN - 1, NAMEDATALEN - 1,
02212 NULL, NULL, NULL
02213 },
02214
02215 {
02216 {"block_size", PGC_INTERNAL, PRESET_OPTIONS,
02217 gettext_noop("Shows the size of a disk block."),
02218 NULL,
02219 GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
02220 },
02221 &block_size,
02222 BLCKSZ, BLCKSZ, BLCKSZ,
02223 NULL, NULL, NULL
02224 },
02225
02226 {
02227 {"segment_size", PGC_INTERNAL, PRESET_OPTIONS,
02228 gettext_noop("Shows the number of pages per disk file."),
02229 NULL,
02230 GUC_UNIT_BLOCKS | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
02231 },
02232 &segment_size,
02233 RELSEG_SIZE, RELSEG_SIZE, RELSEG_SIZE,
02234 NULL, NULL, NULL
02235 },
02236
02237 {
02238 {"wal_block_size", PGC_INTERNAL, PRESET_OPTIONS,
02239 gettext_noop("Shows the block size in the write ahead log."),
02240 NULL,
02241 GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
02242 },
02243 &wal_block_size,
02244 XLOG_BLCKSZ, XLOG_BLCKSZ, XLOG_BLCKSZ,
02245 NULL, NULL, NULL
02246 },
02247
02248 {
02249 {"wal_segment_size", PGC_INTERNAL, PRESET_OPTIONS,
02250 gettext_noop("Shows the number of pages per write ahead log segment."),
02251 NULL,
02252 GUC_UNIT_XBLOCKS | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
02253 },
02254 &wal_segment_size,
02255 (XLOG_SEG_SIZE / XLOG_BLCKSZ),
02256 (XLOG_SEG_SIZE / XLOG_BLCKSZ),
02257 (XLOG_SEG_SIZE / XLOG_BLCKSZ),
02258 NULL, NULL, NULL
02259 },
02260
02261 {
02262 {"autovacuum_naptime", PGC_SIGHUP, AUTOVACUUM,
02263 gettext_noop("Time to sleep between autovacuum runs."),
02264 NULL,
02265 GUC_UNIT_S
02266 },
02267 &autovacuum_naptime,
02268 60, 1, INT_MAX / 1000,
02269 NULL, NULL, NULL
02270 },
02271 {
02272 {"autovacuum_vacuum_threshold", PGC_SIGHUP, AUTOVACUUM,
02273 gettext_noop("Minimum number of tuple updates or deletes prior to vacuum."),
02274 NULL
02275 },
02276 &autovacuum_vac_thresh,
02277 50, 0, INT_MAX,
02278 NULL, NULL, NULL
02279 },
02280 {
02281 {"autovacuum_analyze_threshold", PGC_SIGHUP, AUTOVACUUM,
02282 gettext_noop("Minimum number of tuple inserts, updates, or deletes prior to analyze."),
02283 NULL
02284 },
02285 &autovacuum_anl_thresh,
02286 50, 0, INT_MAX,
02287 NULL, NULL, NULL
02288 },
02289 {
02290
02291 {"autovacuum_freeze_max_age", PGC_POSTMASTER, AUTOVACUUM,
02292 gettext_noop("Age at which to autovacuum a table to prevent transaction ID wraparound."),
02293 NULL
02294 },
02295 &autovacuum_freeze_max_age,
02296
02297 200000000, 100000000, 2000000000,
02298 NULL, NULL, NULL
02299 },
02300 {
02301
02302 {"autovacuum_max_workers", PGC_POSTMASTER, AUTOVACUUM,
02303 gettext_noop("Sets the maximum number of simultaneously running autovacuum worker processes."),
02304 NULL
02305 },
02306 &autovacuum_max_workers,
02307 3, 1, MAX_BACKENDS,
02308 check_autovacuum_max_workers, NULL, NULL
02309 },
02310
02311 {
02312 {"tcp_keepalives_idle", PGC_USERSET, CLIENT_CONN_OTHER,
02313 gettext_noop("Time between issuing TCP keepalives."),
02314 gettext_noop("A value of 0 uses the system default."),
02315 GUC_UNIT_S
02316 },
02317 &tcp_keepalives_idle,
02318 0, 0, INT_MAX,
02319 NULL, assign_tcp_keepalives_idle, show_tcp_keepalives_idle
02320 },
02321
02322 {
02323 {"tcp_keepalives_interval", PGC_USERSET, CLIENT_CONN_OTHER,
02324 gettext_noop("Time between TCP keepalive retransmits."),
02325 gettext_noop("A value of 0 uses the system default."),
02326 GUC_UNIT_S
02327 },
02328 &tcp_keepalives_interval,
02329 0, 0, INT_MAX,
02330 NULL, assign_tcp_keepalives_interval, show_tcp_keepalives_interval
02331 },
02332
02333 {
02334 {"ssl_renegotiation_limit", PGC_USERSET, CONN_AUTH_SECURITY,
02335 gettext_noop("Set the amount of traffic to send and receive before renegotiating the encryption keys."),
02336 NULL,
02337 GUC_UNIT_KB,
02338 },
02339 &ssl_renegotiation_limit,
02340 512 * 1024, 0, MAX_KILOBYTES,
02341 NULL, NULL, NULL
02342 },
02343
02344 {
02345 {"tcp_keepalives_count", PGC_USERSET, CLIENT_CONN_OTHER,
02346 gettext_noop("Maximum number of TCP keepalive retransmits."),
02347 gettext_noop("This controls the number of consecutive keepalive retransmits that can be "
02348 "lost before a connection is considered dead. A value of 0 uses the "
02349 "system default."),
02350 },
02351 &tcp_keepalives_count,
02352 0, 0, INT_MAX,
02353 NULL, assign_tcp_keepalives_count, show_tcp_keepalives_count
02354 },
02355
02356 {
02357 {"gin_fuzzy_search_limit", PGC_USERSET, CLIENT_CONN_OTHER,
02358 gettext_noop("Sets the maximum allowed result for exact search by GIN."),
02359 NULL,
02360 0
02361 },
02362 &GinFuzzySearchLimit,
02363 0, 0, INT_MAX,
02364 NULL, NULL, NULL
02365 },
02366
02367 {
02368 {"effective_cache_size", PGC_USERSET, QUERY_TUNING_COST,
02369 gettext_noop("Sets the planner's assumption about the size of the disk cache."),
02370 gettext_noop("That is, the portion of the kernel's disk cache that "
02371 "will be used for PostgreSQL data files. This is measured in disk "
02372 "pages, which are normally 8 kB each."),
02373 GUC_UNIT_BLOCKS,
02374 },
02375 &effective_cache_size,
02376 DEFAULT_EFFECTIVE_CACHE_SIZE, 1, INT_MAX,
02377 NULL, NULL, NULL
02378 },
02379
02380 {
02381
02382 {"server_version_num", PGC_INTERNAL, PRESET_OPTIONS,
02383 gettext_noop("Shows the server version as an integer."),
02384 NULL,
02385 GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
02386 },
02387 &server_version_num,
02388 PG_VERSION_NUM, PG_VERSION_NUM, PG_VERSION_NUM,
02389 NULL, NULL, NULL
02390 },
02391
02392 {
02393 {"log_temp_files", PGC_SUSET, LOGGING_WHAT,
02394 gettext_noop("Log the use of temporary files larger than this number of kilobytes."),
02395 gettext_noop("Zero logs all files. The default is -1 (turning this feature off)."),
02396 GUC_UNIT_KB
02397 },
02398 &log_temp_files,
02399 -1, -1, INT_MAX,
02400 NULL, NULL, NULL
02401 },
02402
02403 {
02404 {"track_activity_query_size", PGC_POSTMASTER, RESOURCES_MEM,
02405 gettext_noop("Sets the size reserved for pg_stat_activity.query, in bytes."),
02406 NULL,
02407 },
02408 &pgstat_track_activity_query_size,
02409 1024, 100, 102400,
02410 NULL, NULL, NULL
02411 },
02412
02413
02414 {
02415 {NULL, 0, 0, NULL, NULL}, NULL, 0, 0, 0, NULL, NULL, NULL
02416 }
02417 };
02418
02419
02420 static struct config_real ConfigureNamesReal[] =
02421 {
02422 {
02423 {"seq_page_cost", PGC_USERSET, QUERY_TUNING_COST,
02424 gettext_noop("Sets the planner's estimate of the cost of a "
02425 "sequentially fetched disk page."),
02426 NULL
02427 },
02428 &seq_page_cost,
02429 DEFAULT_SEQ_PAGE_COST, 0, DBL_MAX,
02430 NULL, NULL, NULL
02431 },
02432 {
02433 {"random_page_cost", PGC_USERSET, QUERY_TUNING_COST,
02434 gettext_noop("Sets the planner's estimate of the cost of a "
02435 "nonsequentially fetched disk page."),
02436 NULL
02437 },
02438 &random_page_cost,
02439 DEFAULT_RANDOM_PAGE_COST, 0, DBL_MAX,
02440 NULL, NULL, NULL
02441 },
02442 {
02443 {"cpu_tuple_cost", PGC_USERSET, QUERY_TUNING_COST,
02444 gettext_noop("Sets the planner's estimate of the cost of "
02445 "processing each tuple (row)."),
02446 NULL
02447 },
02448 &cpu_tuple_cost,
02449 DEFAULT_CPU_TUPLE_COST, 0, DBL_MAX,
02450 NULL, NULL, NULL
02451 },
02452 {
02453 {"cpu_index_tuple_cost", PGC_USERSET, QUERY_TUNING_COST,
02454 gettext_noop("Sets the planner's estimate of the cost of "
02455 "processing each index entry during an index scan."),
02456 NULL
02457 },
02458 &cpu_index_tuple_cost,
02459 DEFAULT_CPU_INDEX_TUPLE_COST, 0, DBL_MAX,
02460 NULL, NULL, NULL
02461 },
02462 {
02463 {"cpu_operator_cost", PGC_USERSET, QUERY_TUNING_COST,
02464 gettext_noop("Sets the planner's estimate of the cost of "
02465 "processing each operator or function call."),
02466 NULL
02467 },
02468 &cpu_operator_cost,
02469 DEFAULT_CPU_OPERATOR_COST, 0, DBL_MAX,
02470 NULL, NULL, NULL
02471 },
02472
02473 {
02474 {"cursor_tuple_fraction", PGC_USERSET, QUERY_TUNING_OTHER,
02475 gettext_noop("Sets the planner's estimate of the fraction of "
02476 "a cursor's rows that will be retrieved."),
02477 NULL
02478 },
02479 &cursor_tuple_fraction,
02480 DEFAULT_CURSOR_TUPLE_FRACTION, 0.0, 1.0,
02481 NULL, NULL, NULL
02482 },
02483
02484 {
02485 {"geqo_selection_bias", PGC_USERSET, QUERY_TUNING_GEQO,
02486 gettext_noop("GEQO: selective pressure within the population."),
02487 NULL
02488 },
02489 &Geqo_selection_bias,
02490 DEFAULT_GEQO_SELECTION_BIAS,
02491 MIN_GEQO_SELECTION_BIAS, MAX_GEQO_SELECTION_BIAS,
02492 NULL, NULL, NULL
02493 },
02494 {
02495 {"geqo_seed", PGC_USERSET, QUERY_TUNING_GEQO,
02496 gettext_noop("GEQO: seed for random path selection."),
02497 NULL
02498 },
02499 &Geqo_seed,
02500 0.0, 0.0, 1.0,
02501 NULL, NULL, NULL
02502 },
02503
02504 {
02505 {"bgwriter_lru_multiplier", PGC_SIGHUP, RESOURCES_BGWRITER,
02506 gettext_noop("Multiple of the average buffer usage to free per round."),
02507 NULL
02508 },
02509 &bgwriter_lru_multiplier,
02510 2.0, 0.0, 10.0,
02511 NULL, NULL, NULL
02512 },
02513
02514 {
02515 {"seed", PGC_USERSET, UNGROUPED,
02516 gettext_noop("Sets the seed for random-number generation."),
02517 NULL,
02518 GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
02519 },
02520 &phony_random_seed,
02521 0.0, -1.0, 1.0,
02522 check_random_seed, assign_random_seed, show_random_seed
02523 },
02524
02525 {
02526 {"autovacuum_vacuum_scale_factor", PGC_SIGHUP, AUTOVACUUM,
02527 gettext_noop("Number of tuple updates or deletes prior to vacuum as a fraction of reltuples."),
02528 NULL
02529 },
02530 &autovacuum_vac_scale,
02531 0.2, 0.0, 100.0,
02532 NULL, NULL, NULL
02533 },
02534 {
02535 {"autovacuum_analyze_scale_factor", PGC_SIGHUP, AUTOVACUUM,
02536 gettext_noop("Number of tuple inserts, updates, or deletes prior to analyze as a fraction of reltuples."),
02537 NULL
02538 },
02539 &autovacuum_anl_scale,
02540 0.1, 0.0, 100.0,
02541 NULL, NULL, NULL
02542 },
02543
02544 {
02545 {"checkpoint_completion_target", PGC_SIGHUP, WAL_CHECKPOINTS,
02546 gettext_noop("Time spent flushing dirty buffers during checkpoint, as fraction of checkpoint interval."),
02547 NULL
02548 },
02549 &CheckPointCompletionTarget,
02550 0.5, 0.0, 1.0,
02551 NULL, NULL, NULL
02552 },
02553
02554
02555 {
02556 {NULL, 0, 0, NULL, NULL}, NULL, 0.0, 0.0, 0.0, NULL, NULL, NULL
02557 }
02558 };
02559
02560
02561 static struct config_string ConfigureNamesString[] =
02562 {
02563 {
02564 {"archive_command", PGC_SIGHUP, WAL_ARCHIVING,
02565 gettext_noop("Sets the shell command that will be called to archive a WAL file."),
02566 NULL
02567 },
02568 &XLogArchiveCommand,
02569 "",
02570 NULL, NULL, show_archive_command
02571 },
02572
02573 {
02574 {"client_encoding", PGC_USERSET, CLIENT_CONN_LOCALE,
02575 gettext_noop("Sets the client's character set encoding."),
02576 NULL,
02577 GUC_IS_NAME | GUC_REPORT
02578 },
02579 &client_encoding_string,
02580 "SQL_ASCII",
02581 check_client_encoding, assign_client_encoding, NULL
02582 },
02583
02584 {
02585 {"log_line_prefix", PGC_SIGHUP, LOGGING_WHAT,
02586 gettext_noop("Controls information prefixed to each log line."),
02587 gettext_noop("If blank, no prefix is used.")
02588 },
02589 &Log_line_prefix,
02590 "",
02591 NULL, NULL, NULL
02592 },
02593
02594 {
02595 {"log_timezone", PGC_SIGHUP, LOGGING_WHAT,
02596 gettext_noop("Sets the time zone to use in log messages."),
02597 NULL
02598 },
02599 &log_timezone_string,
02600 "GMT",
02601 check_log_timezone, assign_log_timezone, show_log_timezone
02602 },
02603
02604 {
02605 {"DateStyle", PGC_USERSET, CLIENT_CONN_LOCALE,
02606 gettext_noop("Sets the display format for date and time values."),
02607 gettext_noop("Also controls interpretation of ambiguous "
02608 "date inputs."),
02609 GUC_LIST_INPUT | GUC_REPORT
02610 },
02611 &datestyle_string,
02612 "ISO, MDY",
02613 check_datestyle, assign_datestyle, NULL
02614 },
02615
02616 {
02617 {"default_tablespace", PGC_USERSET, CLIENT_CONN_STATEMENT,
02618 gettext_noop("Sets the default tablespace to create tables and indexes in."),
02619 gettext_noop("An empty string selects the database's default tablespace."),
02620 GUC_IS_NAME
02621 },
02622 &default_tablespace,
02623 "",
02624 check_default_tablespace, NULL, NULL
02625 },
02626
02627 {
02628 {"temp_tablespaces", PGC_USERSET, CLIENT_CONN_STATEMENT,
02629 gettext_noop("Sets the tablespace(s) to use for temporary tables and sort files."),
02630 NULL,
02631 GUC_LIST_INPUT | GUC_LIST_QUOTE
02632 },
02633 &temp_tablespaces,
02634 "",
02635 check_temp_tablespaces, assign_temp_tablespaces, NULL
02636 },
02637
02638 {
02639 {"dynamic_library_path", PGC_SUSET, CLIENT_CONN_OTHER,
02640 gettext_noop("Sets the path for dynamically loadable modules."),
02641 gettext_noop("If a dynamically loadable module needs to be opened and "
02642 "the specified name does not have a directory component (i.e., the "
02643 "name does not contain a slash), the system will search this path for "
02644 "the specified file."),
02645 GUC_SUPERUSER_ONLY
02646 },
02647 &Dynamic_library_path,
02648 "$libdir",
02649 NULL, NULL, NULL
02650 },
02651
02652 {
02653 {"krb_server_keyfile", PGC_SIGHUP, CONN_AUTH_SECURITY,
02654 gettext_noop("Sets the location of the Kerberos server key file."),
02655 NULL,
02656 GUC_SUPERUSER_ONLY
02657 },
02658 &pg_krb_server_keyfile,
02659 PG_KRB_SRVTAB,
02660 NULL, NULL, NULL
02661 },
02662
02663 {
02664 {"krb_srvname", PGC_SIGHUP, CONN_AUTH_SECURITY,
02665 gettext_noop("Sets the name of the Kerberos service."),
02666 NULL
02667 },
02668 &pg_krb_srvnam,
02669 PG_KRB_SRVNAM,
02670 NULL, NULL, NULL
02671 },
02672
02673 {
02674 {"bonjour_name", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
02675 gettext_noop("Sets the Bonjour service name."),
02676 NULL
02677 },
02678 &bonjour_name,
02679 "",
02680 NULL, NULL, NULL
02681 },
02682
02683
02684
02685 {
02686 {"lc_collate", PGC_INTERNAL, CLIENT_CONN_LOCALE,
02687 gettext_noop("Shows the collation order locale."),
02688 NULL,
02689 GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
02690 },
02691 &locale_collate,
02692 "C",
02693 NULL, NULL, NULL
02694 },
02695
02696 {
02697 {"lc_ctype", PGC_INTERNAL, CLIENT_CONN_LOCALE,
02698 gettext_noop("Shows the character classification and case conversion locale."),
02699 NULL,
02700 GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
02701 },
02702 &locale_ctype,
02703 "C",
02704 NULL, NULL, NULL
02705 },
02706
02707 {
02708 {"lc_messages", PGC_SUSET, CLIENT_CONN_LOCALE,
02709 gettext_noop("Sets the language in which messages are displayed."),
02710 NULL
02711 },
02712 &locale_messages,
02713 "",
02714 check_locale_messages, assign_locale_messages, NULL
02715 },
02716
02717 {
02718 {"lc_monetary", PGC_USERSET, CLIENT_CONN_LOCALE,
02719 gettext_noop("Sets the locale for formatting monetary amounts."),
02720 NULL
02721 },
02722 &locale_monetary,
02723 "C",
02724 check_locale_monetary, assign_locale_monetary, NULL
02725 },
02726
02727 {
02728 {"lc_numeric", PGC_USERSET, CLIENT_CONN_LOCALE,
02729 gettext_noop("Sets the locale for formatting numbers."),
02730 NULL
02731 },
02732 &locale_numeric,
02733 "C",
02734 check_locale_numeric, assign_locale_numeric, NULL
02735 },
02736
02737 {
02738 {"lc_time", PGC_USERSET, CLIENT_CONN_LOCALE,
02739 gettext_noop("Sets the locale for formatting date and time values."),
02740 NULL
02741 },
02742 &locale_time,
02743 "C",
02744 check_locale_time, assign_locale_time, NULL
02745 },
02746
02747 {
02748 {"shared_preload_libraries", PGC_POSTMASTER, RESOURCES_KERNEL,
02749 gettext_noop("Lists shared libraries to preload into server."),
02750 NULL,
02751 GUC_LIST_INPUT | GUC_LIST_QUOTE | GUC_SUPERUSER_ONLY
02752 },
02753 &shared_preload_libraries_string,
02754 "",
02755 NULL, NULL, NULL
02756 },
02757
02758 {
02759 {"local_preload_libraries", PGC_BACKEND, CLIENT_CONN_OTHER,
02760 gettext_noop("Lists shared libraries to preload into each backend."),
02761 NULL,
02762 GUC_LIST_INPUT | GUC_LIST_QUOTE
02763 },
02764 &local_preload_libraries_string,
02765 "",
02766 NULL, NULL, NULL
02767 },
02768
02769 {
02770 {"search_path", PGC_USERSET, CLIENT_CONN_STATEMENT,
02771 gettext_noop("Sets the schema search order for names that are not schema-qualified."),
02772 NULL,
02773 GUC_LIST_INPUT | GUC_LIST_QUOTE
02774 },
02775 &namespace_search_path,
02776 "\"$user\",public",
02777 check_search_path, assign_search_path, NULL
02778 },
02779
02780 {
02781
02782 {"server_encoding", PGC_INTERNAL, CLIENT_CONN_LOCALE,
02783 gettext_noop("Sets the server (database) character set encoding."),
02784 NULL,
02785 GUC_IS_NAME | GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
02786 },
02787 &server_encoding_string,
02788 "SQL_ASCII",
02789 NULL, NULL, NULL
02790 },
02791
02792 {
02793
02794 {"server_version", PGC_INTERNAL, PRESET_OPTIONS,
02795 gettext_noop("Shows the server version."),
02796 NULL,
02797 GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
02798 },
02799 &server_version_string,
02800 PG_VERSION,
02801 NULL, NULL, NULL
02802 },
02803
02804 {
02805
02806 {"role", PGC_USERSET, UNGROUPED,
02807 gettext_noop("Sets the current role."),
02808 NULL,
02809 GUC_IS_NAME | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_NOT_WHILE_SEC_REST
02810 },
02811 &role_string,
02812 "none",
02813 check_role, assign_role, show_role
02814 },
02815
02816 {
02817
02818 {"session_authorization", PGC_USERSET, UNGROUPED,
02819 gettext_noop("Sets the session user name."),
02820 NULL,
02821 GUC_IS_NAME | GUC_REPORT | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_NOT_WHILE_SEC_REST
02822 },
02823 &session_authorization_string,
02824 NULL,
02825 check_session_authorization, assign_session_authorization, NULL
02826 },
02827
02828 {
02829 {"log_destination", PGC_SIGHUP, LOGGING_WHERE,
02830 gettext_noop("Sets the destination for server log output."),
02831 gettext_noop("Valid values are combinations of \"stderr\", "
02832 "\"syslog\", \"csvlog\", and \"eventlog\", "
02833 "depending on the platform."),
02834 GUC_LIST_INPUT
02835 },
02836 &log_destination_string,
02837 "stderr",
02838 check_log_destination, assign_log_destination, NULL
02839 },
02840 {
02841 {"log_directory", PGC_SIGHUP, LOGGING_WHERE,
02842 gettext_noop("Sets the destination directory for log files."),
02843 gettext_noop("Can be specified as relative to the data directory "
02844 "or as absolute path."),
02845 GUC_SUPERUSER_ONLY
02846 },
02847 &Log_directory,
02848 "pg_log",
02849 check_canonical_path, NULL, NULL
02850 },
02851 {
02852 {"log_filename", PGC_SIGHUP, LOGGING_WHERE,
02853 gettext_noop("Sets the file name pattern for log files."),
02854 NULL,
02855 GUC_SUPERUSER_ONLY
02856 },
02857 &Log_filename,
02858 "postgresql-%Y-%m-%d_%H%M%S.log",
02859 NULL, NULL, NULL
02860 },
02861
02862 {
02863 {"syslog_ident", PGC_SIGHUP, LOGGING_WHERE,
02864 gettext_noop("Sets the program name used to identify PostgreSQL "
02865 "messages in syslog."),
02866 NULL
02867 },
02868 &syslog_ident_str,
02869 "postgres",
02870 NULL, assign_syslog_ident, NULL
02871 },
02872
02873 {
02874 {"event_source", PGC_POSTMASTER, LOGGING_WHERE,
02875 gettext_noop("Sets the application name used to identify "
02876 "PostgreSQL messages in the event log."),
02877 NULL
02878 },
02879 &event_source,
02880 "PostgreSQL",
02881 NULL, NULL, NULL
02882 },
02883
02884 {
02885 {"TimeZone", PGC_USERSET, CLIENT_CONN_LOCALE,
02886 gettext_noop("Sets the time zone for displaying and interpreting time stamps."),
02887 NULL,
02888 GUC_REPORT
02889 },
02890 &timezone_string,
02891 "GMT",
02892 check_timezone, assign_timezone, show_timezone
02893 },
02894 {
02895 {"timezone_abbreviations", PGC_USERSET, CLIENT_CONN_LOCALE,
02896 gettext_noop("Selects a file of time zone abbreviations."),
02897 NULL
02898 },
02899 &timezone_abbreviations_string,
02900 NULL,
02901 check_timezone_abbreviations, assign_timezone_abbreviations, NULL
02902 },
02903
02904 {
02905 {"transaction_isolation", PGC_USERSET, CLIENT_CONN_STATEMENT,
02906 gettext_noop("Sets the current transaction's isolation level."),
02907 NULL,
02908 GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
02909 },
02910 &XactIsoLevel_string,
02911 "default",
02912 check_XactIsoLevel, assign_XactIsoLevel, show_XactIsoLevel
02913 },
02914
02915 {
02916 {"unix_socket_group", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
02917 gettext_noop("Sets the owning group of the Unix-domain socket."),
02918 gettext_noop("The owning user of the socket is always the user "
02919 "that starts the server.")
02920 },
02921 &Unix_socket_group,
02922 "",
02923 NULL, NULL, NULL
02924 },
02925
02926 {
02927 {"unix_socket_directories", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
02928 gettext_noop("Sets the directories where Unix-domain sockets will be created."),
02929 NULL,
02930 GUC_SUPERUSER_ONLY
02931 },
02932 &Unix_socket_directories,
02933 #ifdef HAVE_UNIX_SOCKETS
02934 DEFAULT_PGSOCKET_DIR,
02935 #else
02936 "",
02937 #endif
02938 NULL, NULL, NULL
02939 },
02940
02941 {
02942 {"listen_addresses", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
02943 gettext_noop("Sets the host name or IP address(es) to listen to."),
02944 NULL,
02945 GUC_LIST_INPUT
02946 },
02947 &ListenAddresses,
02948 "localhost",
02949 NULL, NULL, NULL
02950 },
02951
02952 {
02953 {"data_directory", PGC_POSTMASTER, FILE_LOCATIONS,
02954 gettext_noop("Sets the server's data directory."),
02955 NULL,
02956 GUC_SUPERUSER_ONLY
02957 },
02958 &data_directory,
02959 NULL,
02960 NULL, NULL, NULL
02961 },
02962
02963 {
02964 {"config_file", PGC_POSTMASTER, FILE_LOCATIONS,
02965 gettext_noop("Sets the server's main configuration file."),
02966 NULL,
02967 GUC_DISALLOW_IN_FILE | GUC_SUPERUSER_ONLY
02968 },
02969 &ConfigFileName,
02970 NULL,
02971 NULL, NULL, NULL
02972 },
02973
02974 {
02975 {"hba_file", PGC_POSTMASTER, FILE_LOCATIONS,
02976 gettext_noop("Sets the server's \"hba\" configuration file."),
02977 NULL,
02978 GUC_SUPERUSER_ONLY
02979 },
02980 &HbaFileName,
02981 NULL,
02982 NULL, NULL, NULL
02983 },
02984
02985 {
02986 {"ident_file", PGC_POSTMASTER, FILE_LOCATIONS,
02987 gettext_noop("Sets the server's \"ident\" configuration file."),
02988 NULL,
02989 GUC_SUPERUSER_ONLY
02990 },
02991 &IdentFileName,
02992 NULL,
02993 NULL, NULL, NULL
02994 },
02995
02996 {
02997 {"external_pid_file", PGC_POSTMASTER, FILE_LOCATIONS,
02998 gettext_noop("Writes the postmaster PID to the specified file."),
02999 NULL,
03000 GUC_SUPERUSER_ONLY
03001 },
03002 &external_pid_file,
03003 NULL,
03004 check_canonical_path, NULL, NULL
03005 },
03006
03007 {
03008 {"ssl_cert_file", PGC_POSTMASTER, CONN_AUTH_SECURITY,
03009 gettext_noop("Location of the SSL server certificate file."),
03010 NULL
03011 },
03012 &ssl_cert_file,
03013 "server.crt",
03014 NULL, NULL, NULL
03015 },
03016
03017 {
03018 {"ssl_key_file", PGC_POSTMASTER, CONN_AUTH_SECURITY,
03019 gettext_noop("Location of the SSL server private key file."),
03020 NULL
03021 },
03022 &ssl_key_file,
03023 "server.key",
03024 NULL, NULL, NULL
03025 },
03026
03027 {
03028 {"ssl_ca_file", PGC_POSTMASTER, CONN_AUTH_SECURITY,
03029 gettext_noop("Location of the SSL certificate authority file."),
03030 NULL
03031 },
03032 &ssl_ca_file,
03033 "",
03034 NULL, NULL, NULL
03035 },
03036
03037 {
03038 {"ssl_crl_file", PGC_POSTMASTER, CONN_AUTH_SECURITY,
03039 gettext_noop("Location of the SSL certificate revocation list file."),
03040 NULL
03041 },
03042 &ssl_crl_file,
03043 "",
03044 NULL, NULL, NULL
03045 },
03046
03047 {
03048 {"stats_temp_directory", PGC_SIGHUP, STATS_COLLECTOR,
03049 gettext_noop("Writes temporary statistics files to the specified directory."),
03050 NULL,
03051 GUC_SUPERUSER_ONLY
03052 },
03053 &pgstat_temp_directory,
03054 "pg_stat_tmp",
03055 check_canonical_path, assign_pgstat_temp_directory, NULL
03056 },
03057
03058 {
03059 {"synchronous_standby_names", PGC_SIGHUP, REPLICATION_MASTER,
03060 gettext_noop("List of names of potential synchronous standbys."),
03061 NULL,
03062 GUC_LIST_INPUT
03063 },
03064 &SyncRepStandbyNames,
03065 "",
03066 check_synchronous_standby_names, NULL, NULL
03067 },
03068
03069 {
03070 {"default_text_search_config", PGC_USERSET, CLIENT_CONN_LOCALE,
03071 gettext_noop("Sets default text search configuration."),
03072 NULL
03073 },
03074 &TSCurrentConfig,
03075 "pg_catalog.simple",
03076 check_TSCurrentConfig, assign_TSCurrentConfig, NULL
03077 },
03078
03079 {
03080 {"ssl_ciphers", PGC_POSTMASTER, CONN_AUTH_SECURITY,
03081 gettext_noop("Sets the list of allowed SSL ciphers."),
03082 NULL,
03083 GUC_SUPERUSER_ONLY
03084 },
03085 &SSLCipherSuites,
03086 #ifdef USE_SSL
03087 "DEFAULT:!LOW:!EXP:!MD5:@STRENGTH",
03088 #else
03089 "none",
03090 #endif
03091 NULL, NULL, NULL
03092 },
03093
03094 {
03095 {"application_name", PGC_USERSET, LOGGING_WHAT,
03096 gettext_noop("Sets the application name to be reported in statistics and logs."),
03097 NULL,
03098 GUC_IS_NAME | GUC_REPORT | GUC_NOT_IN_SAMPLE
03099 },
03100 &application_name,
03101 "",
03102 check_application_name, assign_application_name, NULL
03103 },
03104
03105
03106 {
03107 {NULL, 0, 0, NULL, NULL}, NULL, NULL, NULL, NULL, NULL
03108 }
03109 };
03110
03111
03112 static struct config_enum ConfigureNamesEnum[] =
03113 {
03114 {
03115 {"backslash_quote", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
03116 gettext_noop("Sets whether \"\\'\" is allowed in string literals."),
03117 NULL
03118 },
03119 &backslash_quote,
03120 BACKSLASH_QUOTE_SAFE_ENCODING, backslash_quote_options,
03121 NULL, NULL, NULL
03122 },
03123
03124 {
03125 {"bytea_output", PGC_USERSET, CLIENT_CONN_STATEMENT,
03126 gettext_noop("Sets the output format for bytea."),
03127 NULL
03128 },
03129 &bytea_output,
03130 BYTEA_OUTPUT_HEX, bytea_output_options,
03131 NULL, NULL, NULL
03132 },
03133
03134 {
03135 {"client_min_messages", PGC_USERSET, LOGGING_WHEN,
03136 gettext_noop("Sets the message levels that are sent to the client."),
03137 gettext_noop("Each level includes all the levels that follow it. The later"
03138 " the level, the fewer messages are sent.")
03139 },
03140 &client_min_messages,
03141 NOTICE, client_message_level_options,
03142 NULL, NULL, NULL
03143 },
03144
03145 {
03146 {"constraint_exclusion", PGC_USERSET, QUERY_TUNING_OTHER,
03147 gettext_noop("Enables the planner to use constraints to optimize queries."),
03148 gettext_noop("Table scans will be skipped if their constraints"
03149 " guarantee that no rows match the query.")
03150 },
03151 &constraint_exclusion,
03152 CONSTRAINT_EXCLUSION_PARTITION, constraint_exclusion_options,
03153 NULL, NULL, NULL
03154 },
03155
03156 {
03157 {"default_transaction_isolation", PGC_USERSET, CLIENT_CONN_STATEMENT,
03158 gettext_noop("Sets the transaction isolation level of each new transaction."),
03159 NULL
03160 },
03161 &DefaultXactIsoLevel,
03162 XACT_READ_COMMITTED, isolation_level_options,
03163 NULL, NULL, NULL
03164 },
03165
03166 {
03167 {"IntervalStyle", PGC_USERSET, CLIENT_CONN_LOCALE,
03168 gettext_noop("Sets the display format for interval values."),
03169 NULL,
03170 GUC_REPORT
03171 },
03172 &IntervalStyle,
03173 INTSTYLE_POSTGRES, intervalstyle_options,
03174 NULL, NULL, NULL
03175 },
03176
03177 {
03178 {"log_error_verbosity", PGC_SUSET, LOGGING_WHAT,
03179 gettext_noop("Sets the verbosity of logged messages."),
03180 NULL
03181 },
03182 &Log_error_verbosity,
03183 PGERROR_DEFAULT, log_error_verbosity_options,
03184 NULL, NULL, NULL
03185 },
03186
03187 {
03188 {"log_min_messages", PGC_SUSET, LOGGING_WHEN,
03189 gettext_noop("Sets the message levels that are logged."),
03190 gettext_noop("Each level includes all the levels that follow it. The later"
03191 " the level, the fewer messages are sent.")
03192 },
03193 &log_min_messages,
03194 WARNING, server_message_level_options,
03195 NULL, NULL, NULL
03196 },
03197
03198 {
03199 {"log_min_error_statement", PGC_SUSET, LOGGING_WHEN,
03200 gettext_noop("Causes all statements generating error at or above this level to be logged."),
03201 gettext_noop("Each level includes all the levels that follow it. The later"
03202 " the level, the fewer messages are sent.")
03203 },
03204 &log_min_error_statement,
03205 ERROR, server_message_level_options,
03206 NULL, NULL, NULL
03207 },
03208
03209 {
03210 {"log_statement", PGC_SUSET, LOGGING_WHAT,
03211 gettext_noop("Sets the type of statements logged."),
03212 NULL
03213 },
03214 &log_statement,
03215 LOGSTMT_NONE, log_statement_options,
03216 NULL, NULL, NULL
03217 },
03218
03219 {
03220 {"syslog_facility", PGC_SIGHUP, LOGGING_WHERE,
03221 gettext_noop("Sets the syslog \"facility\" to be used when syslog enabled."),
03222 NULL
03223 },
03224 &syslog_facility,
03225 #ifdef HAVE_SYSLOG
03226 LOG_LOCAL0,
03227 #else
03228 0,
03229 #endif
03230 syslog_facility_options,
03231 NULL, assign_syslog_facility, NULL
03232 },
03233
03234 {
03235 {"session_replication_role", PGC_SUSET, CLIENT_CONN_STATEMENT,
03236 gettext_noop("Sets the session's behavior for triggers and rewrite rules."),
03237 NULL
03238 },
03239 &SessionReplicationRole,
03240 SESSION_REPLICATION_ROLE_ORIGIN, session_replication_role_options,
03241 NULL, assign_session_replication_role, NULL
03242 },
03243
03244 {
03245 {"synchronous_commit", PGC_USERSET, WAL_SETTINGS,
03246 gettext_noop("Sets the current transaction's synchronization level."),
03247 NULL
03248 },
03249 &synchronous_commit,
03250 SYNCHRONOUS_COMMIT_ON, synchronous_commit_options,
03251 NULL, assign_synchronous_commit, NULL
03252 },
03253
03254 {
03255 {"trace_recovery_messages", PGC_SIGHUP, DEVELOPER_OPTIONS,
03256 gettext_noop("Enables logging of recovery-related debugging information."),
03257 gettext_noop("Each level includes all the levels that follow it. The later"
03258 " the level, the fewer messages are sent.")
03259 },
03260 &trace_recovery_messages,
03261
03262
03263
03264
03265
03266 LOG, client_message_level_options,
03267 NULL, NULL, NULL
03268 },
03269
03270 {
03271 {"track_functions", PGC_SUSET, STATS_COLLECTOR,
03272 gettext_noop("Collects function-level statistics on database activity."),
03273 NULL
03274 },
03275 &pgstat_track_functions,
03276 TRACK_FUNC_OFF, track_function_options,
03277 NULL, NULL, NULL
03278 },
03279
03280 {
03281 {"wal_level", PGC_POSTMASTER, WAL_SETTINGS,
03282 gettext_noop("Set the level of information written to the WAL."),
03283 NULL
03284 },
03285 &wal_level,
03286 WAL_LEVEL_MINIMAL, wal_level_options,
03287 NULL, NULL, NULL
03288 },
03289
03290 {
03291 {"wal_sync_method", PGC_SIGHUP, WAL_SETTINGS,
03292 gettext_noop("Selects the method used for forcing WAL updates to disk."),
03293 NULL
03294 },
03295 &sync_method,
03296 DEFAULT_SYNC_METHOD, sync_method_options,
03297 NULL, assign_xlog_sync_method, NULL
03298 },
03299
03300 {
03301 {"xmlbinary", PGC_USERSET, CLIENT_CONN_STATEMENT,
03302 gettext_noop("Sets how binary values are to be encoded in XML."),
03303 NULL
03304 },
03305 &xmlbinary,
03306 XMLBINARY_BASE64, xmlbinary_options,
03307 NULL, NULL, NULL
03308 },
03309
03310 {
03311 {"xmloption", PGC_USERSET, CLIENT_CONN_STATEMENT,
03312 gettext_noop("Sets whether XML data in implicit parsing and serialization "
03313 "operations is to be considered as documents or content fragments."),
03314 NULL
03315 },
03316 &xmloption,
03317 XMLOPTION_CONTENT, xmloption_options,
03318 NULL, NULL, NULL
03319 },
03320
03321
03322
03323 {
03324 {NULL, 0, 0, NULL, NULL}, NULL, 0, NULL, NULL, NULL, NULL
03325 }
03326 };
03327
03328
03329
03330
03331
03332
03333
03334
03335
03336
03337 static const char *const map_old_guc_names[] = {
03338 "sort_mem", "work_mem",
03339 "vacuum_mem", "maintenance_work_mem",
03340 NULL
03341 };
03342
03343
03344
03345
03346
03347 static struct config_generic **guc_variables;
03348
03349
03350 static int num_guc_variables;
03351
03352
03353 static int size_guc_variables;
03354
03355
03356 static bool guc_dirty;
03357
03358 static bool reporting_enabled;
03359
03360 static int GUCNestLevel = 0;
03361
03362
03363 static int guc_var_compare(const void *a, const void *b);
03364 static int guc_name_compare(const char *namea, const char *nameb);
03365 static void InitializeGUCOptionsFromEnvironment(void);
03366 static void InitializeOneGUCOption(struct config_generic * gconf);
03367 static void push_old_value(struct config_generic * gconf, GucAction action);
03368 static void ReportGUCOption(struct config_generic * record);
03369 static void reapply_stacked_values(struct config_generic * variable,
03370 struct config_string * pHolder,
03371 GucStack *stack,
03372 const char *curvalue,
03373 GucContext curscontext, GucSource cursource);
03374 static void ShowGUCConfigOption(const char *name, DestReceiver *dest);
03375 static void ShowAllGUCConfig(DestReceiver *dest);
03376 static char *_ShowOption(struct config_generic * record, bool use_units);
03377 static bool validate_option_array_item(const char *name, const char *value,
03378 bool skipIfNoPermissions);
03379
03380
03381
03382
03383
03384 static void *
03385 guc_malloc(int elevel, size_t size)
03386 {
03387 void *data;
03388
03389
03390 if (size == 0)
03391 size = 1;
03392 data = malloc(size);
03393 if (data == NULL)
03394 ereport(elevel,
03395 (errcode(ERRCODE_OUT_OF_MEMORY),
03396 errmsg("out of memory")));
03397 return data;
03398 }
03399
03400 static void *
03401 guc_realloc(int elevel, void *old, size_t size)
03402 {
03403 void *data;
03404
03405
03406 if (old == NULL && size == 0)
03407 size = 1;
03408 data = realloc(old, size);
03409 if (data == NULL)
03410 ereport(elevel,
03411 (errcode(ERRCODE_OUT_OF_MEMORY),
03412 errmsg("out of memory")));
03413 return data;
03414 }
03415
03416 static char *
03417 guc_strdup(int elevel, const char *src)
03418 {
03419 char *data;
03420
03421 data = strdup(src);
03422 if (data == NULL)
03423 ereport(elevel,
03424 (errcode(ERRCODE_OUT_OF_MEMORY),
03425 errmsg("out of memory")));
03426 return data;
03427 }
03428
03429
03430
03431
03432
03433 static bool
03434 string_field_used(struct config_string * conf, char *strval)
03435 {
03436 GucStack *stack;
03437
03438 if (strval == *(conf->variable) ||
03439 strval == conf->reset_val ||
03440 strval == conf->boot_val)
03441 return true;
03442 for (stack = conf->gen.stack; stack; stack = stack->prev)
03443 {
03444 if (strval == stack->prior.val.stringval ||
03445 strval == stack->masked.val.stringval)
03446 return true;
03447 }
03448 return false;
03449 }
03450
03451
03452
03453
03454
03455
03456 static void
03457 set_string_field(struct config_string * conf, char **field, char *newval)
03458 {
03459 char *oldval = *field;
03460
03461
03462 *field = newval;
03463
03464
03465 if (oldval && !string_field_used(conf, oldval))
03466 free(oldval);
03467 }
03468
03469
03470
03471
03472 static bool
03473 extra_field_used(struct config_generic * gconf, void *extra)
03474 {
03475 GucStack *stack;
03476
03477 if (extra == gconf->extra)
03478 return true;
03479 switch (gconf->vartype)
03480 {
03481 case PGC_BOOL:
03482 if (extra == ((struct config_bool *) gconf)->reset_extra)
03483 return true;
03484 break;
03485 case PGC_INT:
03486 if (extra == ((struct config_int *) gconf)->reset_extra)
03487 return true;
03488 break;
03489 case PGC_REAL:
03490 if (extra == ((struct config_real *) gconf)->reset_extra)
03491 return true;
03492 break;
03493 case PGC_STRING:
03494 if (extra == ((struct config_string *) gconf)->reset_extra)
03495 return true;
03496 break;
03497 case PGC_ENUM:
03498 if (extra == ((struct config_enum *) gconf)->reset_extra)
03499 return true;
03500 break;
03501 }
03502 for (stack = gconf->stack; stack; stack = stack->prev)
03503 {
03504 if (extra == stack->prior.extra ||
03505 extra == stack->masked.extra)
03506 return true;
03507 }
03508
03509 return false;
03510 }
03511
03512
03513
03514
03515
03516
03517 static void
03518 set_extra_field(struct config_generic * gconf, void **field, void *newval)
03519 {
03520 void *oldval = *field;
03521
03522
03523 *field = newval;
03524
03525
03526 if (oldval && !extra_field_used(gconf, oldval))
03527 free(oldval);
03528 }
03529
03530
03531
03532
03533
03534
03535
03536
03537 static void
03538 set_stack_value(struct config_generic * gconf, config_var_value *val)
03539 {
03540 switch (gconf->vartype)
03541 {
03542 case PGC_BOOL:
03543 val->val.boolval =
03544 *((struct config_bool *) gconf)->variable;
03545 break;
03546 case PGC_INT:
03547 val->val.intval =
03548 *((struct config_int *) gconf)->variable;
03549 break;
03550 case PGC_REAL:
03551 val->val.realval =
03552 *((struct config_real *) gconf)->variable;
03553 break;
03554 case PGC_STRING:
03555 set_string_field((struct config_string *) gconf,
03556 &(val->val.stringval),
03557 *((struct config_string *) gconf)->variable);
03558 break;
03559 case PGC_ENUM:
03560 val->val.enumval =
03561 *((struct config_enum *) gconf)->variable;
03562 break;
03563 }
03564 set_extra_field(gconf, &(val->extra), gconf->extra);
03565 }
03566
03567
03568
03569
03570
03571 static void
03572 discard_stack_value(struct config_generic * gconf, config_var_value *val)
03573 {
03574 switch (gconf->vartype)
03575 {
03576 case PGC_BOOL:
03577 case PGC_INT:
03578 case PGC_REAL:
03579 case PGC_ENUM:
03580
03581 break;
03582 case PGC_STRING:
03583 set_string_field((struct config_string *) gconf,
03584 &(val->val.stringval),
03585 NULL);
03586 break;
03587 }
03588 set_extra_field(gconf, &(val->extra), NULL);
03589 }
03590
03591
03592
03593
03594
03595 struct config_generic **
03596 get_guc_variables(void)
03597 {
03598 return guc_variables;
03599 }
03600
03601
03602
03603
03604
03605
03606
03607 void
03608 build_guc_variables(void)
03609 {
03610 int size_vars;
03611 int num_vars = 0;
03612 struct config_generic **guc_vars;
03613 int i;
03614
03615 for (i = 0; ConfigureNamesBool[i].gen.name; i++)
03616 {
03617 struct config_bool *conf = &ConfigureNamesBool[i];
03618
03619
03620 conf->gen.vartype = PGC_BOOL;
03621 num_vars++;
03622 }
03623
03624 for (i = 0; ConfigureNamesInt[i].gen.name; i++)
03625 {
03626 struct config_int *conf = &ConfigureNamesInt[i];
03627
03628 conf->gen.vartype = PGC_INT;
03629 num_vars++;
03630 }
03631
03632 for (i = 0; ConfigureNamesReal[i].gen.name; i++)
03633 {
03634 struct config_real *conf = &ConfigureNamesReal[i];
03635
03636 conf->gen.vartype = PGC_REAL;
03637 num_vars++;
03638 }
03639
03640 for (i = 0; ConfigureNamesString[i].gen.name; i++)
03641 {
03642 struct config_string *conf = &ConfigureNamesString[i];
03643
03644 conf->gen.vartype = PGC_STRING;
03645 num_vars++;
03646 }
03647
03648 for (i = 0; ConfigureNamesEnum[i].gen.name; i++)
03649 {
03650 struct config_enum *conf = &ConfigureNamesEnum[i];
03651
03652 conf->gen.vartype = PGC_ENUM;
03653 num_vars++;
03654 }
03655
03656
03657
03658
03659 size_vars = num_vars + num_vars / 4;
03660
03661 guc_vars = (struct config_generic **)
03662 guc_malloc(FATAL, size_vars * sizeof(struct config_generic *));
03663
03664 num_vars = 0;
03665
03666 for (i = 0; ConfigureNamesBool[i].gen.name; i++)
03667 guc_vars[num_vars++] = &ConfigureNamesBool[i].gen;
03668
03669 for (i = 0; ConfigureNamesInt[i].gen.name; i++)
03670 guc_vars[num_vars++] = &ConfigureNamesInt[i].gen;
03671
03672 for (i = 0; ConfigureNamesReal[i].gen.name; i++)
03673 guc_vars[num_vars++] = &ConfigureNamesReal[i].gen;
03674
03675 for (i = 0; ConfigureNamesString[i].gen.name; i++)
03676 guc_vars[num_vars++] = &ConfigureNamesString[i].gen;
03677
03678 for (i = 0; ConfigureNamesEnum[i].gen.name; i++)
03679 guc_vars[num_vars++] = &ConfigureNamesEnum[i].gen;
03680
03681 if (guc_variables)
03682 free(guc_variables);
03683 guc_variables = guc_vars;
03684 num_guc_variables = num_vars;
03685 size_guc_variables = size_vars;
03686 qsort((void *) guc_variables, num_guc_variables,
03687 sizeof(struct config_generic *), guc_var_compare);
03688 }
03689
03690
03691
03692
03693
03694 static bool
03695 add_guc_variable(struct config_generic * var, int elevel)
03696 {
03697 if (num_guc_variables + 1 >= size_guc_variables)
03698 {
03699
03700
03701
03702 int size_vars = size_guc_variables + size_guc_variables / 4;
03703 struct config_generic **guc_vars;
03704
03705 if (size_vars == 0)
03706 {
03707 size_vars = 100;
03708 guc_vars = (struct config_generic **)
03709 guc_malloc(elevel, size_vars * sizeof(struct config_generic *));
03710 }
03711 else
03712 {
03713 guc_vars = (struct config_generic **)
03714 guc_realloc(elevel, guc_variables, size_vars * sizeof(struct config_generic *));
03715 }
03716
03717 if (guc_vars == NULL)
03718 return false;
03719
03720 guc_variables = guc_vars;
03721 size_guc_variables = size_vars;
03722 }
03723 guc_variables[num_guc_variables++] = var;
03724 qsort((void *) guc_variables, num_guc_variables,
03725 sizeof(struct config_generic *), guc_var_compare);
03726 return true;
03727 }
03728
03729
03730
03731
03732 static struct config_generic *
03733 add_placeholder_variable(const char *name, int elevel)
03734 {
03735 size_t sz = sizeof(struct config_string) + sizeof(char *);
03736 struct config_string *var;
03737 struct config_generic *gen;
03738
03739 var = (struct config_string *) guc_malloc(elevel, sz);
03740 if (var == NULL)
03741 return NULL;
03742 memset(var, 0, sz);
03743 gen = &var->gen;
03744
03745 gen->name = guc_strdup(elevel, name);
03746 if (gen->name == NULL)
03747 {
03748 free(var);
03749 return NULL;
03750 }
03751
03752 gen->context = PGC_USERSET;
03753 gen->group = CUSTOM_OPTIONS;
03754 gen->short_desc = "GUC placeholder variable";
03755 gen->flags = GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE | GUC_CUSTOM_PLACEHOLDER;
03756 gen->vartype = PGC_STRING;
03757
03758
03759
03760
03761
03762
03763 var->variable = (char **) (var + 1);
03764
03765 if (!add_guc_variable((struct config_generic *) var, elevel))
03766 {
03767 free((void *) gen->name);
03768 free(var);
03769 return NULL;
03770 }
03771
03772 return gen;
03773 }
03774
03775
03776
03777
03778
03779
03780 static struct config_generic *
03781 find_option(const char *name, bool create_placeholders, int elevel)
03782 {
03783 const char **key = &name;
03784 struct config_generic **res;
03785 int i;
03786
03787 Assert(name);
03788
03789
03790
03791
03792
03793 res = (struct config_generic **) bsearch((void *) &key,
03794 (void *) guc_variables,
03795 num_guc_variables,
03796 sizeof(struct config_generic *),
03797 guc_var_compare);
03798 if (res)
03799 return *res;
03800
03801
03802
03803
03804
03805
03806 for (i = 0; map_old_guc_names[i] != NULL; i += 2)
03807 {
03808 if (guc_name_compare(name, map_old_guc_names[i]) == 0)
03809 return find_option(map_old_guc_names[i + 1], false, elevel);
03810 }
03811
03812 if (create_placeholders)
03813 {
03814
03815
03816
03817 if (strchr(name, GUC_QUALIFIER_SEPARATOR) != NULL)
03818 return add_placeholder_variable(name, elevel);
03819 }
03820
03821
03822 return NULL;
03823 }
03824
03825
03826
03827
03828
03829 static int
03830 guc_var_compare(const void *a, const void *b)
03831 {
03832 const struct config_generic *confa = *(struct config_generic * const *) a;
03833 const struct config_generic *confb = *(struct config_generic * const *) b;
03834
03835 return guc_name_compare(confa->name, confb->name);
03836 }
03837
03838
03839
03840
03841 static int
03842 guc_name_compare(const char *namea, const char *nameb)
03843 {
03844
03845
03846
03847
03848
03849 while (*namea && *nameb)
03850 {
03851 char cha = *namea++;
03852 char chb = *nameb++;
03853
03854 if (cha >= 'A' && cha <= 'Z')
03855 cha += 'a' - 'A';
03856 if (chb >= 'A' && chb <= 'Z')
03857 chb += 'a' - 'A';
03858 if (cha != chb)
03859 return cha - chb;
03860 }
03861 if (*namea)
03862 return 1;
03863 if (*nameb)
03864 return -1;
03865 return 0;
03866 }
03867
03868
03869
03870
03871
03872
03873
03874
03875 void
03876 InitializeGUCOptions(void)
03877 {
03878 int i;
03879
03880
03881
03882
03883
03884 pg_timezone_initialize();
03885
03886
03887
03888
03889 build_guc_variables();
03890
03891
03892
03893
03894
03895 for (i = 0; i < num_guc_variables; i++)
03896 {
03897 InitializeOneGUCOption(guc_variables[i]);
03898 }
03899
03900 guc_dirty = false;
03901
03902 reporting_enabled = false;
03903
03904
03905
03906
03907
03908 SetConfigOption("transaction_isolation", "default",
03909 PGC_POSTMASTER, PGC_S_OVERRIDE);
03910 SetConfigOption("transaction_read_only", "no",
03911 PGC_POSTMASTER, PGC_S_OVERRIDE);
03912 SetConfigOption("transaction_deferrable", "no",
03913 PGC_POSTMASTER, PGC_S_OVERRIDE);
03914
03915
03916
03917
03918
03919 InitializeGUCOptionsFromEnvironment();
03920 }
03921
03922
03923
03924
03925
03926
03927
03928
03929
03930
03931 static void
03932 InitializeGUCOptionsFromEnvironment(void)
03933 {
03934 char *env;
03935 long stack_rlimit;
03936
03937 env = getenv("PGPORT");
03938 if (env != NULL)
03939 SetConfigOption("port", env, PGC_POSTMASTER, PGC_S_ENV_VAR);
03940
03941 env = getenv("PGDATESTYLE");
03942 if (env != NULL)
03943 SetConfigOption("datestyle", env, PGC_POSTMASTER, PGC_S_ENV_VAR);
03944
03945 env = getenv("PGCLIENTENCODING");
03946 if (env != NULL)
03947 SetConfigOption("client_encoding", env, PGC_POSTMASTER, PGC_S_ENV_VAR);
03948
03949
03950
03951
03952
03953
03954 stack_rlimit = get_stack_depth_rlimit();
03955 if (stack_rlimit > 0)
03956 {
03957 long new_limit = (stack_rlimit - STACK_DEPTH_SLOP) / 1024L;
03958
03959 if (new_limit > 100)
03960 {
03961 char limbuf[16];
03962
03963 new_limit = Min(new_limit, 2048);
03964 sprintf(limbuf, "%ld", new_limit);
03965 SetConfigOption("max_stack_depth", limbuf,
03966 PGC_POSTMASTER, PGC_S_ENV_VAR);
03967 }
03968 }
03969 }
03970
03971
03972
03973
03974
03975
03976
03977 static void
03978 InitializeOneGUCOption(struct config_generic * gconf)
03979 {
03980 gconf->status = 0;
03981 gconf->source = PGC_S_DEFAULT;
03982 gconf->reset_source = PGC_S_DEFAULT;
03983 gconf->scontext = PGC_INTERNAL;
03984 gconf->reset_scontext = PGC_INTERNAL;
03985 gconf->stack = NULL;
03986 gconf->extra = NULL;
03987 gconf->sourcefile = NULL;
03988 gconf->sourceline = 0;
03989
03990 switch (gconf->vartype)
03991 {
03992 case PGC_BOOL:
03993 {
03994 struct config_bool *conf = (struct config_bool *) gconf;
03995 bool newval = conf->boot_val;
03996 void *extra = NULL;
03997
03998 if (!call_bool_check_hook(conf, &newval, &extra,
03999 PGC_S_DEFAULT, LOG))
04000 elog(FATAL, "failed to initialize %s to %d",
04001 conf->gen.name, (int) newval);
04002 if (conf->assign_hook)
04003 (*conf->assign_hook) (newval, extra);
04004 *conf->variable = conf->reset_val = newval;
04005 conf->gen.extra = conf->reset_extra = extra;
04006 break;
04007 }
04008 case PGC_INT:
04009 {
04010 struct config_int *conf = (struct config_int *) gconf;
04011 int newval = conf->boot_val;
04012 void *extra = NULL;
04013
04014 Assert(newval >= conf->min);
04015 Assert(newval <= conf->max);
04016 if (!call_int_check_hook(conf, &newval, &extra,
04017 PGC_S_DEFAULT, LOG))
04018 elog(FATAL, "failed to initialize %s to %d",
04019 conf->gen.name, newval);
04020 if (conf->assign_hook)
04021 (*conf->assign_hook) (newval, extra);
04022 *conf->variable = conf->reset_val = newval;
04023 conf->gen.extra = conf->reset_extra = extra;
04024 break;
04025 }
04026 case PGC_REAL:
04027 {
04028 struct config_real *conf = (struct config_real *) gconf;
04029 double newval = conf->boot_val;
04030 void *extra = NULL;
04031
04032 Assert(newval >= conf->min);
04033 Assert(newval <= conf->max);
04034 if (!call_real_check_hook(conf, &newval, &extra,
04035 PGC_S_DEFAULT, LOG))
04036 elog(FATAL, "failed to initialize %s to %g",
04037 conf->gen.name, newval);
04038 if (conf->assign_hook)
04039 (*conf->assign_hook) (newval, extra);
04040 *conf->variable = conf->reset_val = newval;
04041 conf->gen.extra = conf->reset_extra = extra;
04042 break;
04043 }
04044 case PGC_STRING:
04045 {
04046 struct config_string *conf = (struct config_string *) gconf;
04047 char *newval;
04048 void *extra = NULL;
04049
04050
04051 if (conf->boot_val != NULL)
04052 newval = guc_strdup(FATAL, conf->boot_val);
04053 else
04054 newval = NULL;
04055
04056 if (!call_string_check_hook(conf, &newval, &extra,
04057 PGC_S_DEFAULT, LOG))
04058 elog(FATAL, "failed to initialize %s to \"%s\"",
04059 conf->gen.name, newval ? newval : "");
04060 if (conf->assign_hook)
04061 (*conf->assign_hook) (newval, extra);
04062 *conf->variable = conf->reset_val = newval;
04063 conf->gen.extra = conf->reset_extra = extra;
04064 break;
04065 }
04066 case PGC_ENUM:
04067 {
04068 struct config_enum *conf = (struct config_enum *) gconf;
04069 int newval = conf->boot_val;
04070 void *extra = NULL;
04071
04072 if (!call_enum_check_hook(conf, &newval, &extra,
04073 PGC_S_DEFAULT, LOG))
04074 elog(FATAL, "failed to initialize %s to %d",
04075 conf->gen.name, newval);
04076 if (conf->assign_hook)
04077 (*conf->assign_hook) (newval, extra);
04078 *conf->variable = conf->reset_val = newval;
04079 conf->gen.extra = conf->reset_extra = extra;
04080 break;
04081 }
04082 }
04083 }
04084
04085
04086
04087
04088
04089
04090
04091
04092
04093
04094
04095
04096
04097 bool
04098 SelectConfigFiles(const char *userDoption, const char *progname)
04099 {
04100 char *configdir;
04101 char *fname;
04102 struct stat stat_buf;
04103
04104
04105 if (userDoption)
04106 configdir = make_absolute_path(userDoption);
04107 else
04108 configdir = make_absolute_path(getenv("PGDATA"));
04109
04110
04111
04112
04113
04114
04115
04116 if (ConfigFileName)
04117 fname = make_absolute_path(ConfigFileName);
04118 else if (configdir)
04119 {
04120 fname = guc_malloc(FATAL,
04121 strlen(configdir) + strlen(CONFIG_FILENAME) + 2);
04122 sprintf(fname, "%s/%s", configdir, CONFIG_FILENAME);
04123 }
04124 else
04125 {
04126 write_stderr("%s does not know where to find the server configuration file.\n"
04127 "You must specify the --config-file or -D invocation "
04128 "option or set the PGDATA environment variable.\n",
04129 progname);
04130 return false;
04131 }
04132
04133
04134
04135
04136
04137 SetConfigOption("config_file", fname, PGC_POSTMASTER, PGC_S_OVERRIDE);
04138 free(fname);
04139
04140
04141
04142
04143 if (stat(ConfigFileName, &stat_buf) != 0)
04144 {
04145 write_stderr("%s cannot access the server configuration file \"%s\": %s\n",
04146 progname, ConfigFileName, strerror(errno));
04147 free(configdir);
04148 return false;
04149 }
04150
04151 ProcessConfigFile(PGC_POSTMASTER);
04152
04153
04154
04155
04156
04157
04158
04159
04160 if (data_directory)
04161 SetDataDir(data_directory);
04162 else if (configdir)
04163 SetDataDir(configdir);
04164 else
04165 {
04166 write_stderr("%s does not know where to find the database system data.\n"
04167 "This can be specified as \"data_directory\" in \"%s\", "
04168 "or by the -D invocation option, or by the "
04169 "PGDATA environment variable.\n",
04170 progname, ConfigFileName);
04171 return false;
04172 }
04173
04174
04175
04176
04177
04178
04179
04180
04181
04182 SetConfigOption("data_directory", DataDir, PGC_POSTMASTER, PGC_S_OVERRIDE);
04183
04184
04185
04186
04187
04188
04189
04190
04191 pg_timezone_abbrev_initialize();
04192
04193
04194
04195
04196 if (HbaFileName)
04197 fname = make_absolute_path(HbaFileName);
04198 else if (configdir)
04199 {
04200 fname = guc_malloc(FATAL,
04201 strlen(configdir) + strlen(HBA_FILENAME) + 2);
04202 sprintf(fname, "%s/%s", configdir, HBA_FILENAME);
04203 }
04204 else
04205 {
04206 write_stderr("%s does not know where to find the \"hba\" configuration file.\n"
04207 "This can be specified as \"hba_file\" in \"%s\", "
04208 "or by the -D invocation option, or by the "
04209 "PGDATA environment variable.\n",
04210 progname, ConfigFileName);
04211 return false;
04212 }
04213 SetConfigOption("hba_file", fname, PGC_POSTMASTER, PGC_S_OVERRIDE);
04214 free(fname);
04215
04216
04217
04218
04219 if (IdentFileName)
04220 fname = make_absolute_path(IdentFileName);
04221 else if (configdir)
04222 {
04223 fname = guc_malloc(FATAL,
04224 strlen(configdir) + strlen(IDENT_FILENAME) + 2);
04225 sprintf(fname, "%s/%s", configdir, IDENT_FILENAME);
04226 }
04227 else
04228 {
04229 write_stderr("%s does not know where to find the \"ident\" configuration file.\n"
04230 "This can be specified as \"ident_file\" in \"%s\", "
04231 "or by the -D invocation option, or by the "
04232 "PGDATA environment variable.\n",
04233 progname, ConfigFileName);
04234 return false;
04235 }
04236 SetConfigOption("ident_file", fname, PGC_POSTMASTER, PGC_S_OVERRIDE);
04237 free(fname);
04238
04239 free(configdir);
04240
04241 return true;
04242 }
04243
04244
04245
04246
04247
04248 void
04249 ResetAllOptions(void)
04250 {
04251 int i;
04252
04253 for (i = 0; i < num_guc_variables; i++)
04254 {
04255 struct config_generic *gconf = guc_variables[i];
04256
04257
04258 if (gconf->context != PGC_SUSET &&
04259 gconf->context != PGC_USERSET)
04260 continue;
04261
04262 if (gconf->flags & GUC_NO_RESET_ALL)
04263 continue;
04264
04265 if (gconf->source <= PGC_S_OVERRIDE)
04266 continue;
04267
04268
04269 push_old_value(gconf, GUC_ACTION_SET);
04270
04271 switch (gconf->vartype)
04272 {
04273 case PGC_BOOL:
04274 {
04275 struct config_bool *conf = (struct config_bool *) gconf;
04276
04277 if (conf->assign_hook)
04278 (*conf->assign_hook) (conf->reset_val,
04279 conf->reset_extra);
04280 *conf->variable = conf->reset_val;
04281 set_extra_field(&conf->gen, &conf->gen.extra,
04282 conf->reset_extra);
04283 break;
04284 }
04285 case PGC_INT:
04286 {
04287 struct config_int *conf = (struct config_int *) gconf;
04288
04289 if (conf->assign_hook)
04290 (*conf->assign_hook) (conf->reset_val,
04291 conf->reset_extra);
04292 *conf->variable = conf->reset_val;
04293 set_extra_field(&conf->gen, &conf->gen.extra,
04294 conf->reset_extra);
04295 break;
04296 }
04297 case PGC_REAL:
04298 {
04299 struct config_real *conf = (struct config_real *) gconf;
04300
04301 if (conf->assign_hook)
04302 (*conf->assign_hook) (conf->reset_val,
04303 conf->reset_extra);
04304 *conf->variable = conf->reset_val;
04305 set_extra_field(&conf->gen, &conf->gen.extra,
04306 conf->reset_extra);
04307 break;
04308 }
04309 case PGC_STRING:
04310 {
04311 struct config_string *conf = (struct config_string *) gconf;
04312
04313 if (conf->assign_hook)
04314 (*conf->assign_hook) (conf->reset_val,
04315 conf->reset_extra);
04316 set_string_field(conf, conf->variable, conf->reset_val);
04317 set_extra_field(&conf->gen, &conf->gen.extra,
04318 conf->reset_extra);
04319 break;
04320 }
04321 case PGC_ENUM:
04322 {
04323 struct config_enum *conf = (struct config_enum *) gconf;
04324
04325 if (conf->assign_hook)
04326 (*conf->assign_hook) (conf->reset_val,
04327 conf->reset_extra);
04328 *conf->variable = conf->reset_val;
04329 set_extra_field(&conf->gen, &conf->gen.extra,
04330 conf->reset_extra);
04331 break;
04332 }
04333 }
04334
04335 gconf->source = gconf->reset_source;
04336 gconf->scontext = gconf->reset_scontext;
04337
04338 if (gconf->flags & GUC_REPORT)
04339 ReportGUCOption(gconf);
04340 }
04341 }
04342
04343
04344
04345
04346
04347
04348 static void
04349 push_old_value(struct config_generic * gconf, GucAction action)
04350 {
04351 GucStack *stack;
04352
04353
04354 if (GUCNestLevel == 0)
04355 return;
04356
04357
04358 stack = gconf->stack;
04359 if (stack && stack->nest_level >= GUCNestLevel)
04360 {
04361
04362 Assert(stack->nest_level == GUCNestLevel);
04363 switch (action)
04364 {
04365 case GUC_ACTION_SET:
04366
04367 if (stack->state == GUC_SET_LOCAL)
04368 {
04369
04370 discard_stack_value(gconf, &stack->masked);
04371 }
04372 stack->state = GUC_SET;
04373 break;
04374 case GUC_ACTION_LOCAL:
04375 if (stack->state == GUC_SET)
04376 {
04377
04378 stack->masked_scontext = gconf->scontext;
04379 set_stack_value(gconf, &stack->masked);
04380 stack->state = GUC_SET_LOCAL;
04381 }
04382
04383 break;
04384 case GUC_ACTION_SAVE:
04385
04386 Assert(stack->state == GUC_SAVE);
04387 break;
04388 }
04389 Assert(guc_dirty);
04390 return;
04391 }
04392
04393
04394
04395
04396
04397
04398 stack = (GucStack *) MemoryContextAllocZero(TopTransactionContext,
04399 sizeof(GucStack));
04400
04401 stack->prev = gconf->stack;
04402 stack->nest_level = GUCNestLevel;
04403 switch (action)
04404 {
04405 case GUC_ACTION_SET:
04406 stack->state = GUC_SET;
04407 break;
04408 case GUC_ACTION_LOCAL:
04409 stack->state = GUC_LOCAL;
04410 break;
04411 case GUC_ACTION_SAVE:
04412 stack->state = GUC_SAVE;
04413 break;
04414 }
04415 stack->source = gconf->source;
04416 stack->scontext = gconf->scontext;
04417 set_stack_value(gconf, &stack->prior);
04418
04419 gconf->stack = stack;
04420
04421
04422 guc_dirty = true;
04423 }
04424
04425
04426
04427
04428
04429 void
04430 AtStart_GUC(void)
04431 {
04432
04433
04434
04435
04436
04437 if (GUCNestLevel != 0)
04438 elog(WARNING, "GUC nest level = %d at transaction start",
04439 GUCNestLevel);
04440 GUCNestLevel = 1;
04441 }
04442
04443
04444
04445
04446
04447
04448
04449 int
04450 NewGUCNestLevel(void)
04451 {
04452 return ++GUCNestLevel;
04453 }
04454
04455
04456
04457
04458
04459
04460
04461
04462
04463 void
04464 AtEOXact_GUC(bool isCommit, int nestLevel)
04465 {
04466 bool still_dirty;
04467 int i;
04468
04469
04470
04471
04472
04473
04474 Assert(nestLevel > 0 &&
04475 (nestLevel <= GUCNestLevel ||
04476 (nestLevel == GUCNestLevel + 1 && !isCommit)));
04477
04478
04479 if (!guc_dirty)
04480 {
04481 GUCNestLevel = nestLevel - 1;
04482 return;
04483 }
04484
04485 still_dirty = false;
04486 for (i = 0; i < num_guc_variables; i++)
04487 {
04488 struct config_generic *gconf = guc_variables[i];
04489 GucStack *stack;
04490
04491
04492
04493
04494
04495
04496
04497
04498 while ((stack = gconf->stack) != NULL &&
04499 stack->nest_level >= nestLevel)
04500 {
04501 GucStack *prev = stack->prev;
04502 bool restorePrior = false;
04503 bool restoreMasked = false;
04504 bool changed;
04505
04506
04507
04508
04509
04510
04511
04512 if (!isCommit)
04513 restorePrior = true;
04514 else if (stack->state == GUC_SAVE)
04515 restorePrior = true;
04516 else if (stack->nest_level == 1)
04517 {
04518
04519 if (stack->state == GUC_SET_LOCAL)
04520 restoreMasked = true;
04521 else if (stack->state == GUC_SET)
04522 {
04523
04524 discard_stack_value(gconf, &stack->prior);
04525 }
04526 else
04527 restorePrior = true;
04528 }
04529 else if (prev == NULL ||
04530 prev->nest_level < stack->nest_level - 1)
04531 {
04532
04533 stack->nest_level--;
04534 continue;
04535 }
04536 else
04537 {
04538
04539
04540
04541
04542 switch (stack->state)
04543 {
04544 case GUC_SAVE:
04545 Assert(false);
04546
04547 case GUC_SET:
04548
04549 discard_stack_value(gconf, &stack->prior);
04550 if (prev->state == GUC_SET_LOCAL)
04551 discard_stack_value(gconf, &prev->masked);
04552 prev->state = GUC_SET;
04553 break;
04554
04555 case GUC_LOCAL:
04556 if (prev->state == GUC_SET)
04557 {
04558
04559 prev->masked_scontext = stack->scontext;
04560 prev->masked = stack->prior;
04561 prev->state = GUC_SET_LOCAL;
04562 }
04563 else
04564 {
04565
04566 discard_stack_value(gconf, &stack->prior);
04567 }
04568 break;
04569
04570 case GUC_SET_LOCAL:
04571
04572 discard_stack_value(gconf, &stack->prior);
04573
04574 prev->masked_scontext = stack->masked_scontext;
04575 if (prev->state == GUC_SET_LOCAL)
04576 discard_stack_value(gconf, &prev->masked);
04577 prev->masked = stack->masked;
04578 prev->state = GUC_SET_LOCAL;
04579 break;
04580 }
04581 }
04582
04583 changed = false;
04584
04585 if (restorePrior || restoreMasked)
04586 {
04587
04588 config_var_value newvalue;
04589 GucSource newsource;
04590 GucContext newscontext;
04591
04592 if (restoreMasked)
04593 {
04594 newvalue = stack->masked;
04595 newsource = PGC_S_SESSION;
04596 newscontext = stack->masked_scontext;
04597 }
04598 else
04599 {
04600 newvalue = stack->prior;
04601 newsource = stack->source;
04602 newscontext = stack->scontext;
04603 }
04604
04605 switch (gconf->vartype)
04606 {
04607 case PGC_BOOL:
04608 {
04609 struct config_bool *conf = (struct config_bool *) gconf;
04610 bool newval = newvalue.val.boolval;
04611 void *newextra = newvalue.extra;
04612
04613 if (*conf->variable != newval ||
04614 conf->gen.extra != newextra)
04615 {
04616 if (conf->assign_hook)
04617 (*conf->assign_hook) (newval, newextra);
04618 *conf->variable = newval;
04619 set_extra_field(&conf->gen, &conf->gen.extra,
04620 newextra);
04621 changed = true;
04622 }
04623 break;
04624 }
04625 case PGC_INT:
04626 {
04627 struct config_int *conf = (struct config_int *) gconf;
04628 int newval = newvalue.val.intval;
04629 void *newextra = newvalue.extra;
04630
04631 if (*conf->variable != newval ||
04632 conf->gen.extra != newextra)
04633 {
04634 if (conf->assign_hook)
04635 (*conf->assign_hook) (newval, newextra);
04636 *conf->variable = newval;
04637 set_extra_field(&conf->gen, &conf->gen.extra,
04638 newextra);
04639 changed = true;
04640 }
04641 break;
04642 }
04643 case PGC_REAL:
04644 {
04645 struct config_real *conf = (struct config_real *) gconf;
04646 double newval = newvalue.val.realval;
04647 void *newextra = newvalue.extra;
04648
04649 if (*conf->variable != newval ||
04650 conf->gen.extra != newextra)
04651 {
04652 if (conf->assign_hook)
04653 (*conf->assign_hook) (newval, newextra);
04654 *conf->variable = newval;
04655 set_extra_field(&conf->gen, &conf->gen.extra,
04656 newextra);
04657 changed = true;
04658 }
04659 break;
04660 }
04661 case PGC_STRING:
04662 {
04663 struct config_string *conf = (struct config_string *) gconf;
04664 char *newval = newvalue.val.stringval;
04665 void *newextra = newvalue.extra;
04666
04667 if (*conf->variable != newval ||
04668 conf->gen.extra != newextra)
04669 {
04670 if (conf->assign_hook)
04671 (*conf->assign_hook) (newval, newextra);
04672 set_string_field(conf, conf->variable, newval);
04673 set_extra_field(&conf->gen, &conf->gen.extra,
04674 newextra);
04675 changed = true;
04676 }
04677
04678
04679
04680
04681
04682
04683
04684 set_string_field(conf, &stack->prior.val.stringval, NULL);
04685 set_string_field(conf, &stack->masked.val.stringval, NULL);
04686 break;
04687 }
04688 case PGC_ENUM:
04689 {
04690 struct config_enum *conf = (struct config_enum *) gconf;
04691 int newval = newvalue.val.enumval;
04692 void *newextra = newvalue.extra;
04693
04694 if (*conf->variable != newval ||
04695 conf->gen.extra != newextra)
04696 {
04697 if (conf->assign_hook)
04698 (*conf->assign_hook) (newval, newextra);
04699 *conf->variable = newval;
04700 set_extra_field(&conf->gen, &conf->gen.extra,
04701 newextra);
04702 changed = true;
04703 }
04704 break;
04705 }
04706 }
04707
04708
04709
04710
04711 set_extra_field(gconf, &(stack->prior.extra), NULL);
04712 set_extra_field(gconf, &(stack->masked.extra), NULL);
04713
04714
04715 gconf->source = newsource;
04716 gconf->scontext = newscontext;
04717 }
04718
04719
04720 gconf->stack = prev;
04721 pfree(stack);
04722
04723
04724 if (changed && (gconf->flags & GUC_REPORT))
04725 ReportGUCOption(gconf);
04726 }
04727
04728 if (stack != NULL)
04729 still_dirty = true;
04730 }
04731
04732
04733 guc_dirty = still_dirty;
04734
04735
04736 GUCNestLevel = nestLevel - 1;
04737 }
04738
04739
04740
04741
04742
04743
04744 void
04745 BeginReportingGUCOptions(void)
04746 {
04747 int i;
04748
04749
04750
04751
04752
04753 if (whereToSendOutput != DestRemote ||
04754 PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
04755 return;
04756
04757 reporting_enabled = true;
04758
04759
04760 for (i = 0; i < num_guc_variables; i++)
04761 {
04762 struct config_generic *conf = guc_variables[i];
04763
04764 if (conf->flags & GUC_REPORT)
04765 ReportGUCOption(conf);
04766 }
04767 }
04768
04769
04770
04771
04772 static void
04773 ReportGUCOption(struct config_generic * record)
04774 {
04775 if (reporting_enabled && (record->flags & GUC_REPORT))
04776 {
04777 char *val = _ShowOption(record, false);
04778 StringInfoData msgbuf;
04779
04780 pq_beginmessage(&msgbuf, 'S');
04781 pq_sendstring(&msgbuf, record->name);
04782 pq_sendstring(&msgbuf, val);
04783 pq_endmessage(&msgbuf);
04784
04785 pfree(val);
04786 }
04787 }
04788
04789
04790
04791
04792
04793
04794
04795
04796
04797
04798
04799 bool
04800 parse_int(const char *value, int *result, int flags, const char **hintmsg)
04801 {
04802 int64 val;
04803 char *endptr;
04804
04805
04806 if (result)
04807 *result = 0;
04808 if (hintmsg)
04809 *hintmsg = NULL;
04810
04811
04812 errno = 0;
04813 val = strtol(value, &endptr, 0);
04814
04815 if (endptr == value)
04816 return false;
04817
04818 if (errno == ERANGE || val != (int64) ((int32) val))
04819 {
04820 if (hintmsg)
04821 *hintmsg = gettext_noop("Value exceeds integer range.");
04822 return false;
04823 }
04824
04825
04826 while (isspace((unsigned char) *endptr))
04827 endptr++;
04828
04829
04830 if (*endptr != '\0')
04831 {
04832
04833
04834
04835
04836 if (flags & GUC_UNIT_MEMORY)
04837 {
04838
04839 if (hintmsg)
04840 *hintmsg = gettext_noop("Valid units for this parameter are \"kB\", \"MB\", and \"GB\".");
04841
04842 #if BLCKSZ < 1024 || BLCKSZ > (1024*1024)
04843 #error BLCKSZ must be between 1KB and 1MB
04844 #endif
04845 #if XLOG_BLCKSZ < 1024 || XLOG_BLCKSZ > (1024*1024)
04846 #error XLOG_BLCKSZ must be between 1KB and 1MB
04847 #endif
04848
04849 if (strncmp(endptr, "kB", 2) == 0)
04850 {
04851 endptr += 2;
04852 switch (flags & GUC_UNIT_MEMORY)
04853 {
04854 case GUC_UNIT_BLOCKS:
04855 val /= (BLCKSZ / 1024);
04856 break;
04857 case GUC_UNIT_XBLOCKS:
04858 val /= (XLOG_BLCKSZ / 1024);
04859 break;
04860 }
04861 }
04862 else if (strncmp(endptr, "MB", 2) == 0)
04863 {
04864 endptr += 2;
04865 switch (flags & GUC_UNIT_MEMORY)
04866 {
04867 case GUC_UNIT_KB:
04868 val *= KB_PER_MB;
04869 break;
04870 case GUC_UNIT_BLOCKS:
04871 val *= KB_PER_MB / (BLCKSZ / 1024);
04872 break;
04873 case GUC_UNIT_XBLOCKS:
04874 val *= KB_PER_MB / (XLOG_BLCKSZ / 1024);
04875 break;
04876 }
04877 }
04878 else if (strncmp(endptr, "GB", 2) == 0)
04879 {
04880 endptr += 2;
04881 switch (flags & GUC_UNIT_MEMORY)
04882 {
04883 case GUC_UNIT_KB:
04884 val *= KB_PER_GB;
04885 break;
04886 case GUC_UNIT_BLOCKS:
04887 val *= KB_PER_GB / (BLCKSZ / 1024);
04888 break;
04889 case GUC_UNIT_XBLOCKS:
04890 val *= KB_PER_GB / (XLOG_BLCKSZ / 1024);
04891 break;
04892 }
04893 }
04894 }
04895 else if (flags & GUC_UNIT_TIME)
04896 {
04897
04898 if (hintmsg)
04899 *hintmsg = gettext_noop("Valid units for this parameter are \"ms\", \"s\", \"min\", \"h\", and \"d\".");
04900
04901 if (strncmp(endptr, "ms", 2) == 0)
04902 {
04903 endptr += 2;
04904 switch (flags & GUC_UNIT_TIME)
04905 {
04906 case GUC_UNIT_S:
04907 val /= MS_PER_S;
04908 break;
04909 case GUC_UNIT_MIN:
04910 val /= MS_PER_MIN;
04911 break;
04912 }
04913 }
04914 else if (strncmp(endptr, "s", 1) == 0)
04915 {
04916 endptr += 1;
04917 switch (flags & GUC_UNIT_TIME)
04918 {
04919 case GUC_UNIT_MS:
04920 val *= MS_PER_S;
04921 break;
04922 case GUC_UNIT_MIN:
04923 val /= S_PER_MIN;
04924 break;
04925 }
04926 }
04927 else if (strncmp(endptr, "min", 3) == 0)
04928 {
04929 endptr += 3;
04930 switch (flags & GUC_UNIT_TIME)
04931 {
04932 case GUC_UNIT_MS:
04933 val *= MS_PER_MIN;
04934 break;
04935 case GUC_UNIT_S:
04936 val *= S_PER_MIN;
04937 break;
04938 }
04939 }
04940 else if (strncmp(endptr, "h", 1) == 0)
04941 {
04942 endptr += 1;
04943 switch (flags & GUC_UNIT_TIME)
04944 {
04945 case GUC_UNIT_MS:
04946 val *= MS_PER_H;
04947 break;
04948 case GUC_UNIT_S:
04949 val *= S_PER_H;
04950 break;
04951 case GUC_UNIT_MIN:
04952 val *= MIN_PER_H;
04953 break;
04954 }
04955 }
04956 else if (strncmp(endptr, "d", 1) == 0)
04957 {
04958 endptr += 1;
04959 switch (flags & GUC_UNIT_TIME)
04960 {
04961 case GUC_UNIT_MS:
04962 val *= MS_PER_D;
04963 break;
04964 case GUC_UNIT_S:
04965 val *= S_PER_D;
04966 break;
04967 case GUC_UNIT_MIN:
04968 val *= MIN_PER_D;
04969 break;
04970 }
04971 }
04972 }
04973
04974
04975 while (isspace((unsigned char) *endptr))
04976 endptr++;
04977
04978 if (*endptr != '\0')
04979 return false;
04980
04981
04982 if (val != (int64) ((int32) val))
04983 {
04984 if (hintmsg)
04985 *hintmsg = gettext_noop("Value exceeds integer range.");
04986 return false;
04987 }
04988 }
04989
04990 if (result)
04991 *result = (int) val;
04992 return true;
04993 }
04994
04995
04996
04997
04998
04999
05000
05001
05002 bool
05003 parse_real(const char *value, double *result)
05004 {
05005 double val;
05006 char *endptr;
05007
05008 if (result)
05009 *result = 0;
05010
05011 errno = 0;
05012 val = strtod(value, &endptr);
05013 if (endptr == value || errno == ERANGE)
05014 return false;
05015
05016
05017 while (isspace((unsigned char) *endptr))
05018 endptr++;
05019 if (*endptr != '\0')
05020 return false;
05021
05022 if (result)
05023 *result = val;
05024 return true;
05025 }
05026
05027
05028
05029
05030
05031
05032
05033
05034
05035
05036 const char *
05037 config_enum_lookup_by_value(struct config_enum * record, int val)
05038 {
05039 const struct config_enum_entry *entry;
05040
05041 for (entry = record->options; entry && entry->name; entry++)
05042 {
05043 if (entry->val == val)
05044 return entry->name;
05045 }
05046
05047 elog(ERROR, "could not find enum option %d for %s",
05048 val, record->gen.name);
05049 return NULL;
05050 }
05051
05052
05053
05054
05055
05056
05057
05058
05059 bool
05060 config_enum_lookup_by_name(struct config_enum * record, const char *value,
05061 int *retval)
05062 {
05063 const struct config_enum_entry *entry;
05064
05065 for (entry = record->options; entry && entry->name; entry++)
05066 {
05067 if (pg_strcasecmp(value, entry->name) == 0)
05068 {
05069 *retval = entry->val;
05070 return TRUE;
05071 }
05072 }
05073
05074 *retval = 0;
05075 return FALSE;
05076 }
05077
05078
05079
05080
05081
05082
05083
05084
05085 static char *
05086 config_enum_get_options(struct config_enum * record, const char *prefix,
05087 const char *suffix, const char *separator)
05088 {
05089 const struct config_enum_entry *entry;
05090 StringInfoData retstr;
05091 int seplen;
05092
05093 initStringInfo(&retstr);
05094 appendStringInfoString(&retstr, prefix);
05095
05096 seplen = strlen(separator);
05097 for (entry = record->options; entry && entry->name; entry++)
05098 {
05099 if (!entry->hidden)
05100 {
05101 appendStringInfoString(&retstr, entry->name);
05102 appendBinaryStringInfo(&retstr, separator, seplen);
05103 }
05104 }
05105
05106
05107
05108
05109
05110
05111
05112
05113 if (retstr.len >= seplen)
05114 {
05115
05116 retstr.data[retstr.len - seplen] = '\0';
05117 retstr.len -= seplen;
05118 }
05119
05120 appendStringInfoString(&retstr, suffix);
05121
05122 return retstr.data;
05123 }
05124
05125
05126
05127
05128
05129
05130
05131
05132
05133
05134
05135
05136
05137
05138
05139
05140
05141
05142
05143
05144
05145
05146
05147
05148
05149
05150
05151
05152
05153
05154
05155
05156
05157
05158
05159
05160
05161 int
05162 set_config_option(const char *name, const char *value,
05163 GucContext context, GucSource source,
05164 GucAction action, bool changeVal, int elevel)
05165 {
05166 struct config_generic *record;
05167 bool prohibitValueChange = false;
05168 bool makeDefault;
05169
05170 if (elevel == 0)
05171 {
05172 if (source == PGC_S_DEFAULT || source == PGC_S_FILE)
05173 {
05174
05175
05176
05177
05178 elevel = IsUnderPostmaster ? DEBUG3 : LOG;
05179 }
05180 else if (source == PGC_S_GLOBAL || source == PGC_S_DATABASE || source == PGC_S_USER ||
05181 source == PGC_S_DATABASE_USER)
05182 elevel = WARNING;
05183 else
05184 elevel = ERROR;
05185 }
05186
05187 record = find_option(name, true, elevel);
05188 if (record == NULL)
05189 {
05190 ereport(elevel,
05191 (errcode(ERRCODE_UNDEFINED_OBJECT),
05192 errmsg("unrecognized configuration parameter \"%s\"", name)));
05193 return 0;
05194 }
05195
05196
05197
05198
05199
05200 switch (record->context)
05201 {
05202 case PGC_INTERNAL:
05203 if (context != PGC_INTERNAL)
05204 {
05205 ereport(elevel,
05206 (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
05207 errmsg("parameter \"%s\" cannot be changed",
05208 name)));
05209 return 0;
05210 }
05211 break;
05212 case PGC_POSTMASTER:
05213 if (context == PGC_SIGHUP)
05214 {
05215
05216
05217
05218
05219
05220
05221
05222
05223
05224 prohibitValueChange = true;
05225 }
05226 else if (context != PGC_POSTMASTER)
05227 {
05228 ereport(elevel,
05229 (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
05230 errmsg("parameter \"%s\" cannot be changed without restarting the server",
05231 name)));
05232 return 0;
05233 }
05234 break;
05235 case PGC_SIGHUP:
05236 if (context != PGC_SIGHUP && context != PGC_POSTMASTER)
05237 {
05238 ereport(elevel,
05239 (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
05240 errmsg("parameter \"%s\" cannot be changed now",
05241 name)));
05242 return 0;
05243 }
05244
05245
05246
05247
05248
05249
05250
05251 break;
05252 case PGC_BACKEND:
05253 if (context == PGC_SIGHUP)
05254 {
05255
05256
05257
05258
05259
05260
05261
05262
05263 if (IsUnderPostmaster)
05264 return -1;
05265 }
05266 else if (context != PGC_POSTMASTER && context != PGC_BACKEND &&
05267 source != PGC_S_CLIENT)
05268 {
05269 ereport(elevel,
05270 (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
05271 errmsg("parameter \"%s\" cannot be set after connection start",
05272 name)));
05273 return 0;
05274 }
05275 break;
05276 case PGC_SUSET:
05277 if (context == PGC_USERSET || context == PGC_BACKEND)
05278 {
05279 ereport(elevel,
05280 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
05281 errmsg("permission denied to set parameter \"%s\"",
05282 name)));
05283 return 0;
05284 }
05285 break;
05286 case PGC_USERSET:
05287
05288 break;
05289 }
05290
05291
05292
05293
05294
05295
05296
05297
05298
05299
05300
05301
05302
05303
05304
05305
05306
05307
05308
05309 if (record->flags & GUC_NOT_WHILE_SEC_REST)
05310 {
05311 if (InLocalUserIdChange())
05312 {
05313
05314
05315
05316
05317 ereport(elevel,
05318 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
05319 errmsg("cannot set parameter \"%s\" within security-definer function",
05320 name)));
05321 return 0;
05322 }
05323 if (InSecurityRestrictedOperation())
05324 {
05325 ereport(elevel,
05326 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
05327 errmsg("cannot set parameter \"%s\" within security-restricted operation",
05328 name)));
05329 return 0;
05330 }
05331 }
05332
05333
05334
05335
05336
05337
05338
05339 makeDefault = changeVal && (source <= PGC_S_OVERRIDE) &&
05340 ((value != NULL) || source == PGC_S_DEFAULT);
05341
05342
05343
05344
05345
05346
05347
05348
05349 if (record->source > source)
05350 {
05351 if (changeVal && !makeDefault)
05352 {
05353 elog(DEBUG3, "\"%s\": setting ignored because previous source is higher priority",
05354 name);
05355 return -1;
05356 }
05357 changeVal = false;
05358 }
05359
05360
05361
05362
05363 switch (record->vartype)
05364 {
05365 case PGC_BOOL:
05366 {
05367 struct config_bool *conf = (struct config_bool *) record;
05368 bool newval;
05369 void *newextra = NULL;
05370
05371 if (value)
05372 {
05373 if (!parse_bool(value, &newval))
05374 {
05375 ereport(elevel,
05376 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
05377 errmsg("parameter \"%s\" requires a Boolean value",
05378 name)));
05379 return 0;
05380 }
05381 if (!call_bool_check_hook(conf, &newval, &newextra,
05382 source, elevel))
05383 return 0;
05384 }
05385 else if (source == PGC_S_DEFAULT)
05386 {
05387 newval = conf->boot_val;
05388 if (!call_bool_check_hook(conf, &newval, &newextra,
05389 source, elevel))
05390 return 0;
05391 }
05392 else
05393 {
05394 newval = conf->reset_val;
05395 newextra = conf->reset_extra;
05396 source = conf->gen.reset_source;
05397 context = conf->gen.reset_scontext;
05398 }
05399
05400 if (prohibitValueChange)
05401 {
05402 if (*conf->variable != newval)
05403 {
05404 ereport(elevel,
05405 (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
05406 errmsg("parameter \"%s\" cannot be changed without restarting the server",
05407 name)));
05408 return 0;
05409 }
05410 return -1;
05411 }
05412
05413 if (changeVal)
05414 {
05415
05416 if (!makeDefault)
05417 push_old_value(&conf->gen, action);
05418
05419 if (conf->assign_hook)
05420 (*conf->assign_hook) (newval, newextra);
05421 *conf->variable = newval;
05422 set_extra_field(&conf->gen, &conf->gen.extra,
05423 newextra);
05424 conf->gen.source = source;
05425 conf->gen.scontext = context;
05426 }
05427 if (makeDefault)
05428 {
05429 GucStack *stack;
05430
05431 if (conf->gen.reset_source <= source)
05432 {
05433 conf->reset_val = newval;
05434 set_extra_field(&conf->gen, &conf->reset_extra,
05435 newextra);
05436 conf->gen.reset_source = source;
05437 conf->gen.reset_scontext = context;
05438 }
05439 for (stack = conf->gen.stack; stack; stack = stack->prev)
05440 {
05441 if (stack->source <= source)
05442 {
05443 stack->prior.val.boolval = newval;
05444 set_extra_field(&conf->gen, &stack->prior.extra,
05445 newextra);
05446 stack->source = source;
05447 stack->scontext = context;
05448 }
05449 }
05450 }
05451
05452
05453 if (newextra && !extra_field_used(&conf->gen, newextra))
05454 free(newextra);
05455 break;
05456 }
05457
05458 case PGC_INT:
05459 {
05460 struct config_int *conf = (struct config_int *) record;
05461 int newval;
05462 void *newextra = NULL;
05463
05464 if (value)
05465 {
05466 const char *hintmsg;
05467
05468 if (!parse_int(value, &newval, conf->gen.flags, &hintmsg))
05469 {
05470 ereport(elevel,
05471 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
05472 errmsg("invalid value for parameter \"%s\": \"%s\"",
05473 name, value),
05474 hintmsg ? errhint("%s", _(hintmsg)) : 0));
05475 return 0;
05476 }
05477 if (newval < conf->min || newval > conf->max)
05478 {
05479 ereport(elevel,
05480 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
05481 errmsg("%d is outside the valid range for parameter \"%s\" (%d .. %d)",
05482 newval, name, conf->min, conf->max)));
05483 return 0;
05484 }
05485 if (!call_int_check_hook(conf, &newval, &newextra,
05486 source, elevel))
05487 return 0;
05488 }
05489 else if (source == PGC_S_DEFAULT)
05490 {
05491 newval = conf->boot_val;
05492 if (!call_int_check_hook(conf, &newval, &newextra,
05493 source, elevel))
05494 return 0;
05495 }
05496 else
05497 {
05498 newval = conf->reset_val;
05499 newextra = conf->reset_extra;
05500 source = conf->gen.reset_source;
05501 context = conf->gen.reset_scontext;
05502 }
05503
05504 if (prohibitValueChange)
05505 {
05506 if (*conf->variable != newval)
05507 {
05508 ereport(elevel,
05509 (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
05510 errmsg("parameter \"%s\" cannot be changed without restarting the server",
05511 name)));
05512 return 0;
05513 }
05514 return -1;
05515 }
05516
05517 if (changeVal)
05518 {
05519
05520 if (!makeDefault)
05521 push_old_value(&conf->gen, action);
05522
05523 if (conf->assign_hook)
05524 (*conf->assign_hook) (newval, newextra);
05525 *conf->variable = newval;
05526 set_extra_field(&conf->gen, &conf->gen.extra,
05527 newextra);
05528 conf->gen.source = source;
05529 conf->gen.scontext = context;
05530 }
05531 if (makeDefault)
05532 {
05533 GucStack *stack;
05534
05535 if (conf->gen.reset_source <= source)
05536 {
05537 conf->reset_val = newval;
05538 set_extra_field(&conf->gen, &conf->reset_extra,
05539 newextra);
05540 conf->gen.reset_source = source;
05541 conf->gen.reset_scontext = context;
05542 }
05543 for (stack = conf->gen.stack; stack; stack = stack->prev)
05544 {
05545 if (stack->source <= source)
05546 {
05547 stack->prior.val.intval = newval;
05548 set_extra_field(&conf->gen, &stack->prior.extra,
05549 newextra);
05550 stack->source = source;
05551 stack->scontext = context;
05552 }
05553 }
05554 }
05555
05556
05557 if (newextra && !extra_field_used(&conf->gen, newextra))
05558 free(newextra);
05559 break;
05560 }
05561
05562 case PGC_REAL:
05563 {
05564 struct config_real *conf = (struct config_real *) record;
05565 double newval;
05566 void *newextra = NULL;
05567
05568 if (value)
05569 {
05570 if (!parse_real(value, &newval))
05571 {
05572 ereport(elevel,
05573 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
05574 errmsg("parameter \"%s\" requires a numeric value",
05575 name)));
05576 return 0;
05577 }
05578 if (newval < conf->min || newval > conf->max)
05579 {
05580 ereport(elevel,
05581 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
05582 errmsg("%g is outside the valid range for parameter \"%s\" (%g .. %g)",
05583 newval, name, conf->min, conf->max)));
05584 return 0;
05585 }
05586 if (!call_real_check_hook(conf, &newval, &newextra,
05587 source, elevel))
05588 return 0;
05589 }
05590 else if (source == PGC_S_DEFAULT)
05591 {
05592 newval = conf->boot_val;
05593 if (!call_real_check_hook(conf, &newval, &newextra,
05594 source, elevel))
05595 return 0;
05596 }
05597 else
05598 {
05599 newval = conf->reset_val;
05600 newextra = conf->reset_extra;
05601 source = conf->gen.reset_source;
05602 context = conf->gen.reset_scontext;
05603 }
05604
05605 if (prohibitValueChange)
05606 {
05607 if (*conf->variable != newval)
05608 {
05609 ereport(elevel,
05610 (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
05611 errmsg("parameter \"%s\" cannot be changed without restarting the server",
05612 name)));
05613 return 0;
05614 }
05615 return -1;
05616 }
05617
05618 if (changeVal)
05619 {
05620
05621 if (!makeDefault)
05622 push_old_value(&conf->gen, action);
05623
05624 if (conf->assign_hook)
05625 (*conf->assign_hook) (newval, newextra);
05626 *conf->variable = newval;
05627 set_extra_field(&conf->gen, &conf->gen.extra,
05628 newextra);
05629 conf->gen.source = source;
05630 conf->gen.scontext = context;
05631 }
05632 if (makeDefault)
05633 {
05634 GucStack *stack;
05635
05636 if (conf->gen.reset_source <= source)
05637 {
05638 conf->reset_val = newval;
05639 set_extra_field(&conf->gen, &conf->reset_extra,
05640 newextra);
05641 conf->gen.reset_source = source;
05642 conf->gen.reset_scontext = context;
05643 }
05644 for (stack = conf->gen.stack; stack; stack = stack->prev)
05645 {
05646 if (stack->source <= source)
05647 {
05648 stack->prior.val.realval = newval;
05649 set_extra_field(&conf->gen, &stack->prior.extra,
05650 newextra);
05651 stack->source = source;
05652 stack->scontext = context;
05653 }
05654 }
05655 }
05656
05657
05658 if (newextra && !extra_field_used(&conf->gen, newextra))
05659 free(newextra);
05660 break;
05661 }
05662
05663 case PGC_STRING:
05664 {
05665 struct config_string *conf = (struct config_string *) record;
05666 char *newval;
05667 void *newextra = NULL;
05668
05669 if (value)
05670 {
05671
05672
05673
05674
05675 newval = guc_strdup(elevel, value);
05676 if (newval == NULL)
05677 return 0;
05678
05679
05680
05681
05682
05683 if (conf->gen.flags & GUC_IS_NAME)
05684 truncate_identifier(newval, strlen(newval), true);
05685
05686 if (!call_string_check_hook(conf, &newval, &newextra,
05687 source, elevel))
05688 {
05689 free(newval);
05690 return 0;
05691 }
05692 }
05693 else if (source == PGC_S_DEFAULT)
05694 {
05695
05696 if (conf->boot_val != NULL)
05697 {
05698 newval = guc_strdup(elevel, conf->boot_val);
05699 if (newval == NULL)
05700 return 0;
05701 }
05702 else
05703 newval = NULL;
05704
05705 if (!call_string_check_hook(conf, &newval, &newextra,
05706 source, elevel))
05707 {
05708 free(newval);
05709 return 0;
05710 }
05711 }
05712 else
05713 {
05714
05715
05716
05717
05718 newval = conf->reset_val;
05719 newextra = conf->reset_extra;
05720 source = conf->gen.reset_source;
05721 context = conf->gen.reset_scontext;
05722 }
05723
05724 if (prohibitValueChange)
05725 {
05726
05727 if (*conf->variable == NULL || newval == NULL ||
05728 strcmp(*conf->variable, newval) != 0)
05729 {
05730 ereport(elevel,
05731 (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
05732 errmsg("parameter \"%s\" cannot be changed without restarting the server",
05733 name)));
05734 return 0;
05735 }
05736 return -1;
05737 }
05738
05739 if (changeVal)
05740 {
05741
05742 if (!makeDefault)
05743 push_old_value(&conf->gen, action);
05744
05745 if (conf->assign_hook)
05746 (*conf->assign_hook) (newval, newextra);
05747 set_string_field(conf, conf->variable, newval);
05748 set_extra_field(&conf->gen, &conf->gen.extra,
05749 newextra);
05750 conf->gen.source = source;
05751 conf->gen.scontext = context;
05752 }
05753
05754 if (makeDefault)
05755 {
05756 GucStack *stack;
05757
05758 if (conf->gen.reset_source <= source)
05759 {
05760 set_string_field(conf, &conf->reset_val, newval);
05761 set_extra_field(&conf->gen, &conf->reset_extra,
05762 newextra);
05763 conf->gen.reset_source = source;
05764 conf->gen.reset_scontext = context;
05765 }
05766 for (stack = conf->gen.stack; stack; stack = stack->prev)
05767 {
05768 if (stack->source <= source)
05769 {
05770 set_string_field(conf, &stack->prior.val.stringval,
05771 newval);
05772 set_extra_field(&conf->gen, &stack->prior.extra,
05773 newextra);
05774 stack->source = source;
05775 stack->scontext = context;
05776 }
05777 }
05778 }
05779
05780
05781 if (newval && !string_field_used(conf, newval))
05782 free(newval);
05783
05784 if (newextra && !extra_field_used(&conf->gen, newextra))
05785 free(newextra);
05786 break;
05787 }
05788
05789 case PGC_ENUM:
05790 {
05791 struct config_enum *conf = (struct config_enum *) record;
05792 int newval;
05793 void *newextra = NULL;
05794
05795 if (value)
05796 {
05797 if (!config_enum_lookup_by_name(conf, value, &newval))
05798 {
05799 char *hintmsg;
05800
05801 hintmsg = config_enum_get_options(conf,
05802 "Available values: ",
05803 ".", ", ");
05804
05805 ereport(elevel,
05806 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
05807 errmsg("invalid value for parameter \"%s\": \"%s\"",
05808 name, value),
05809 hintmsg ? errhint("%s", _(hintmsg)) : 0));
05810
05811 if (hintmsg)
05812 pfree(hintmsg);
05813 return 0;
05814 }
05815 if (!call_enum_check_hook(conf, &newval, &newextra,
05816 source, elevel))
05817 return 0;
05818 }
05819 else if (source == PGC_S_DEFAULT)
05820 {
05821 newval = conf->boot_val;
05822 if (!call_enum_check_hook(conf, &newval, &newextra,
05823 source, elevel))
05824 return 0;
05825 }
05826 else
05827 {
05828 newval = conf->reset_val;
05829 newextra = conf->reset_extra;
05830 source = conf->gen.reset_source;
05831 context = conf->gen.reset_scontext;
05832 }
05833
05834 if (prohibitValueChange)
05835 {
05836 if (*conf->variable != newval)
05837 {
05838 ereport(elevel,
05839 (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
05840 errmsg("parameter \"%s\" cannot be changed without restarting the server",
05841 name)));
05842 return 0;
05843 }
05844 return -1;
05845 }
05846
05847 if (changeVal)
05848 {
05849
05850 if (!makeDefault)
05851 push_old_value(&conf->gen, action);
05852
05853 if (conf->assign_hook)
05854 (*conf->assign_hook) (newval, newextra);
05855 *conf->variable = newval;
05856 set_extra_field(&conf->gen, &conf->gen.extra,
05857 newextra);
05858 conf->gen.source = source;
05859 conf->gen.scontext = context;
05860 }
05861 if (makeDefault)
05862 {
05863 GucStack *stack;
05864
05865 if (conf->gen.reset_source <= source)
05866 {
05867 conf->reset_val = newval;
05868 set_extra_field(&conf->gen, &conf->reset_extra,
05869 newextra);
05870 conf->gen.reset_source = source;
05871 conf->gen.reset_scontext = context;
05872 }
05873 for (stack = conf->gen.stack; stack; stack = stack->prev)
05874 {
05875 if (stack->source <= source)
05876 {
05877 stack->prior.val.enumval = newval;
05878 set_extra_field(&conf->gen, &stack->prior.extra,
05879 newextra);
05880 stack->source = source;
05881 stack->scontext = context;
05882 }
05883 }
05884 }
05885
05886
05887 if (newextra && !extra_field_used(&conf->gen, newextra))
05888 free(newextra);
05889 break;
05890 }
05891 }
05892
05893 if (changeVal && (record->flags & GUC_REPORT))
05894 ReportGUCOption(record);
05895
05896 return changeVal ? 1 : -1;
05897 }
05898
05899
05900
05901
05902
05903 static void
05904 set_config_sourcefile(const char *name, char *sourcefile, int sourceline)
05905 {
05906 struct config_generic *record;
05907 int elevel;
05908
05909
05910
05911
05912
05913 elevel = IsUnderPostmaster ? DEBUG3 : LOG;
05914
05915 record = find_option(name, true, elevel);
05916
05917 if (record == NULL)
05918 elog(ERROR, "unrecognized configuration parameter \"%s\"", name);
05919
05920 sourcefile = guc_strdup(elevel, sourcefile);
05921 if (record->sourcefile)
05922 free(record->sourcefile);
05923 record->sourcefile = sourcefile;
05924 record->sourceline = sourceline;
05925 }
05926
05927
05928
05929
05930
05931
05932
05933
05934
05935
05936
05937 void
05938 SetConfigOption(const char *name, const char *value,
05939 GucContext context, GucSource source)
05940 {
05941 (void) set_config_option(name, value, context, source,
05942 GUC_ACTION_SET, true, 0);
05943 }
05944
05945
05946
05947
05948
05949
05950
05951
05952
05953
05954
05955
05956
05957
05958
05959
05960
05961 const char *
05962 GetConfigOption(const char *name, bool missing_ok, bool restrict_superuser)
05963 {
05964 struct config_generic *record;
05965 static char buffer[256];
05966
05967 record = find_option(name, false, ERROR);
05968 if (record == NULL)
05969 {
05970 if (missing_ok)
05971 return NULL;
05972 ereport(ERROR,
05973 (errcode(ERRCODE_UNDEFINED_OBJECT),
05974 errmsg("unrecognized configuration parameter \"%s\"",
05975 name)));
05976 }
05977 if (restrict_superuser &&
05978 (record->flags & GUC_SUPERUSER_ONLY) &&
05979 !superuser())
05980 ereport(ERROR,
05981 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
05982 errmsg("must be superuser to examine \"%s\"", name)));
05983
05984 switch (record->vartype)
05985 {
05986 case PGC_BOOL:
05987 return *((struct config_bool *) record)->variable ? "on" : "off";
05988
05989 case PGC_INT:
05990 snprintf(buffer, sizeof(buffer), "%d",
05991 *((struct config_int *) record)->variable);
05992 return buffer;
05993
05994 case PGC_REAL:
05995 snprintf(buffer, sizeof(buffer), "%g",
05996 *((struct config_real *) record)->variable);
05997 return buffer;
05998
05999 case PGC_STRING:
06000 return *((struct config_string *) record)->variable;
06001
06002 case PGC_ENUM:
06003 return config_enum_lookup_by_value((struct config_enum *) record,
06004 *((struct config_enum *) record)->variable);
06005 }
06006 return NULL;
06007 }
06008
06009
06010
06011
06012
06013
06014
06015
06016 const char *
06017 GetConfigOptionResetString(const char *name)
06018 {
06019 struct config_generic *record;
06020 static char buffer[256];
06021
06022 record = find_option(name, false, ERROR);
06023 if (record == NULL)
06024 ereport(ERROR,
06025 (errcode(ERRCODE_UNDEFINED_OBJECT),
06026 errmsg("unrecognized configuration parameter \"%s\"", name)));
06027 if ((record->flags & GUC_SUPERUSER_ONLY) && !superuser())
06028 ereport(ERROR,
06029 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
06030 errmsg("must be superuser to examine \"%s\"", name)));
06031
06032 switch (record->vartype)
06033 {
06034 case PGC_BOOL:
06035 return ((struct config_bool *) record)->reset_val ? "on" : "off";
06036
06037 case PGC_INT:
06038 snprintf(buffer, sizeof(buffer), "%d",
06039 ((struct config_int *) record)->reset_val);
06040 return buffer;
06041
06042 case PGC_REAL:
06043 snprintf(buffer, sizeof(buffer), "%g",
06044 ((struct config_real *) record)->reset_val);
06045 return buffer;
06046
06047 case PGC_STRING:
06048 return ((struct config_string *) record)->reset_val;
06049
06050 case PGC_ENUM:
06051 return config_enum_lookup_by_value((struct config_enum *) record,
06052 ((struct config_enum *) record)->reset_val);
06053 }
06054 return NULL;
06055 }
06056
06057
06058
06059
06060
06061
06062
06063
06064
06065
06066
06067
06068
06069 static char *
06070 flatten_set_variable_args(const char *name, List *args)
06071 {
06072 struct config_generic *record;
06073 int flags;
06074 StringInfoData buf;
06075 ListCell *l;
06076
06077
06078 if (args == NIL)
06079 return NULL;
06080
06081
06082
06083
06084
06085 record = find_option(name, false, WARNING);
06086 if (record)
06087 flags = record->flags;
06088 else
06089 flags = 0;
06090
06091
06092 if ((flags & GUC_LIST_INPUT) == 0 &&
06093 list_length(args) != 1)
06094 ereport(ERROR,
06095 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
06096 errmsg("SET %s takes only one argument", name)));
06097
06098 initStringInfo(&buf);
06099
06100
06101
06102
06103
06104
06105 foreach(l, args)
06106 {
06107 Node *arg = (Node *) lfirst(l);
06108 char *val;
06109 TypeName *typeName = NULL;
06110 A_Const *con;
06111
06112 if (l != list_head(args))
06113 appendStringInfo(&buf, ", ");
06114
06115 if (IsA(arg, TypeCast))
06116 {
06117 TypeCast *tc = (TypeCast *) arg;
06118
06119 arg = tc->arg;
06120 typeName = tc->typeName;
06121 }
06122
06123 if (!IsA(arg, A_Const))
06124 elog(ERROR, "unrecognized node type: %d", (int) nodeTag(arg));
06125 con = (A_Const *) arg;
06126
06127 switch (nodeTag(&con->val))
06128 {
06129 case T_Integer:
06130 appendStringInfo(&buf, "%ld", intVal(&con->val));
06131 break;
06132 case T_Float:
06133
06134 appendStringInfoString(&buf, strVal(&con->val));
06135 break;
06136 case T_String:
06137 val = strVal(&con->val);
06138 if (typeName != NULL)
06139 {
06140
06141
06142
06143
06144
06145 Oid typoid;
06146 int32 typmod;
06147 Datum interval;
06148 char *intervalout;
06149
06150 typenameTypeIdAndMod(NULL, typeName, &typoid, &typmod);
06151 Assert(typoid == INTERVALOID);
06152
06153 interval =
06154 DirectFunctionCall3(interval_in,
06155 CStringGetDatum(val),
06156 ObjectIdGetDatum(InvalidOid),
06157 Int32GetDatum(typmod));
06158
06159 intervalout =
06160 DatumGetCString(DirectFunctionCall1(interval_out,
06161 interval));
06162 appendStringInfo(&buf, "INTERVAL '%s'", intervalout);
06163 }
06164 else
06165 {
06166
06167
06168
06169
06170 if (flags & GUC_LIST_QUOTE)
06171 appendStringInfoString(&buf, quote_identifier(val));
06172 else
06173 appendStringInfoString(&buf, val);
06174 }
06175 break;
06176 default:
06177 elog(ERROR, "unrecognized node type: %d",
06178 (int) nodeTag(&con->val));
06179 break;
06180 }
06181 }
06182
06183 return buf.data;
06184 }
06185
06186
06187
06188
06189
06190 void
06191 ExecSetVariableStmt(VariableSetStmt *stmt)
06192 {
06193 GucAction action = stmt->is_local ? GUC_ACTION_LOCAL : GUC_ACTION_SET;
06194
06195 switch (stmt->kind)
06196 {
06197 case VAR_SET_VALUE:
06198 case VAR_SET_CURRENT:
06199 (void) set_config_option(stmt->name,
06200 ExtractSetVariableArgs(stmt),
06201 (superuser() ? PGC_SUSET : PGC_USERSET),
06202 PGC_S_SESSION,
06203 action,
06204 true,
06205 0);
06206 break;
06207 case VAR_SET_MULTI:
06208
06209
06210
06211
06212
06213
06214
06215
06216 if (strcmp(stmt->name, "TRANSACTION") == 0)
06217 {
06218 ListCell *head;
06219
06220 foreach(head, stmt->args)
06221 {
06222 DefElem *item = (DefElem *) lfirst(head);
06223
06224 if (strcmp(item->defname, "transaction_isolation") == 0)
06225 SetPGVariable("transaction_isolation",
06226 list_make1(item->arg), stmt->is_local);
06227 else if (strcmp(item->defname, "transaction_read_only") == 0)
06228 SetPGVariable("transaction_read_only",
06229 list_make1(item->arg), stmt->is_local);
06230 else if (strcmp(item->defname, "transaction_deferrable") == 0)
06231 SetPGVariable("transaction_deferrable",
06232 list_make1(item->arg), stmt->is_local);
06233 else
06234 elog(ERROR, "unexpected SET TRANSACTION element: %s",
06235 item->defname);
06236 }
06237 }
06238 else if (strcmp(stmt->name, "SESSION CHARACTERISTICS") == 0)
06239 {
06240 ListCell *head;
06241
06242 foreach(head, stmt->args)
06243 {
06244 DefElem *item = (DefElem *) lfirst(head);
06245
06246 if (strcmp(item->defname, "transaction_isolation") == 0)
06247 SetPGVariable("default_transaction_isolation",
06248 list_make1(item->arg), stmt->is_local);
06249 else if (strcmp(item->defname, "transaction_read_only") == 0)
06250 SetPGVariable("default_transaction_read_only",
06251 list_make1(item->arg), stmt->is_local);
06252 else if (strcmp(item->defname, "transaction_deferrable") == 0)
06253 SetPGVariable("default_transaction_deferrable",
06254 list_make1(item->arg), stmt->is_local);
06255 else
06256 elog(ERROR, "unexpected SET SESSION element: %s",
06257 item->defname);
06258 }
06259 }
06260 else if (strcmp(stmt->name, "TRANSACTION SNAPSHOT") == 0)
06261 {
06262 A_Const *con = (A_Const *) linitial(stmt->args);
06263
06264 if (stmt->is_local)
06265 ereport(ERROR,
06266 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
06267 errmsg("SET LOCAL TRANSACTION SNAPSHOT is not implemented")));
06268 Assert(IsA(con, A_Const));
06269 Assert(nodeTag(&con->val) == T_String);
06270 ImportSnapshot(strVal(&con->val));
06271 }
06272 else
06273 elog(ERROR, "unexpected SET MULTI element: %s",
06274 stmt->name);
06275 break;
06276 case VAR_SET_DEFAULT:
06277 case VAR_RESET:
06278 (void) set_config_option(stmt->name,
06279 NULL,
06280 (superuser() ? PGC_SUSET : PGC_USERSET),
06281 PGC_S_SESSION,
06282 action,
06283 true,
06284 0);
06285 break;
06286 case VAR_RESET_ALL:
06287 ResetAllOptions();
06288 break;
06289 }
06290 }
06291
06292
06293
06294
06295
06296
06297
06298 char *
06299 ExtractSetVariableArgs(VariableSetStmt *stmt)
06300 {
06301 switch (stmt->kind)
06302 {
06303 case VAR_SET_VALUE:
06304 return flatten_set_variable_args(stmt->name, stmt->args);
06305 case VAR_SET_CURRENT:
06306 return GetConfigOptionByName(stmt->name, NULL);
06307 default:
06308 return NULL;
06309 }
06310 }
06311
06312
06313
06314
06315
06316
06317
06318 void
06319 SetPGVariable(const char *name, List *args, bool is_local)
06320 {
06321 char *argstring = flatten_set_variable_args(name, args);
06322
06323
06324 (void) set_config_option(name,
06325 argstring,
06326 (superuser() ? PGC_SUSET : PGC_USERSET),
06327 PGC_S_SESSION,
06328 is_local ? GUC_ACTION_LOCAL : GUC_ACTION_SET,
06329 true,
06330 0);
06331 }
06332
06333
06334
06335
06336 Datum
06337 set_config_by_name(PG_FUNCTION_ARGS)
06338 {
06339 char *name;
06340 char *value;
06341 char *new_value;
06342 bool is_local;
06343
06344 if (PG_ARGISNULL(0))
06345 ereport(ERROR,
06346 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
06347 errmsg("SET requires parameter name")));
06348
06349
06350 name = TextDatumGetCString(PG_GETARG_DATUM(0));
06351
06352
06353 if (PG_ARGISNULL(1))
06354 value = NULL;
06355 else
06356 value = TextDatumGetCString(PG_GETARG_DATUM(1));
06357
06358
06359
06360
06361
06362 if (PG_ARGISNULL(2))
06363 is_local = false;
06364 else
06365 is_local = PG_GETARG_BOOL(2);
06366
06367
06368 (void) set_config_option(name,
06369 value,
06370 (superuser() ? PGC_SUSET : PGC_USERSET),
06371 PGC_S_SESSION,
06372 is_local ? GUC_ACTION_LOCAL : GUC_ACTION_SET,
06373 true,
06374 0);
06375
06376
06377 new_value = GetConfigOptionByName(name, NULL);
06378
06379
06380 PG_RETURN_TEXT_P(cstring_to_text(new_value));
06381 }
06382
06383
06384
06385
06386
06387
06388 static struct config_generic *
06389 init_custom_variable(const char *name,
06390 const char *short_desc,
06391 const char *long_desc,
06392 GucContext context,
06393 int flags,
06394 enum config_type type,
06395 size_t sz)
06396 {
06397 struct config_generic *gen;
06398
06399
06400
06401
06402
06403
06404
06405
06406 if (context == PGC_POSTMASTER &&
06407 !process_shared_preload_libraries_in_progress)
06408 elog(FATAL, "cannot create PGC_POSTMASTER variables after startup");
06409
06410 gen = (struct config_generic *) guc_malloc(ERROR, sz);
06411 memset(gen, 0, sz);
06412
06413 gen->name = guc_strdup(ERROR, name);
06414 gen->context = context;
06415 gen->group = CUSTOM_OPTIONS;
06416 gen->short_desc = short_desc;
06417 gen->long_desc = long_desc;
06418 gen->flags = flags;
06419 gen->vartype = type;
06420
06421 return gen;
06422 }
06423
06424
06425
06426
06427
06428 static void
06429 define_custom_variable(struct config_generic * variable)
06430 {
06431 const char *name = variable->name;
06432 const char **nameAddr = &name;
06433 struct config_string *pHolder;
06434 struct config_generic **res;
06435
06436
06437
06438
06439 res = (struct config_generic **) bsearch((void *) &nameAddr,
06440 (void *) guc_variables,
06441 num_guc_variables,
06442 sizeof(struct config_generic *),
06443 guc_var_compare);
06444 if (res == NULL)
06445 {
06446
06447
06448
06449
06450 InitializeOneGUCOption(variable);
06451 add_guc_variable(variable, ERROR);
06452 return;
06453 }
06454
06455
06456
06457
06458 if (((*res)->flags & GUC_CUSTOM_PLACEHOLDER) == 0)
06459 ereport(ERROR,
06460 (errcode(ERRCODE_INTERNAL_ERROR),
06461 errmsg("attempt to redefine parameter \"%s\"", name)));
06462
06463 Assert((*res)->vartype == PGC_STRING);
06464 pHolder = (struct config_string *) (*res);
06465
06466
06467
06468
06469
06470
06471 InitializeOneGUCOption(variable);
06472
06473
06474
06475
06476
06477 *res = variable;
06478
06479
06480
06481
06482
06483
06484
06485
06486
06487
06488
06489
06490
06491 if (pHolder->reset_val)
06492 (void) set_config_option(name, pHolder->reset_val,
06493 pHolder->gen.reset_scontext,
06494 pHolder->gen.reset_source,
06495 GUC_ACTION_SET, true, WARNING);
06496
06497 Assert(variable->stack == NULL);
06498
06499
06500 reapply_stacked_values(variable, pHolder, pHolder->gen.stack,
06501 *(pHolder->variable),
06502 pHolder->gen.scontext, pHolder->gen.source);
06503
06504
06505 if (pHolder->gen.sourcefile)
06506 set_config_sourcefile(name, pHolder->gen.sourcefile,
06507 pHolder->gen.sourceline);
06508
06509
06510
06511
06512
06513
06514
06515 set_string_field(pHolder, pHolder->variable, NULL);
06516 set_string_field(pHolder, &pHolder->reset_val, NULL);
06517
06518 free(pHolder);
06519 }
06520
06521
06522
06523
06524
06525
06526
06527
06528 static void
06529 reapply_stacked_values(struct config_generic * variable,
06530 struct config_string * pHolder,
06531 GucStack *stack,
06532 const char *curvalue,
06533 GucContext curscontext, GucSource cursource)
06534 {
06535 const char *name = variable->name;
06536 GucStack *oldvarstack = variable->stack;
06537
06538 if (stack != NULL)
06539 {
06540
06541 reapply_stacked_values(variable, pHolder, stack->prev,
06542 stack->prior.val.stringval,
06543 stack->scontext, stack->source);
06544
06545
06546 switch (stack->state)
06547 {
06548 case GUC_SAVE:
06549 (void) set_config_option(name, curvalue,
06550 curscontext, cursource,
06551 GUC_ACTION_SAVE, true, WARNING);
06552 break;
06553
06554 case GUC_SET:
06555 (void) set_config_option(name, curvalue,
06556 curscontext, cursource,
06557 GUC_ACTION_SET, true, WARNING);
06558 break;
06559
06560 case GUC_LOCAL:
06561 (void) set_config_option(name, curvalue,
06562 curscontext, cursource,
06563 GUC_ACTION_LOCAL, true, WARNING);
06564 break;
06565
06566 case GUC_SET_LOCAL:
06567
06568 (void) set_config_option(name, stack->masked.val.stringval,
06569 stack->masked_scontext, PGC_S_SESSION,
06570 GUC_ACTION_SET, true, WARNING);
06571
06572 (void) set_config_option(name, curvalue,
06573 curscontext, cursource,
06574 GUC_ACTION_LOCAL, true, WARNING);
06575 break;
06576 }
06577
06578
06579 if (variable->stack != oldvarstack)
06580 variable->stack->nest_level = stack->nest_level;
06581 }
06582 else
06583 {
06584
06585
06586
06587
06588
06589
06590
06591
06592 if (curvalue != pHolder->reset_val ||
06593 curscontext != pHolder->gen.reset_scontext ||
06594 cursource != pHolder->gen.reset_source)
06595 {
06596 (void) set_config_option(name, curvalue,
06597 curscontext, cursource,
06598 GUC_ACTION_SET, true, WARNING);
06599 variable->stack = NULL;
06600 }
06601 }
06602 }
06603
06604 void
06605 DefineCustomBoolVariable(const char *name,
06606 const char *short_desc,
06607 const char *long_desc,
06608 bool *valueAddr,
06609 bool bootValue,
06610 GucContext context,
06611 int flags,
06612 GucBoolCheckHook check_hook,
06613 GucBoolAssignHook assign_hook,
06614 GucShowHook show_hook)
06615 {
06616 struct config_bool *var;
06617
06618 var = (struct config_bool *)
06619 init_custom_variable(name, short_desc, long_desc, context, flags,
06620 PGC_BOOL, sizeof(struct config_bool));
06621 var->variable = valueAddr;
06622 var->boot_val = bootValue;
06623 var->reset_val = bootValue;
06624 var->check_hook = check_hook;
06625 var->assign_hook = assign_hook;
06626 var->show_hook = show_hook;
06627 define_custom_variable(&var->gen);
06628 }
06629
06630 void
06631 DefineCustomIntVariable(const char *name,
06632 const char *short_desc,
06633 const char *long_desc,
06634 int *valueAddr,
06635 int bootValue,
06636 int minValue,
06637 int maxValue,
06638 GucContext context,
06639 int flags,
06640 GucIntCheckHook check_hook,
06641 GucIntAssignHook assign_hook,
06642 GucShowHook show_hook)
06643 {
06644 struct config_int *var;
06645
06646 var = (struct config_int *)
06647 init_custom_variable(name, short_desc, long_desc, context, flags,
06648 PGC_INT, sizeof(struct config_int));
06649 var->variable = valueAddr;
06650 var->boot_val = bootValue;
06651 var->reset_val = bootValue;
06652 var->min = minValue;
06653 var->max = maxValue;
06654 var->check_hook = check_hook;
06655 var->assign_hook = assign_hook;
06656 var->show_hook = show_hook;
06657 define_custom_variable(&var->gen);
06658 }
06659
06660 void
06661 DefineCustomRealVariable(const char *name,
06662 const char *short_desc,
06663 const char *long_desc,
06664 double *valueAddr,
06665 double bootValue,
06666 double minValue,
06667 double maxValue,
06668 GucContext context,
06669 int flags,
06670 GucRealCheckHook check_hook,
06671 GucRealAssignHook assign_hook,
06672 GucShowHook show_hook)
06673 {
06674 struct config_real *var;
06675
06676 var = (struct config_real *)
06677 init_custom_variable(name, short_desc, long_desc, context, flags,
06678 PGC_REAL, sizeof(struct config_real));
06679 var->variable = valueAddr;
06680 var->boot_val = bootValue;
06681 var->reset_val = bootValue;
06682 var->min = minValue;
06683 var->max = maxValue;
06684 var->check_hook = check_hook;
06685 var->assign_hook = assign_hook;
06686 var->show_hook = show_hook;
06687 define_custom_variable(&var->gen);
06688 }
06689
06690 void
06691 DefineCustomStringVariable(const char *name,
06692 const char *short_desc,
06693 const char *long_desc,
06694 char **valueAddr,
06695 const char *bootValue,
06696 GucContext context,
06697 int flags,
06698 GucStringCheckHook check_hook,
06699 GucStringAssignHook assign_hook,
06700 GucShowHook show_hook)
06701 {
06702 struct config_string *var;
06703
06704 var = (struct config_string *)
06705 init_custom_variable(name, short_desc, long_desc, context, flags,
06706 PGC_STRING, sizeof(struct config_string));
06707 var->variable = valueAddr;
06708 var->boot_val = bootValue;
06709 var->check_hook = check_hook;
06710 var->assign_hook = assign_hook;
06711 var->show_hook = show_hook;
06712 define_custom_variable(&var->gen);
06713 }
06714
06715 void
06716 DefineCustomEnumVariable(const char *name,
06717 const char *short_desc,
06718 const char *long_desc,
06719 int *valueAddr,
06720 int bootValue,
06721 const struct config_enum_entry * options,
06722 GucContext context,
06723 int flags,
06724 GucEnumCheckHook check_hook,
06725 GucEnumAssignHook assign_hook,
06726 GucShowHook show_hook)
06727 {
06728 struct config_enum *var;
06729
06730 var = (struct config_enum *)
06731 init_custom_variable(name, short_desc, long_desc, context, flags,
06732 PGC_ENUM, sizeof(struct config_enum));
06733 var->variable = valueAddr;
06734 var->boot_val = bootValue;
06735 var->reset_val = bootValue;
06736 var->options = options;
06737 var->check_hook = check_hook;
06738 var->assign_hook = assign_hook;
06739 var->show_hook = show_hook;
06740 define_custom_variable(&var->gen);
06741 }
06742
06743 void
06744 EmitWarningsOnPlaceholders(const char *className)
06745 {
06746 int classLen = strlen(className);
06747 int i;
06748
06749 for (i = 0; i < num_guc_variables; i++)
06750 {
06751 struct config_generic *var = guc_variables[i];
06752
06753 if ((var->flags & GUC_CUSTOM_PLACEHOLDER) != 0 &&
06754 strncmp(className, var->name, classLen) == 0 &&
06755 var->name[classLen] == GUC_QUALIFIER_SEPARATOR)
06756 {
06757 ereport(WARNING,
06758 (errcode(ERRCODE_UNDEFINED_OBJECT),
06759 errmsg("unrecognized configuration parameter \"%s\"",
06760 var->name)));
06761 }
06762 }
06763 }
06764
06765
06766
06767
06768
06769 void
06770 GetPGVariable(const char *name, DestReceiver *dest)
06771 {
06772 if (guc_name_compare(name, "all") == 0)
06773 ShowAllGUCConfig(dest);
06774 else
06775 ShowGUCConfigOption(name, dest);
06776 }
06777
06778 TupleDesc
06779 GetPGVariableResultDesc(const char *name)
06780 {
06781 TupleDesc tupdesc;
06782
06783 if (guc_name_compare(name, "all") == 0)
06784 {
06785
06786 tupdesc = CreateTemplateTupleDesc(3, false);
06787 TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
06788 TEXTOID, -1, 0);
06789 TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting",
06790 TEXTOID, -1, 0);
06791 TupleDescInitEntry(tupdesc, (AttrNumber) 3, "description",
06792 TEXTOID, -1, 0);
06793 }
06794 else
06795 {
06796 const char *varname;
06797
06798
06799 (void) GetConfigOptionByName(name, &varname);
06800
06801
06802 tupdesc = CreateTemplateTupleDesc(1, false);
06803 TupleDescInitEntry(tupdesc, (AttrNumber) 1, varname,
06804 TEXTOID, -1, 0);
06805 }
06806 return tupdesc;
06807 }
06808
06809
06810
06811
06812
06813 static void
06814 ShowGUCConfigOption(const char *name, DestReceiver *dest)
06815 {
06816 TupOutputState *tstate;
06817 TupleDesc tupdesc;
06818 const char *varname;
06819 char *value;
06820
06821
06822 value = GetConfigOptionByName(name, &varname);
06823
06824
06825 tupdesc = CreateTemplateTupleDesc(1, false);
06826 TupleDescInitEntry(tupdesc, (AttrNumber) 1, varname,
06827 TEXTOID, -1, 0);
06828
06829
06830 tstate = begin_tup_output_tupdesc(dest, tupdesc);
06831
06832
06833 do_text_output_oneline(tstate, value);
06834
06835 end_tup_output(tstate);
06836 }
06837
06838
06839
06840
06841 static void
06842 ShowAllGUCConfig(DestReceiver *dest)
06843 {
06844 bool am_superuser = superuser();
06845 int i;
06846 TupOutputState *tstate;
06847 TupleDesc tupdesc;
06848 Datum values[3];
06849 bool isnull[3] = {false, false, false};
06850
06851
06852 tupdesc = CreateTemplateTupleDesc(3, false);
06853 TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
06854 TEXTOID, -1, 0);
06855 TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting",
06856 TEXTOID, -1, 0);
06857 TupleDescInitEntry(tupdesc, (AttrNumber) 3, "description",
06858 TEXTOID, -1, 0);
06859
06860
06861 tstate = begin_tup_output_tupdesc(dest, tupdesc);
06862
06863 for (i = 0; i < num_guc_variables; i++)
06864 {
06865 struct config_generic *conf = guc_variables[i];
06866 char *setting;
06867
06868 if ((conf->flags & GUC_NO_SHOW_ALL) ||
06869 ((conf->flags & GUC_SUPERUSER_ONLY) && !am_superuser))
06870 continue;
06871
06872
06873 values[0] = PointerGetDatum(cstring_to_text(conf->name));
06874
06875 setting = _ShowOption(conf, true);
06876 if (setting)
06877 {
06878 values[1] = PointerGetDatum(cstring_to_text(setting));
06879 isnull[1] = false;
06880 }
06881 else
06882 {
06883 values[1] = PointerGetDatum(NULL);
06884 isnull[1] = true;
06885 }
06886
06887 values[2] = PointerGetDatum(cstring_to_text(conf->short_desc));
06888
06889
06890 do_tup_output(tstate, values, isnull);
06891
06892
06893 pfree(DatumGetPointer(values[0]));
06894 if (setting)
06895 {
06896 pfree(setting);
06897 pfree(DatumGetPointer(values[1]));
06898 }
06899 pfree(DatumGetPointer(values[2]));
06900 }
06901
06902 end_tup_output(tstate);
06903 }
06904
06905
06906
06907
06908
06909 char *
06910 GetConfigOptionByName(const char *name, const char **varname)
06911 {
06912 struct config_generic *record;
06913
06914 record = find_option(name, false, ERROR);
06915 if (record == NULL)
06916 ereport(ERROR,
06917 (errcode(ERRCODE_UNDEFINED_OBJECT),
06918 errmsg("unrecognized configuration parameter \"%s\"", name)));
06919 if ((record->flags & GUC_SUPERUSER_ONLY) && !superuser())
06920 ereport(ERROR,
06921 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
06922 errmsg("must be superuser to examine \"%s\"", name)));
06923
06924 if (varname)
06925 *varname = record->name;
06926
06927 return _ShowOption(record, true);
06928 }
06929
06930
06931
06932
06933
06934 void
06935 GetConfigOptionByNum(int varnum, const char **values, bool *noshow)
06936 {
06937 char buffer[256];
06938 struct config_generic *conf;
06939
06940
06941 Assert((varnum >= 0) && (varnum < num_guc_variables));
06942
06943 conf = guc_variables[varnum];
06944
06945 if (noshow)
06946 {
06947 if ((conf->flags & GUC_NO_SHOW_ALL) ||
06948 ((conf->flags & GUC_SUPERUSER_ONLY) && !superuser()))
06949 *noshow = true;
06950 else
06951 *noshow = false;
06952 }
06953
06954
06955
06956
06957 values[0] = conf->name;
06958
06959
06960 values[1] = _ShowOption(conf, false);
06961
06962
06963 if (conf->vartype == PGC_INT)
06964 {
06965 static char buf[8];
06966
06967 switch (conf->flags & (GUC_UNIT_MEMORY | GUC_UNIT_TIME))
06968 {
06969 case GUC_UNIT_KB:
06970 values[2] = "kB";
06971 break;
06972 case GUC_UNIT_BLOCKS:
06973 snprintf(buf, sizeof(buf), "%dkB", BLCKSZ / 1024);
06974 values[2] = buf;
06975 break;
06976 case GUC_UNIT_XBLOCKS:
06977 snprintf(buf, sizeof(buf), "%dkB", XLOG_BLCKSZ / 1024);
06978 values[2] = buf;
06979 break;
06980 case GUC_UNIT_MS:
06981 values[2] = "ms";
06982 break;
06983 case GUC_UNIT_S:
06984 values[2] = "s";
06985 break;
06986 case GUC_UNIT_MIN:
06987 values[2] = "min";
06988 break;
06989 default:
06990 values[2] = "";
06991 break;
06992 }
06993 }
06994 else
06995 values[2] = NULL;
06996
06997
06998 values[3] = config_group_names[conf->group];
06999
07000
07001 values[4] = conf->short_desc;
07002
07003
07004 values[5] = conf->long_desc;
07005
07006
07007 values[6] = GucContext_Names[conf->context];
07008
07009
07010 values[7] = config_type_names[conf->vartype];
07011
07012
07013 values[8] = GucSource_Names[conf->source];
07014
07015
07016 switch (conf->vartype)
07017 {
07018 case PGC_BOOL:
07019 {
07020 struct config_bool *lconf = (struct config_bool *) conf;
07021
07022
07023 values[9] = NULL;
07024
07025
07026 values[10] = NULL;
07027
07028
07029 values[11] = NULL;
07030
07031
07032 values[12] = pstrdup(lconf->boot_val ? "on" : "off");
07033
07034
07035 values[13] = pstrdup(lconf->reset_val ? "on" : "off");
07036 }
07037 break;
07038
07039 case PGC_INT:
07040 {
07041 struct config_int *lconf = (struct config_int *) conf;
07042
07043
07044 snprintf(buffer, sizeof(buffer), "%d", lconf->min);
07045 values[9] = pstrdup(buffer);
07046
07047
07048 snprintf(buffer, sizeof(buffer), "%d", lconf->max);
07049 values[10] = pstrdup(buffer);
07050
07051
07052 values[11] = NULL;
07053
07054
07055 snprintf(buffer, sizeof(buffer), "%d", lconf->boot_val);
07056 values[12] = pstrdup(buffer);
07057
07058
07059 snprintf(buffer, sizeof(buffer), "%d", lconf->reset_val);
07060 values[13] = pstrdup(buffer);
07061 }
07062 break;
07063
07064 case PGC_REAL:
07065 {
07066 struct config_real *lconf = (struct config_real *) conf;
07067
07068
07069 snprintf(buffer, sizeof(buffer), "%g", lconf->min);
07070 values[9] = pstrdup(buffer);
07071
07072
07073 snprintf(buffer, sizeof(buffer), "%g", lconf->max);
07074 values[10] = pstrdup(buffer);
07075
07076
07077 values[11] = NULL;
07078
07079
07080 snprintf(buffer, sizeof(buffer), "%g", lconf->boot_val);
07081 values[12] = pstrdup(buffer);
07082
07083
07084 snprintf(buffer, sizeof(buffer), "%g", lconf->reset_val);
07085 values[13] = pstrdup(buffer);
07086 }
07087 break;
07088
07089 case PGC_STRING:
07090 {
07091 struct config_string *lconf = (struct config_string *) conf;
07092
07093
07094 values[9] = NULL;
07095
07096
07097 values[10] = NULL;
07098
07099
07100 values[11] = NULL;
07101
07102
07103 if (lconf->boot_val == NULL)
07104 values[12] = NULL;
07105 else
07106 values[12] = pstrdup(lconf->boot_val);
07107
07108
07109 if (lconf->reset_val == NULL)
07110 values[13] = NULL;
07111 else
07112 values[13] = pstrdup(lconf->reset_val);
07113 }
07114 break;
07115
07116 case PGC_ENUM:
07117 {
07118 struct config_enum *lconf = (struct config_enum *) conf;
07119
07120
07121 values[9] = NULL;
07122
07123
07124 values[10] = NULL;
07125
07126
07127
07128
07129
07130
07131
07132 values[11] = config_enum_get_options((struct config_enum *) conf,
07133 "{\"", "\"}", "\",\"");
07134
07135
07136 values[12] = pstrdup(config_enum_lookup_by_value(lconf,
07137 lconf->boot_val));
07138
07139
07140 values[13] = pstrdup(config_enum_lookup_by_value(lconf,
07141 lconf->reset_val));
07142 }
07143 break;
07144
07145 default:
07146 {
07147
07148
07149
07150
07151
07152 values[9] = NULL;
07153
07154
07155 values[10] = NULL;
07156
07157
07158 values[11] = NULL;
07159
07160
07161 values[12] = NULL;
07162
07163
07164 values[13] = NULL;
07165 }
07166 break;
07167 }
07168
07169
07170
07171
07172
07173
07174 if (conf->source == PGC_S_FILE && superuser())
07175 {
07176 values[14] = conf->sourcefile;
07177 snprintf(buffer, sizeof(buffer), "%d", conf->sourceline);
07178 values[15] = pstrdup(buffer);
07179 }
07180 else
07181 {
07182 values[14] = NULL;
07183 values[15] = NULL;
07184 }
07185 }
07186
07187
07188
07189
07190 int
07191 GetNumConfigOptions(void)
07192 {
07193 return num_guc_variables;
07194 }
07195
07196
07197
07198
07199
07200 Datum
07201 show_config_by_name(PG_FUNCTION_ARGS)
07202 {
07203 char *varname;
07204 char *varval;
07205
07206
07207 varname = TextDatumGetCString(PG_GETARG_DATUM(0));
07208
07209
07210 varval = GetConfigOptionByName(varname, NULL);
07211
07212
07213 PG_RETURN_TEXT_P(cstring_to_text(varval));
07214 }
07215
07216
07217
07218
07219
07220 #define NUM_PG_SETTINGS_ATTS 16
07221
07222 Datum
07223 show_all_settings(PG_FUNCTION_ARGS)
07224 {
07225 FuncCallContext *funcctx;
07226 TupleDesc tupdesc;
07227 int call_cntr;
07228 int max_calls;
07229 AttInMetadata *attinmeta;
07230 MemoryContext oldcontext;
07231
07232
07233 if (SRF_IS_FIRSTCALL())
07234 {
07235
07236 funcctx = SRF_FIRSTCALL_INIT();
07237
07238
07239
07240
07241 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
07242
07243
07244
07245
07246
07247 tupdesc = CreateTemplateTupleDesc(NUM_PG_SETTINGS_ATTS, false);
07248 TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
07249 TEXTOID, -1, 0);
07250 TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting",
07251 TEXTOID, -1, 0);
07252 TupleDescInitEntry(tupdesc, (AttrNumber) 3, "unit",
07253 TEXTOID, -1, 0);
07254 TupleDescInitEntry(tupdesc, (AttrNumber) 4, "category",
07255 TEXTOID, -1, 0);
07256 TupleDescInitEntry(tupdesc, (AttrNumber) 5, "short_desc",
07257 TEXTOID, -1, 0);
07258 TupleDescInitEntry(tupdesc, (AttrNumber) 6, "extra_desc",
07259 TEXTOID, -1, 0);
07260 TupleDescInitEntry(tupdesc, (AttrNumber) 7, "context",
07261 TEXTOID, -1, 0);
07262 TupleDescInitEntry(tupdesc, (AttrNumber) 8, "vartype",
07263 TEXTOID, -1, 0);
07264 TupleDescInitEntry(tupdesc, (AttrNumber) 9, "source",
07265 TEXTOID, -1, 0);
07266 TupleDescInitEntry(tupdesc, (AttrNumber) 10, "min_val",
07267 TEXTOID, -1, 0);
07268 TupleDescInitEntry(tupdesc, (AttrNumber) 11, "max_val",
07269 TEXTOID, -1, 0);
07270 TupleDescInitEntry(tupdesc, (AttrNumber) 12, "enumvals",
07271 TEXTARRAYOID, -1, 0);
07272 TupleDescInitEntry(tupdesc, (AttrNumber) 13, "boot_val",
07273 TEXTOID, -1, 0);
07274 TupleDescInitEntry(tupdesc, (AttrNumber) 14, "reset_val",
07275 TEXTOID, -1, 0);
07276 TupleDescInitEntry(tupdesc, (AttrNumber) 15, "sourcefile",
07277 TEXTOID, -1, 0);
07278 TupleDescInitEntry(tupdesc, (AttrNumber) 16, "sourceline",
07279 INT4OID, -1, 0);
07280
07281
07282
07283
07284
07285 attinmeta = TupleDescGetAttInMetadata(tupdesc);
07286 funcctx->attinmeta = attinmeta;
07287
07288
07289 funcctx->max_calls = GetNumConfigOptions();
07290
07291 MemoryContextSwitchTo(oldcontext);
07292 }
07293
07294
07295 funcctx = SRF_PERCALL_SETUP();
07296
07297 call_cntr = funcctx->call_cntr;
07298 max_calls = funcctx->max_calls;
07299 attinmeta = funcctx->attinmeta;
07300
07301 if (call_cntr < max_calls)
07302 {
07303 char *values[NUM_PG_SETTINGS_ATTS];
07304 bool noshow;
07305 HeapTuple tuple;
07306 Datum result;
07307
07308
07309
07310
07311 do
07312 {
07313 GetConfigOptionByNum(call_cntr, (const char **) values, &noshow);
07314 if (noshow)
07315 {
07316
07317 call_cntr = ++funcctx->call_cntr;
07318
07319
07320 if (call_cntr >= max_calls)
07321 SRF_RETURN_DONE(funcctx);
07322 }
07323 } while (noshow);
07324
07325
07326 tuple = BuildTupleFromCStrings(attinmeta, values);
07327
07328
07329 result = HeapTupleGetDatum(tuple);
07330
07331 SRF_RETURN_NEXT(funcctx, result);
07332 }
07333 else
07334 {
07335
07336 SRF_RETURN_DONE(funcctx);
07337 }
07338 }
07339
07340 static char *
07341 _ShowOption(struct config_generic * record, bool use_units)
07342 {
07343 char buffer[256];
07344 const char *val;
07345
07346 switch (record->vartype)
07347 {
07348 case PGC_BOOL:
07349 {
07350 struct config_bool *conf = (struct config_bool *) record;
07351
07352 if (conf->show_hook)
07353 val = (*conf->show_hook) ();
07354 else
07355 val = *conf->variable ? "on" : "off";
07356 }
07357 break;
07358
07359 case PGC_INT:
07360 {
07361 struct config_int *conf = (struct config_int *) record;
07362
07363 if (conf->show_hook)
07364 val = (*conf->show_hook) ();
07365 else
07366 {
07367
07368
07369
07370
07371 int64 result = *conf->variable;
07372 const char *unit;
07373
07374 if (use_units && result > 0 &&
07375 (record->flags & GUC_UNIT_MEMORY))
07376 {
07377 switch (record->flags & GUC_UNIT_MEMORY)
07378 {
07379 case GUC_UNIT_BLOCKS:
07380 result *= BLCKSZ / 1024;
07381 break;
07382 case GUC_UNIT_XBLOCKS:
07383 result *= XLOG_BLCKSZ / 1024;
07384 break;
07385 }
07386
07387 if (result % KB_PER_GB == 0)
07388 {
07389 result /= KB_PER_GB;
07390 unit = "GB";
07391 }
07392 else if (result % KB_PER_MB == 0)
07393 {
07394 result /= KB_PER_MB;
07395 unit = "MB";
07396 }
07397 else
07398 {
07399 unit = "kB";
07400 }
07401 }
07402 else if (use_units && result > 0 &&
07403 (record->flags & GUC_UNIT_TIME))
07404 {
07405 switch (record->flags & GUC_UNIT_TIME)
07406 {
07407 case GUC_UNIT_S:
07408 result *= MS_PER_S;
07409 break;
07410 case GUC_UNIT_MIN:
07411 result *= MS_PER_MIN;
07412 break;
07413 }
07414
07415 if (result % MS_PER_D == 0)
07416 {
07417 result /= MS_PER_D;
07418 unit = "d";
07419 }
07420 else if (result % MS_PER_H == 0)
07421 {
07422 result /= MS_PER_H;
07423 unit = "h";
07424 }
07425 else if (result % MS_PER_MIN == 0)
07426 {
07427 result /= MS_PER_MIN;
07428 unit = "min";
07429 }
07430 else if (result % MS_PER_S == 0)
07431 {
07432 result /= MS_PER_S;
07433 unit = "s";
07434 }
07435 else
07436 {
07437 unit = "ms";
07438 }
07439 }
07440 else
07441 unit = "";
07442
07443 snprintf(buffer, sizeof(buffer), INT64_FORMAT "%s",
07444 result, unit);
07445 val = buffer;
07446 }
07447 }
07448 break;
07449
07450 case PGC_REAL:
07451 {
07452 struct config_real *conf = (struct config_real *) record;
07453
07454 if (conf->show_hook)
07455 val = (*conf->show_hook) ();
07456 else
07457 {
07458 snprintf(buffer, sizeof(buffer), "%g",
07459 *conf->variable);
07460 val = buffer;
07461 }
07462 }
07463 break;
07464
07465 case PGC_STRING:
07466 {
07467 struct config_string *conf = (struct config_string *) record;
07468
07469 if (conf->show_hook)
07470 val = (*conf->show_hook) ();
07471 else if (*conf->variable && **conf->variable)
07472 val = *conf->variable;
07473 else
07474 val = "";
07475 }
07476 break;
07477
07478 case PGC_ENUM:
07479 {
07480 struct config_enum *conf = (struct config_enum *) record;
07481
07482 if (conf->show_hook)
07483 val = (*conf->show_hook) ();
07484 else
07485 val = config_enum_lookup_by_value(conf, *conf->variable);
07486 }
07487 break;
07488
07489 default:
07490
07491 val = "???";
07492 break;
07493 }
07494
07495 return pstrdup(val);
07496 }
07497
07498
07499 #ifdef EXEC_BACKEND
07500
07501
07502
07503
07504
07505
07506
07507
07508
07509
07510
07511
07512 static void
07513 write_one_nondefault_variable(FILE *fp, struct config_generic * gconf)
07514 {
07515 if (gconf->source == PGC_S_DEFAULT)
07516 return;
07517
07518 fprintf(fp, "%s", gconf->name);
07519 fputc(0, fp);
07520
07521 switch (gconf->vartype)
07522 {
07523 case PGC_BOOL:
07524 {
07525 struct config_bool *conf = (struct config_bool *) gconf;
07526
07527 if (*conf->variable)
07528 fprintf(fp, "true");
07529 else
07530 fprintf(fp, "false");
07531 }
07532 break;
07533
07534 case PGC_INT:
07535 {
07536 struct config_int *conf = (struct config_int *) gconf;
07537
07538 fprintf(fp, "%d", *conf->variable);
07539 }
07540 break;
07541
07542 case PGC_REAL:
07543 {
07544 struct config_real *conf = (struct config_real *) gconf;
07545
07546 fprintf(fp, "%.17g", *conf->variable);
07547 }
07548 break;
07549
07550 case PGC_STRING:
07551 {
07552 struct config_string *conf = (struct config_string *) gconf;
07553
07554 fprintf(fp, "%s", *conf->variable);
07555 }
07556 break;
07557
07558 case PGC_ENUM:
07559 {
07560 struct config_enum *conf = (struct config_enum *) gconf;
07561
07562 fprintf(fp, "%s",
07563 config_enum_lookup_by_value(conf, *conf->variable));
07564 }
07565 break;
07566 }
07567
07568 fputc(0, fp);
07569
07570 if (gconf->sourcefile)
07571 fprintf(fp, "%s", gconf->sourcefile);
07572 fputc(0, fp);
07573
07574 fwrite(&gconf->sourceline, 1, sizeof(gconf->sourceline), fp);
07575 fwrite(&gconf->source, 1, sizeof(gconf->source), fp);
07576 fwrite(&gconf->scontext, 1, sizeof(gconf->scontext), fp);
07577 }
07578
07579 void
07580 write_nondefault_variables(GucContext context)
07581 {
07582 int elevel;
07583 FILE *fp;
07584 int i;
07585
07586 Assert(context == PGC_POSTMASTER || context == PGC_SIGHUP);
07587
07588 elevel = (context == PGC_SIGHUP) ? LOG : ERROR;
07589
07590
07591
07592
07593 fp = AllocateFile(CONFIG_EXEC_PARAMS_NEW, "w");
07594 if (!fp)
07595 {
07596 ereport(elevel,
07597 (errcode_for_file_access(),
07598 errmsg("could not write to file \"%s\": %m",
07599 CONFIG_EXEC_PARAMS_NEW)));
07600 return;
07601 }
07602
07603 for (i = 0; i < num_guc_variables; i++)
07604 {
07605 write_one_nondefault_variable(fp, guc_variables[i]);
07606 }
07607
07608 if (FreeFile(fp))
07609 {
07610 ereport(elevel,
07611 (errcode_for_file_access(),
07612 errmsg("could not write to file \"%s\": %m",
07613 CONFIG_EXEC_PARAMS_NEW)));
07614 return;
07615 }
07616
07617
07618
07619
07620
07621 rename(CONFIG_EXEC_PARAMS_NEW, CONFIG_EXEC_PARAMS);
07622 }
07623
07624
07625
07626
07627
07628
07629
07630 static char *
07631 read_string_with_null(FILE *fp)
07632 {
07633 int i = 0,
07634 ch,
07635 maxlen = 256;
07636 char *str = NULL;
07637
07638 do
07639 {
07640 if ((ch = fgetc(fp)) == EOF)
07641 {
07642 if (i == 0)
07643 return NULL;
07644 else
07645 elog(FATAL, "invalid format of exec config params file");
07646 }
07647 if (i == 0)
07648 str = guc_malloc(FATAL, maxlen);
07649 else if (i == maxlen)
07650 str = guc_realloc(FATAL, str, maxlen *= 2);
07651 str[i++] = ch;
07652 } while (ch != 0);
07653
07654 return str;
07655 }
07656
07657
07658
07659
07660
07661
07662 void
07663 read_nondefault_variables(void)
07664 {
07665 FILE *fp;
07666 char *varname,
07667 *varvalue,
07668 *varsourcefile;
07669 int varsourceline;
07670 GucSource varsource;
07671 GucContext varscontext;
07672
07673
07674
07675
07676 fp = AllocateFile(CONFIG_EXEC_PARAMS, "r");
07677 if (!fp)
07678 {
07679
07680 if (errno != ENOENT)
07681 ereport(FATAL,
07682 (errcode_for_file_access(),
07683 errmsg("could not read from file \"%s\": %m",
07684 CONFIG_EXEC_PARAMS)));
07685 return;
07686 }
07687
07688 for (;;)
07689 {
07690 struct config_generic *record;
07691
07692 if ((varname = read_string_with_null(fp)) == NULL)
07693 break;
07694
07695 if ((record = find_option(varname, true, FATAL)) == NULL)
07696 elog(FATAL, "failed to locate variable \"%s\" in exec config params file", varname);
07697
07698 if ((varvalue = read_string_with_null(fp)) == NULL)
07699 elog(FATAL, "invalid format of exec config params file");
07700 if ((varsourcefile = read_string_with_null(fp)) == NULL)
07701 elog(FATAL, "invalid format of exec config params file");
07702 if (fread(&varsourceline, 1, sizeof(varsourceline), fp) != sizeof(varsourceline))
07703 elog(FATAL, "invalid format of exec config params file");
07704 if (fread(&varsource, 1, sizeof(varsource), fp) != sizeof(varsource))
07705 elog(FATAL, "invalid format of exec config params file");
07706 if (fread(&varscontext, 1, sizeof(varscontext), fp) != sizeof(varscontext))
07707 elog(FATAL, "invalid format of exec config params file");
07708
07709 (void) set_config_option(varname, varvalue,
07710 varscontext, varsource,
07711 GUC_ACTION_SET, true, 0);
07712 if (varsourcefile[0])
07713 set_config_sourcefile(varname, varsourcefile, varsourceline);
07714
07715 free(varname);
07716 free(varvalue);
07717 free(varsourcefile);
07718 }
07719
07720 FreeFile(fp);
07721 }
07722 #endif
07723
07724
07725
07726
07727
07728
07729
07730
07731
07732 void
07733 ParseLongOption(const char *string, char **name, char **value)
07734 {
07735 size_t equal_pos;
07736 char *cp;
07737
07738 AssertArg(string);
07739 AssertArg(name);
07740 AssertArg(value);
07741
07742 equal_pos = strcspn(string, "=");
07743
07744 if (string[equal_pos] == '=')
07745 {
07746 *name = guc_malloc(FATAL, equal_pos + 1);
07747 strlcpy(*name, string, equal_pos + 1);
07748
07749 *value = guc_strdup(FATAL, &string[equal_pos + 1]);
07750 }
07751 else
07752 {
07753
07754 *name = guc_strdup(FATAL, string);
07755 *value = NULL;
07756 }
07757
07758 for (cp = *name; *cp; cp++)
07759 if (*cp == '-')
07760 *cp = '_';
07761 }
07762
07763
07764
07765
07766
07767
07768
07769
07770 void
07771 ProcessGUCArray(ArrayType *array,
07772 GucContext context, GucSource source, GucAction action)
07773 {
07774 int i;
07775
07776 Assert(array != NULL);
07777 Assert(ARR_ELEMTYPE(array) == TEXTOID);
07778 Assert(ARR_NDIM(array) == 1);
07779 Assert(ARR_LBOUND(array)[0] == 1);
07780
07781 for (i = 1; i <= ARR_DIMS(array)[0]; i++)
07782 {
07783 Datum d;
07784 bool isnull;
07785 char *s;
07786 char *name;
07787 char *value;
07788
07789 d = array_ref(array, 1, &i,
07790 -1 ,
07791 -1 ,
07792 false ,
07793 'i' ,
07794 &isnull);
07795
07796 if (isnull)
07797 continue;
07798
07799 s = TextDatumGetCString(d);
07800
07801 ParseLongOption(s, &name, &value);
07802 if (!value)
07803 {
07804 ereport(WARNING,
07805 (errcode(ERRCODE_SYNTAX_ERROR),
07806 errmsg("could not parse setting for parameter \"%s\"",
07807 name)));
07808 free(name);
07809 continue;
07810 }
07811
07812 (void) set_config_option(name, value,
07813 context, source,
07814 action, true, 0);
07815
07816 free(name);
07817 if (value)
07818 free(value);
07819 pfree(s);
07820 }
07821 }
07822
07823
07824
07825
07826
07827
07828 ArrayType *
07829 GUCArrayAdd(ArrayType *array, const char *name, const char *value)
07830 {
07831 struct config_generic *record;
07832 Datum datum;
07833 char *newval;
07834 ArrayType *a;
07835
07836 Assert(name);
07837 Assert(value);
07838
07839
07840 (void) validate_option_array_item(name, value, false);
07841
07842
07843 record = find_option(name, false, WARNING);
07844 if (record)
07845 name = record->name;
07846
07847
07848 newval = palloc(strlen(name) + 1 + strlen(value) + 1);
07849 sprintf(newval, "%s=%s", name, value);
07850 datum = CStringGetTextDatum(newval);
07851
07852 if (array)
07853 {
07854 int index;
07855 bool isnull;
07856 int i;
07857
07858 Assert(ARR_ELEMTYPE(array) == TEXTOID);
07859 Assert(ARR_NDIM(array) == 1);
07860 Assert(ARR_LBOUND(array)[0] == 1);
07861
07862 index = ARR_DIMS(array)[0] + 1;
07863
07864 for (i = 1; i <= ARR_DIMS(array)[0]; i++)
07865 {
07866 Datum d;
07867 char *current;
07868
07869 d = array_ref(array, 1, &i,
07870 -1 ,
07871 -1 ,
07872 false ,
07873 'i' ,
07874 &isnull);
07875 if (isnull)
07876 continue;
07877 current = TextDatumGetCString(d);
07878
07879
07880 if (strncmp(current, newval, strlen(name) + 1) == 0)
07881 {
07882 index = i;
07883 break;
07884 }
07885 }
07886
07887 a = array_set(array, 1, &index,
07888 datum,
07889 false,
07890 -1 ,
07891 -1 ,
07892 false ,
07893 'i' );
07894 }
07895 else
07896 a = construct_array(&datum, 1,
07897 TEXTOID,
07898 -1, false, 'i');
07899
07900 return a;
07901 }
07902
07903
07904
07905
07906
07907
07908
07909 ArrayType *
07910 GUCArrayDelete(ArrayType *array, const char *name)
07911 {
07912 struct config_generic *record;
07913 ArrayType *newarray;
07914 int i;
07915 int index;
07916
07917 Assert(name);
07918
07919
07920 (void) validate_option_array_item(name, NULL, false);
07921
07922
07923 record = find_option(name, false, WARNING);
07924 if (record)
07925 name = record->name;
07926
07927
07928 if (!array)
07929 return NULL;
07930
07931 newarray = NULL;
07932 index = 1;
07933
07934 for (i = 1; i <= ARR_DIMS(array)[0]; i++)
07935 {
07936 Datum d;
07937 char *val;
07938 bool isnull;
07939
07940 d = array_ref(array, 1, &i,
07941 -1 ,
07942 -1 ,
07943 false ,
07944 'i' ,
07945 &isnull);
07946 if (isnull)
07947 continue;
07948 val = TextDatumGetCString(d);
07949
07950
07951 if (strncmp(val, name, strlen(name)) == 0
07952 && val[strlen(name)] == '=')
07953 continue;
07954
07955
07956 if (newarray)
07957 newarray = array_set(newarray, 1, &index,
07958 d,
07959 false,
07960 -1 ,
07961 -1 ,
07962 false ,
07963 'i' );
07964 else
07965 newarray = construct_array(&d, 1,
07966 TEXTOID,
07967 -1, false, 'i');
07968
07969 index++;
07970 }
07971
07972 return newarray;
07973 }
07974
07975
07976
07977
07978
07979
07980
07981 ArrayType *
07982 GUCArrayReset(ArrayType *array)
07983 {
07984 ArrayType *newarray;
07985 int i;
07986 int index;
07987
07988
07989 if (!array)
07990 return NULL;
07991
07992
07993 if (superuser())
07994 return NULL;
07995
07996 newarray = NULL;
07997 index = 1;
07998
07999 for (i = 1; i <= ARR_DIMS(array)[0]; i++)
08000 {
08001 Datum d;
08002 char *val;
08003 char *eqsgn;
08004 bool isnull;
08005
08006 d = array_ref(array, 1, &i,
08007 -1 ,
08008 -1 ,
08009 false ,
08010 'i' ,
08011 &isnull);
08012 if (isnull)
08013 continue;
08014 val = TextDatumGetCString(d);
08015
08016 eqsgn = strchr(val, '=');
08017 *eqsgn = '\0';
08018
08019
08020 if (validate_option_array_item(val, NULL, true))
08021 continue;
08022
08023
08024 if (newarray)
08025 newarray = array_set(newarray, 1, &index,
08026 d,
08027 false,
08028 -1 ,
08029 -1 ,
08030 false ,
08031 'i' );
08032 else
08033 newarray = construct_array(&d, 1,
08034 TEXTOID,
08035 -1, false, 'i');
08036
08037 index++;
08038 pfree(val);
08039 }
08040
08041 return newarray;
08042 }
08043
08044
08045
08046
08047
08048
08049
08050
08051
08052
08053
08054
08055 static bool
08056 validate_option_array_item(const char *name, const char *value,
08057 bool skipIfNoPermissions)
08058
08059 {
08060 struct config_generic *gconf;
08061
08062
08063
08064
08065
08066
08067
08068
08069
08070
08071
08072
08073
08074
08075
08076
08077
08078
08079 gconf = find_option(name, true, WARNING);
08080 if (!gconf)
08081 {
08082
08083 if (skipIfNoPermissions)
08084 return false;
08085 ereport(ERROR,
08086 (errcode(ERRCODE_UNDEFINED_OBJECT),
08087 errmsg("unrecognized configuration parameter \"%s\"",
08088 name)));
08089 }
08090
08091 if (gconf->flags & GUC_CUSTOM_PLACEHOLDER)
08092 {
08093
08094
08095
08096
08097 if (superuser())
08098 return true;
08099 if (skipIfNoPermissions)
08100 return false;
08101 ereport(ERROR,
08102 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
08103 errmsg("permission denied to set parameter \"%s\"", name)));
08104 }
08105
08106
08107 if (gconf->context == PGC_USERSET)
08108 ;
08109 else if (gconf->context == PGC_SUSET && superuser())
08110 ;
08111 else if (skipIfNoPermissions)
08112 return false;
08113
08114
08115
08116 (void) set_config_option(name, value,
08117 superuser() ? PGC_SUSET : PGC_USERSET,
08118 PGC_S_TEST, GUC_ACTION_SET, false, 0);
08119
08120 return true;
08121 }
08122
08123
08124
08125
08126
08127
08128
08129
08130
08131
08132 void
08133 GUC_check_errcode(int sqlerrcode)
08134 {
08135 GUC_check_errcode_value = sqlerrcode;
08136 }
08137
08138
08139
08140
08141
08142
08143
08144
08145 static bool
08146 call_bool_check_hook(struct config_bool * conf, bool *newval, void **extra,
08147 GucSource source, int elevel)
08148 {
08149
08150 if (!conf->check_hook)
08151 return true;
08152
08153
08154 GUC_check_errcode_value = ERRCODE_INVALID_PARAMETER_VALUE;
08155 GUC_check_errmsg_string = NULL;
08156 GUC_check_errdetail_string = NULL;
08157 GUC_check_errhint_string = NULL;
08158
08159 if (!(*conf->check_hook) (newval, extra, source))
08160 {
08161 ereport(elevel,
08162 (errcode(GUC_check_errcode_value),
08163 GUC_check_errmsg_string ?
08164 errmsg_internal("%s", GUC_check_errmsg_string) :
08165 errmsg("invalid value for parameter \"%s\": %d",
08166 conf->gen.name, (int) *newval),
08167 GUC_check_errdetail_string ?
08168 errdetail_internal("%s", GUC_check_errdetail_string) : 0,
08169 GUC_check_errhint_string ?
08170 errhint("%s", GUC_check_errhint_string) : 0));
08171
08172 FlushErrorState();
08173 return false;
08174 }
08175
08176 return true;
08177 }
08178
08179 static bool
08180 call_int_check_hook(struct config_int * conf, int *newval, void **extra,
08181 GucSource source, int elevel)
08182 {
08183
08184 if (!conf->check_hook)
08185 return true;
08186
08187
08188 GUC_check_errcode_value = ERRCODE_INVALID_PARAMETER_VALUE;
08189 GUC_check_errmsg_string = NULL;
08190 GUC_check_errdetail_string = NULL;
08191 GUC_check_errhint_string = NULL;
08192
08193 if (!(*conf->check_hook) (newval, extra, source))
08194 {
08195 ereport(elevel,
08196 (errcode(GUC_check_errcode_value),
08197 GUC_check_errmsg_string ?
08198 errmsg_internal("%s", GUC_check_errmsg_string) :
08199 errmsg("invalid value for parameter \"%s\": %d",
08200 conf->gen.name, *newval),
08201 GUC_check_errdetail_string ?
08202 errdetail_internal("%s", GUC_check_errdetail_string) : 0,
08203 GUC_check_errhint_string ?
08204 errhint("%s", GUC_check_errhint_string) : 0));
08205
08206 FlushErrorState();
08207 return false;
08208 }
08209
08210 return true;
08211 }
08212
08213 static bool
08214 call_real_check_hook(struct config_real * conf, double *newval, void **extra,
08215 GucSource source, int elevel)
08216 {
08217
08218 if (!conf->check_hook)
08219 return true;
08220
08221
08222 GUC_check_errcode_value = ERRCODE_INVALID_PARAMETER_VALUE;
08223 GUC_check_errmsg_string = NULL;
08224 GUC_check_errdetail_string = NULL;
08225 GUC_check_errhint_string = NULL;
08226
08227 if (!(*conf->check_hook) (newval, extra, source))
08228 {
08229 ereport(elevel,
08230 (errcode(GUC_check_errcode_value),
08231 GUC_check_errmsg_string ?
08232 errmsg_internal("%s", GUC_check_errmsg_string) :
08233 errmsg("invalid value for parameter \"%s\": %g",
08234 conf->gen.name, *newval),
08235 GUC_check_errdetail_string ?
08236 errdetail_internal("%s", GUC_check_errdetail_string) : 0,
08237 GUC_check_errhint_string ?
08238 errhint("%s", GUC_check_errhint_string) : 0));
08239
08240 FlushErrorState();
08241 return false;
08242 }
08243
08244 return true;
08245 }
08246
08247 static bool
08248 call_string_check_hook(struct config_string * conf, char **newval, void **extra,
08249 GucSource source, int elevel)
08250 {
08251
08252 if (!conf->check_hook)
08253 return true;
08254
08255
08256 GUC_check_errcode_value = ERRCODE_INVALID_PARAMETER_VALUE;
08257 GUC_check_errmsg_string = NULL;
08258 GUC_check_errdetail_string = NULL;
08259 GUC_check_errhint_string = NULL;
08260
08261 if (!(*conf->check_hook) (newval, extra, source))
08262 {
08263 ereport(elevel,
08264 (errcode(GUC_check_errcode_value),
08265 GUC_check_errmsg_string ?
08266 errmsg_internal("%s", GUC_check_errmsg_string) :
08267 errmsg("invalid value for parameter \"%s\": \"%s\"",
08268 conf->gen.name, *newval ? *newval : ""),
08269 GUC_check_errdetail_string ?
08270 errdetail_internal("%s", GUC_check_errdetail_string) : 0,
08271 GUC_check_errhint_string ?
08272 errhint("%s", GUC_check_errhint_string) : 0));
08273
08274 FlushErrorState();
08275 return false;
08276 }
08277
08278 return true;
08279 }
08280
08281 static bool
08282 call_enum_check_hook(struct config_enum * conf, int *newval, void **extra,
08283 GucSource source, int elevel)
08284 {
08285
08286 if (!conf->check_hook)
08287 return true;
08288
08289
08290 GUC_check_errcode_value = ERRCODE_INVALID_PARAMETER_VALUE;
08291 GUC_check_errmsg_string = NULL;
08292 GUC_check_errdetail_string = NULL;
08293 GUC_check_errhint_string = NULL;
08294
08295 if (!(*conf->check_hook) (newval, extra, source))
08296 {
08297 ereport(elevel,
08298 (errcode(GUC_check_errcode_value),
08299 GUC_check_errmsg_string ?
08300 errmsg_internal("%s", GUC_check_errmsg_string) :
08301 errmsg("invalid value for parameter \"%s\": \"%s\"",
08302 conf->gen.name,
08303 config_enum_lookup_by_value(conf, *newval)),
08304 GUC_check_errdetail_string ?
08305 errdetail_internal("%s", GUC_check_errdetail_string) : 0,
08306 GUC_check_errhint_string ?
08307 errhint("%s", GUC_check_errhint_string) : 0));
08308
08309 FlushErrorState();
08310 return false;
08311 }
08312
08313 return true;
08314 }
08315
08316
08317
08318
08319
08320
08321 static bool
08322 check_log_destination(char **newval, void **extra, GucSource source)
08323 {
08324 char *rawstring;
08325 List *elemlist;
08326 ListCell *l;
08327 int newlogdest = 0;
08328 int *myextra;
08329
08330
08331 rawstring = pstrdup(*newval);
08332
08333
08334 if (!SplitIdentifierString(rawstring, ',', &elemlist))
08335 {
08336
08337 GUC_check_errdetail("List syntax is invalid.");
08338 pfree(rawstring);
08339 list_free(elemlist);
08340 return false;
08341 }
08342
08343 foreach(l, elemlist)
08344 {
08345 char *tok = (char *) lfirst(l);
08346
08347 if (pg_strcasecmp(tok, "stderr") == 0)
08348 newlogdest |= LOG_DESTINATION_STDERR;
08349 else if (pg_strcasecmp(tok, "csvlog") == 0)
08350 newlogdest |= LOG_DESTINATION_CSVLOG;
08351 #ifdef HAVE_SYSLOG
08352 else if (pg_strcasecmp(tok, "syslog") == 0)
08353 newlogdest |= LOG_DESTINATION_SYSLOG;
08354 #endif
08355 #ifdef WIN32
08356 else if (pg_strcasecmp(tok, "eventlog") == 0)
08357 newlogdest |= LOG_DESTINATION_EVENTLOG;
08358 #endif
08359 else
08360 {
08361 GUC_check_errdetail("Unrecognized key word: \"%s\".", tok);
08362 pfree(rawstring);
08363 list_free(elemlist);
08364 return false;
08365 }
08366 }
08367
08368 pfree(rawstring);
08369 list_free(elemlist);
08370
08371 myextra = (int *) guc_malloc(ERROR, sizeof(int));
08372 *myextra = newlogdest;
08373 *extra = (void *) myextra;
08374
08375 return true;
08376 }
08377
08378 static void
08379 assign_log_destination(const char *newval, void *extra)
08380 {
08381 Log_destination = *((int *) extra);
08382 }
08383
08384 static void
08385 assign_syslog_facility(int newval, void *extra)
08386 {
08387 #ifdef HAVE_SYSLOG
08388 set_syslog_parameters(syslog_ident_str ? syslog_ident_str : "postgres",
08389 newval);
08390 #endif
08391
08392 }
08393
08394 static void
08395 assign_syslog_ident(const char *newval, void *extra)
08396 {
08397 #ifdef HAVE_SYSLOG
08398 set_syslog_parameters(newval, syslog_facility);
08399 #endif
08400
08401 }
08402
08403
08404 static void
08405 assign_session_replication_role(int newval, void *extra)
08406 {
08407
08408
08409
08410
08411 if (SessionReplicationRole != newval)
08412 ResetPlanCache();
08413 }
08414
08415 static bool
08416 check_temp_buffers(int *newval, void **extra, GucSource source)
08417 {
08418
08419
08420
08421 if (NLocBuffer && NLocBuffer != *newval)
08422 {
08423 GUC_check_errdetail("\"temp_buffers\" cannot be changed after any temporary tables have been accessed in the session.");
08424 return false;
08425 }
08426 return true;
08427 }
08428
08429 static bool
08430 check_phony_autocommit(bool *newval, void **extra, GucSource source)
08431 {
08432 if (!*newval)
08433 {
08434 GUC_check_errcode(ERRCODE_FEATURE_NOT_SUPPORTED);
08435 GUC_check_errmsg("SET AUTOCOMMIT TO OFF is no longer supported");
08436 return false;
08437 }
08438 return true;
08439 }
08440
08441 static bool
08442 check_debug_assertions(bool *newval, void **extra, GucSource source)
08443 {
08444 #ifndef USE_ASSERT_CHECKING
08445 if (*newval)
08446 {
08447 GUC_check_errmsg("assertion checking is not supported by this build");
08448 return false;
08449 }
08450 #endif
08451 return true;
08452 }
08453
08454 static bool
08455 check_bonjour(bool *newval, void **extra, GucSource source)
08456 {
08457 #ifndef USE_BONJOUR
08458 if (*newval)
08459 {
08460 GUC_check_errmsg("Bonjour is not supported by this build");
08461 return false;
08462 }
08463 #endif
08464 return true;
08465 }
08466
08467 static bool
08468 check_ssl(bool *newval, void **extra, GucSource source)
08469 {
08470 #ifndef USE_SSL
08471 if (*newval)
08472 {
08473 GUC_check_errmsg("SSL is not supported by this build");
08474 return false;
08475 }
08476 #endif
08477 return true;
08478 }
08479
08480 static bool
08481 check_stage_log_stats(bool *newval, void **extra, GucSource source)
08482 {
08483 if (*newval && log_statement_stats)
08484 {
08485 GUC_check_errdetail("Cannot enable parameter when \"log_statement_stats\" is true.");
08486 return false;
08487 }
08488 return true;
08489 }
08490
08491 static bool
08492 check_log_stats(bool *newval, void **extra, GucSource source)
08493 {
08494 if (*newval &&
08495 (log_parser_stats || log_planner_stats || log_executor_stats))
08496 {
08497 GUC_check_errdetail("Cannot enable \"log_statement_stats\" when "
08498 "\"log_parser_stats\", \"log_planner_stats\", "
08499 "or \"log_executor_stats\" is true.");
08500 return false;
08501 }
08502 return true;
08503 }
08504
08505 static bool
08506 check_canonical_path(char **newval, void **extra, GucSource source)
08507 {
08508
08509
08510
08511
08512
08513 if (*newval)
08514 canonicalize_path(*newval);
08515 return true;
08516 }
08517
08518 static bool
08519 check_timezone_abbreviations(char **newval, void **extra, GucSource source)
08520 {
08521
08522
08523
08524
08525
08526
08527
08528
08529
08530
08531
08532 if (*newval == NULL)
08533 {
08534 Assert(source == PGC_S_DEFAULT);
08535 return true;
08536 }
08537
08538
08539 *extra = load_tzoffsets(*newval);
08540
08541
08542 if (!*extra)
08543 return false;
08544
08545 return true;
08546 }
08547
08548 static void
08549 assign_timezone_abbreviations(const char *newval, void *extra)
08550 {
08551
08552 if (!extra)
08553 return;
08554
08555 InstallTimeZoneAbbrevs((TimeZoneAbbrevTable *) extra);
08556 }
08557
08558
08559
08560
08561
08562
08563
08564
08565
08566
08567
08568 static void
08569 pg_timezone_abbrev_initialize(void)
08570 {
08571 SetConfigOption("timezone_abbreviations", "Default",
08572 PGC_POSTMASTER, PGC_S_DYNAMIC_DEFAULT);
08573 }
08574
08575 static const char *
08576 show_archive_command(void)
08577 {
08578 if (XLogArchivingActive())
08579 return XLogArchiveCommand;
08580 else
08581 return "(disabled)";
08582 }
08583
08584 static void
08585 assign_tcp_keepalives_idle(int newval, void *extra)
08586 {
08587
08588
08589
08590
08591
08592
08593
08594
08595
08596
08597
08598 (void) pq_setkeepalivesidle(newval, MyProcPort);
08599 }
08600
08601 static const char *
08602 show_tcp_keepalives_idle(void)
08603 {
08604
08605 static char nbuf[16];
08606
08607 snprintf(nbuf, sizeof(nbuf), "%d", pq_getkeepalivesidle(MyProcPort));
08608 return nbuf;
08609 }
08610
08611 static void
08612 assign_tcp_keepalives_interval(int newval, void *extra)
08613 {
08614
08615 (void) pq_setkeepalivesinterval(newval, MyProcPort);
08616 }
08617
08618 static const char *
08619 show_tcp_keepalives_interval(void)
08620 {
08621
08622 static char nbuf[16];
08623
08624 snprintf(nbuf, sizeof(nbuf), "%d", pq_getkeepalivesinterval(MyProcPort));
08625 return nbuf;
08626 }
08627
08628 static void
08629 assign_tcp_keepalives_count(int newval, void *extra)
08630 {
08631
08632 (void) pq_setkeepalivescount(newval, MyProcPort);
08633 }
08634
08635 static const char *
08636 show_tcp_keepalives_count(void)
08637 {
08638
08639 static char nbuf[16];
08640
08641 snprintf(nbuf, sizeof(nbuf), "%d", pq_getkeepalivescount(MyProcPort));
08642 return nbuf;
08643 }
08644
08645 static bool
08646 check_maxconnections(int *newval, void **extra, GucSource source)
08647 {
08648 if (*newval + GetNumShmemAttachedBgworkers() + autovacuum_max_workers + 1 >
08649 MAX_BACKENDS)
08650 return false;
08651 return true;
08652 }
08653
08654 static bool
08655 check_autovacuum_max_workers(int *newval, void **extra, GucSource source)
08656 {
08657 if (MaxConnections + *newval + 1 + GetNumShmemAttachedBgworkers() >
08658 MAX_BACKENDS)
08659 return false;
08660 return true;
08661 }
08662
08663 static bool
08664 check_effective_io_concurrency(int *newval, void **extra, GucSource source)
08665 {
08666 #ifdef USE_PREFETCH
08667 double new_prefetch_pages = 0.0;
08668 int i;
08669
08670
08671
08672
08673
08674
08675
08676
08677
08678
08679
08680
08681
08682
08683
08684
08685
08686
08687
08688
08689
08690
08691
08692
08693
08694
08695
08696
08697
08698
08699
08700
08701
08702
08703 for (i = 1; i <= *newval; i++)
08704 new_prefetch_pages += (double) *newval / (double) i;
08705
08706
08707 if (new_prefetch_pages >= 0.0 && new_prefetch_pages < (double) INT_MAX)
08708 {
08709 int *myextra = (int *) guc_malloc(ERROR, sizeof(int));
08710
08711 *myextra = (int) rint(new_prefetch_pages);
08712 *extra = (void *) myextra;
08713
08714 return true;
08715 }
08716 else
08717 return false;
08718 #else
08719 return true;
08720 #endif
08721 }
08722
08723 static void
08724 assign_effective_io_concurrency(int newval, void *extra)
08725 {
08726 #ifdef USE_PREFETCH
08727 target_prefetch_pages = *((int *) extra);
08728 #endif
08729 }
08730
08731 static void
08732 assign_pgstat_temp_directory(const char *newval, void *extra)
08733 {
08734
08735 char *dname;
08736 char *tname;
08737 char *fname;
08738
08739
08740 dname = guc_malloc(ERROR, strlen(newval) + 1);
08741 sprintf(dname, "%s", newval);
08742
08743
08744 tname = guc_malloc(ERROR, strlen(newval) + 12);
08745 sprintf(tname, "%s/global.tmp", newval);
08746 fname = guc_malloc(ERROR, strlen(newval) + 13);
08747 sprintf(fname, "%s/global.stat", newval);
08748
08749 if (pgstat_stat_directory)
08750 free(pgstat_stat_directory);
08751 pgstat_stat_directory = dname;
08752 if (pgstat_stat_tmpname)
08753 free(pgstat_stat_tmpname);
08754 pgstat_stat_tmpname = tname;
08755 if (pgstat_stat_filename)
08756 free(pgstat_stat_filename);
08757 pgstat_stat_filename = fname;
08758 }
08759
08760 static bool
08761 check_application_name(char **newval, void **extra, GucSource source)
08762 {
08763
08764 char *p;
08765
08766 for (p = *newval; *p; p++)
08767 {
08768 if (*p < 32 || *p > 126)
08769 *p = '?';
08770 }
08771
08772 return true;
08773 }
08774
08775 static void
08776 assign_application_name(const char *newval, void *extra)
08777 {
08778
08779 pgstat_report_appname(newval);
08780 }
08781
08782 static const char *
08783 show_unix_socket_permissions(void)
08784 {
08785 static char buf[8];
08786
08787 snprintf(buf, sizeof(buf), "%04o", Unix_socket_permissions);
08788 return buf;
08789 }
08790
08791 static const char *
08792 show_log_file_mode(void)
08793 {
08794 static char buf[8];
08795
08796 snprintf(buf, sizeof(buf), "%04o", Log_file_mode);
08797 return buf;
08798 }
08799
08800 #include "guc-file.c"