From 3e1e6219c6db94e3c69a8c5cddd6c9ab4b3aa848 Mon Sep 17 00:00:00 2001 From: David Christensen Date: Thu, 19 Aug 2021 14:33:15 -0500 Subject: [PATCH] POC: use sentinel values for parsing/outputting "special" int GUCs Some GUCs include specific key values like "-1", etc, which have context beyond the actual value involved. Add support for providing synonyms for these values on input/output which make things a lot easier to understand. Add a new GUC output_special_values to enable the change of behavior on output; by default we leave this alone, as there may be tools parsing/using these values as they currently output. As far as I know, this "magic values" really only exists for ints; we can expand things similarly for other types if the need arises. For now, a non-exhaustive pass has been done through the config_int options list to identify likely/needed values. This will probably need to be tightened up in the future. This code supports multiple values; it will stop at the first parsed found value and use that int value. --- src/backend/utils/misc/guc.c | 376 ++++++++++++++++++++---------- src/include/utils/guc_tables.h | 1 + src/test/regress/expected/guc.out | 45 ++++ src/test/regress/sql/guc.sql | 16 ++ 4 files changed, 309 insertions(+), 129 deletions(-) diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 6fc5cbc09a..3f10fef244 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -236,6 +236,9 @@ static void assign_recovery_target_lsn(const char *newval, void *extra); static bool check_primary_slot_name(char **newval, void **extra, GucSource source); static bool check_default_with_oids(bool *newval, void **extra, GucSource source); +static bool parse_special_int(const struct config_enum_entry *options, const char *value, int *result); +static bool special_int_to_value(const struct config_enum_entry *options, int value, const char **retval); + /* Private functions in guc-file.l that need to be called from guc.c */ static ConfigVariable *ProcessConfigFileInternal(GucContext context, bool applySettings, int elevel); @@ -566,6 +569,57 @@ extern const struct config_enum_entry recovery_target_action_options[]; extern const struct config_enum_entry sync_method_options[]; extern const struct config_enum_entry dynamic_shared_memory_options[]; +/* Some static structs for use in options which have -1 as special values; + * example: "disabled" or "inherited". While these are not enums per se, we + * are reusing the struct, with the bool field indicating whether to print the + * translated values on output */ + +static const struct config_enum_entry special_auto[] = { + {"auto", -1, false}, + {NULL, 0, false} +}; + +static const struct config_enum_entry special_disabled[] = { + {"disabled", -1, false}, + {NULL, 0, false} +}; + +static const struct config_enum_entry special_disabled0[] = { + {"disabled", 0, false}, + {NULL, 0, false} +}; + +static const struct config_enum_entry special_disabled_all[] = { + {"disabled", -1, false}, + {"all", 0, false}, + {NULL, 0, false} +}; + +static const struct config_enum_entry special_default0[] = { + {"default", 0, false}, + {NULL, 0, false} +}; + +static const struct config_enum_entry special_immediate0[] = { + {"immediate", 0, false}, + {NULL, 0, false} +}; + +static const struct config_enum_entry special_none0[] = { + {"none", 0, false}, + {NULL, 0, false} +}; + +static const struct config_enum_entry special_unlimited[] = { + {"unlimited", -1, false}, + {NULL, 0, false} +}; + +static const struct config_enum_entry special_unlimited0[] = { + {"unlimited", 0, false}, + {NULL, 0, false} +}; + /* * GUC option variables that are exported from this module */ @@ -593,6 +647,8 @@ bool check_function_bodies = true; bool default_with_oids = false; bool session_auth_is_superuser; +bool output_special_values = false; + int log_min_error_statement = ERROR; int log_min_messages = WARNING; int client_min_messages = NOTICE; @@ -2120,6 +2176,15 @@ static struct config_bool ConfigureNamesBool[] = NULL, NULL, NULL }, + { + {"output_special_values", PGC_USERSET, CLIENT_CONN_OTHER, + gettext_noop("Whether to display \"special\" values in settings display."), + }, + &output_special_values, + false, + NULL, NULL, NULL + }, + /* End-of-list marker */ { {NULL, 0, 0, NULL, NULL}, NULL, false, NULL, NULL, NULL @@ -2138,7 +2203,7 @@ static struct config_int ConfigureNamesInt[] = }, &XLogArchiveTimeout, 0, 0, INT_MAX / 2, - NULL, NULL, NULL + NULL, NULL, NULL, special_disabled0 }, { {"post_auth_delay", PGC_BACKEND, DEVELOPER_OPTIONS, @@ -2149,7 +2214,7 @@ static struct config_int ConfigureNamesInt[] = }, &PostAuthDelay, 0, 0, INT_MAX / 1000000, - NULL, NULL, NULL + NULL, NULL, NULL, special_disabled0 }, { {"default_statistics_target", PGC_USERSET, QUERY_TUNING_OTHER, @@ -2159,7 +2224,7 @@ static struct config_int ConfigureNamesInt[] = }, &default_statistics_target, 100, 1, 10000, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { {"from_collapse_limit", PGC_USERSET, QUERY_TUNING_OTHER, @@ -2172,7 +2237,7 @@ static struct config_int ConfigureNamesInt[] = }, &from_collapse_limit, 8, 1, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { {"join_collapse_limit", PGC_USERSET, QUERY_TUNING_OTHER, @@ -2185,7 +2250,7 @@ static struct config_int ConfigureNamesInt[] = }, &join_collapse_limit, 8, 1, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { {"geqo_threshold", PGC_USERSET, QUERY_TUNING_GEQO, @@ -2195,7 +2260,7 @@ static struct config_int ConfigureNamesInt[] = }, &geqo_threshold, 12, 2, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { {"geqo_effort", PGC_USERSET, QUERY_TUNING_GEQO, @@ -2205,7 +2270,7 @@ static struct config_int ConfigureNamesInt[] = }, &Geqo_effort, DEFAULT_GEQO_EFFORT, MIN_GEQO_EFFORT, MAX_GEQO_EFFORT, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { {"geqo_pool_size", PGC_USERSET, QUERY_TUNING_GEQO, @@ -2215,7 +2280,7 @@ static struct config_int ConfigureNamesInt[] = }, &Geqo_pool_size, 0, 0, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { {"geqo_generations", PGC_USERSET, QUERY_TUNING_GEQO, @@ -2225,7 +2290,7 @@ static struct config_int ConfigureNamesInt[] = }, &Geqo_generations, 0, 0, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -2237,7 +2302,7 @@ static struct config_int ConfigureNamesInt[] = }, &DeadlockTimeout, 1000, 1, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -2248,7 +2313,7 @@ static struct config_int ConfigureNamesInt[] = }, &max_standby_archive_delay, 30 * 1000, -1, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, special_unlimited }, { @@ -2259,7 +2324,7 @@ static struct config_int ConfigureNamesInt[] = }, &max_standby_streaming_delay, 30 * 1000, -1, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, special_unlimited }, { @@ -2270,7 +2335,7 @@ static struct config_int ConfigureNamesInt[] = }, &recovery_min_apply_delay, 0, 0, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -2281,7 +2346,7 @@ static struct config_int ConfigureNamesInt[] = }, &wal_receiver_status_interval, 10, 0, INT_MAX / 1000, - NULL, NULL, NULL + NULL, NULL, NULL, special_disabled0 }, { @@ -2292,7 +2357,7 @@ static struct config_int ConfigureNamesInt[] = }, &wal_receiver_timeout, 60 * 1000, 0, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, special_disabled0 }, { @@ -2302,7 +2367,7 @@ static struct config_int ConfigureNamesInt[] = }, &MaxConnections, 100, 1, MAX_BACKENDS, - check_maxconnections, NULL, NULL + check_maxconnections, NULL, NULL, NULL }, { @@ -2313,7 +2378,7 @@ static struct config_int ConfigureNamesInt[] = }, &ReservedBackends, 3, 0, MAX_BACKENDS, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -2324,7 +2389,7 @@ static struct config_int ConfigureNamesInt[] = }, &min_dynamic_shared_memory, 0, 0, (int) Min((size_t) INT_MAX, SIZE_MAX / (1024 * 1024)), - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, /* @@ -2339,7 +2404,7 @@ static struct config_int ConfigureNamesInt[] = }, &NBuffers, 16384, 16, INT_MAX / 2, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -2350,7 +2415,7 @@ static struct config_int ConfigureNamesInt[] = }, &shared_memory_size_mb, 0, 0, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -2372,7 +2437,7 @@ static struct config_int ConfigureNamesInt[] = }, &num_temp_buffers, 1024, 100, INT_MAX / 2, - check_temp_buffers, NULL, NULL + check_temp_buffers, NULL, NULL, NULL }, { @@ -2382,7 +2447,7 @@ static struct config_int ConfigureNamesInt[] = }, &PostPortNumber, DEF_PGPORT, 1, 65535, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -2397,7 +2462,7 @@ static struct config_int ConfigureNamesInt[] = }, &Unix_socket_permissions, 0777, 0000, 0777, - NULL, NULL, show_unix_socket_permissions + NULL, NULL, show_unix_socket_permissions, NULL }, { @@ -2411,7 +2476,7 @@ static struct config_int ConfigureNamesInt[] = }, &Log_file_mode, 0600, 0000, 0777, - NULL, NULL, show_log_file_mode + NULL, NULL, show_log_file_mode, NULL }, @@ -2426,7 +2491,7 @@ static struct config_int ConfigureNamesInt[] = }, &data_directory_mode, 0700, 0000, 0777, - NULL, NULL, show_data_directory_mode + NULL, NULL, show_data_directory_mode, NULL }, { @@ -2439,7 +2504,7 @@ static struct config_int ConfigureNamesInt[] = }, &work_mem, 4096, 64, MAX_KILOBYTES, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -2450,7 +2515,7 @@ static struct config_int ConfigureNamesInt[] = }, &maintenance_work_mem, 65536, 1024, MAX_KILOBYTES, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -2462,7 +2527,7 @@ static struct config_int ConfigureNamesInt[] = }, &logical_decoding_work_mem, 65536, 64, MAX_KILOBYTES, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, /* @@ -2478,7 +2543,7 @@ static struct config_int ConfigureNamesInt[] = }, &max_stack_depth, 100, 100, MAX_KILOBYTES, - check_max_stack_depth, assign_max_stack_depth, NULL + check_max_stack_depth, assign_max_stack_depth, NULL, NULL }, { @@ -2489,7 +2554,7 @@ static struct config_int ConfigureNamesInt[] = }, &temp_file_limit, -1, -1, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, special_unlimited }, { @@ -2499,7 +2564,7 @@ static struct config_int ConfigureNamesInt[] = }, &VacuumCostPageHit, 1, 0, 10000, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -2509,7 +2574,7 @@ static struct config_int ConfigureNamesInt[] = }, &VacuumCostPageMiss, 2, 0, 10000, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -2519,7 +2584,7 @@ static struct config_int ConfigureNamesInt[] = }, &VacuumCostPageDirty, 20, 0, 10000, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -2529,7 +2594,7 @@ static struct config_int ConfigureNamesInt[] = }, &VacuumCostLimit, 200, 1, 10000, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -2539,7 +2604,7 @@ static struct config_int ConfigureNamesInt[] = }, &autovacuum_vac_cost_limit, -1, -1, 10000, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -2549,7 +2614,7 @@ static struct config_int ConfigureNamesInt[] = }, &max_files_per_process, 1000, 64, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, /* @@ -2562,7 +2627,7 @@ static struct config_int ConfigureNamesInt[] = }, &max_prepared_xacts, 0, 0, MAX_BACKENDS, - NULL, NULL, NULL + NULL, NULL, NULL, special_disabled0 }, #ifdef LOCK_DEBUG @@ -2574,7 +2639,7 @@ static struct config_int ConfigureNamesInt[] = }, &Trace_lock_oidmin, FirstNormalObjectId, 0, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { {"trace_lock_table", PGC_SUSET, DEVELOPER_OPTIONS, @@ -2584,7 +2649,7 @@ static struct config_int ConfigureNamesInt[] = }, &Trace_lock_table, 0, 0, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, #endif @@ -2596,7 +2661,7 @@ static struct config_int ConfigureNamesInt[] = }, &StatementTimeout, 0, 0, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, special_unlimited0 }, { @@ -2607,7 +2672,7 @@ static struct config_int ConfigureNamesInt[] = }, &LockTimeout, 0, 0, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, special_unlimited0 }, { @@ -2618,7 +2683,7 @@ static struct config_int ConfigureNamesInt[] = }, &IdleInTransactionSessionTimeout, 0, 0, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, special_unlimited0 }, { @@ -2629,7 +2694,7 @@ static struct config_int ConfigureNamesInt[] = }, &IdleSessionTimeout, 0, 0, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, special_unlimited0 }, { @@ -2639,7 +2704,7 @@ static struct config_int ConfigureNamesInt[] = }, &vacuum_freeze_min_age, 50000000, 0, 1000000000, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -2649,7 +2714,7 @@ static struct config_int ConfigureNamesInt[] = }, &vacuum_freeze_table_age, 150000000, 0, 2000000000, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -2659,7 +2724,7 @@ static struct config_int ConfigureNamesInt[] = }, &vacuum_multixact_freeze_min_age, 5000000, 0, 1000000000, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -2669,7 +2734,7 @@ static struct config_int ConfigureNamesInt[] = }, &vacuum_multixact_freeze_table_age, 150000000, 0, 2000000000, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -2679,7 +2744,7 @@ static struct config_int ConfigureNamesInt[] = }, &vacuum_defer_cleanup_age, 0, 0, 1000000, /* see ComputeXidHorizons */ - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { {"vacuum_failsafe_age", PGC_USERSET, CLIENT_CONN_STATEMENT, @@ -2688,7 +2753,7 @@ static struct config_int ConfigureNamesInt[] = }, &vacuum_failsafe_age, 1600000000, 0, 2100000000, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { {"vacuum_multixact_failsafe_age", PGC_USERSET, CLIENT_CONN_STATEMENT, @@ -2697,7 +2762,7 @@ static struct config_int ConfigureNamesInt[] = }, &vacuum_multixact_failsafe_age, 1600000000, 0, 2100000000, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, /* @@ -2712,7 +2777,7 @@ static struct config_int ConfigureNamesInt[] = }, &max_locks_per_xact, 64, 10, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -2724,7 +2789,7 @@ static struct config_int ConfigureNamesInt[] = }, &max_predicate_locks_per_xact, 64, 10, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -2735,7 +2800,7 @@ static struct config_int ConfigureNamesInt[] = }, &max_predicate_locks_per_relation, -2, INT_MIN, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -2746,7 +2811,7 @@ static struct config_int ConfigureNamesInt[] = }, &max_predicate_locks_per_page, 2, 0, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -2757,7 +2822,7 @@ static struct config_int ConfigureNamesInt[] = }, &AuthenticationTimeout, 60, 1, 600, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -2770,7 +2835,7 @@ static struct config_int ConfigureNamesInt[] = }, &PreAuthDelay, 0, 0, 60, - NULL, NULL, NULL + NULL, NULL, NULL, special_disabled0 }, { @@ -2781,7 +2846,7 @@ static struct config_int ConfigureNamesInt[] = }, &wal_keep_size_mb, 0, 0, MAX_KILOBYTES, - NULL, NULL, NULL + NULL, NULL, NULL, special_none0 }, { @@ -2793,7 +2858,7 @@ static struct config_int ConfigureNamesInt[] = &min_wal_size_mb, DEFAULT_MIN_WAL_SEGS * (DEFAULT_XLOG_SEG_SIZE / (1024 * 1024)), 2, MAX_KILOBYTES, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -2805,7 +2870,7 @@ static struct config_int ConfigureNamesInt[] = &max_wal_size_mb, DEFAULT_MAX_WAL_SEGS * (DEFAULT_XLOG_SEG_SIZE / (1024 * 1024)), 2, MAX_KILOBYTES, - NULL, assign_max_wal_size, NULL + NULL, assign_max_wal_size, NULL, NULL }, { @@ -2816,7 +2881,7 @@ static struct config_int ConfigureNamesInt[] = }, &CheckPointTimeout, 300, 30, 86400, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -2831,7 +2896,7 @@ static struct config_int ConfigureNamesInt[] = }, &CheckPointWarning, 30, 0, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, special_disabled0 }, { @@ -2842,7 +2907,7 @@ static struct config_int ConfigureNamesInt[] = }, &checkpoint_flush_after, DEFAULT_CHECKPOINT_FLUSH_AFTER, 0, WRITEBACK_MAX_PENDING_FLUSHES, - NULL, NULL, NULL + NULL, NULL, NULL, special_disabled0 }, { @@ -2853,7 +2918,7 @@ static struct config_int ConfigureNamesInt[] = }, &XLOGbuffers, -1, -1, (INT_MAX / XLOG_BLCKSZ), - check_wal_buffers, NULL, NULL + check_wal_buffers, NULL, NULL, special_auto }, { @@ -2864,7 +2929,7 @@ static struct config_int ConfigureNamesInt[] = }, &WalWriterDelay, 200, 1, 10000, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -2875,7 +2940,7 @@ static struct config_int ConfigureNamesInt[] = }, &WalWriterFlushAfter, (1024 * 1024) / XLOG_BLCKSZ, 0, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, special_immediate0 }, { @@ -2886,7 +2951,7 @@ static struct config_int ConfigureNamesInt[] = }, &wal_skip_threshold, 2048, 0, MAX_KILOBYTES, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -2896,7 +2961,7 @@ static struct config_int ConfigureNamesInt[] = }, &max_wal_senders, 10, 0, MAX_BACKENDS, - check_max_wal_senders, NULL, NULL + check_max_wal_senders, NULL, NULL, NULL }, { @@ -2907,7 +2972,7 @@ static struct config_int ConfigureNamesInt[] = }, &max_replication_slots, 10, 0, MAX_BACKENDS /* XXX? */ , - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -2920,7 +2985,7 @@ static struct config_int ConfigureNamesInt[] = }, &max_slot_wal_keep_size_mb, -1, -1, MAX_KILOBYTES, - NULL, NULL, NULL + NULL, NULL, NULL, special_unlimited }, { @@ -2931,7 +2996,7 @@ static struct config_int ConfigureNamesInt[] = }, &wal_sender_timeout, 60 * 1000, 0, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, special_disabled0 }, { @@ -2943,7 +3008,7 @@ static struct config_int ConfigureNamesInt[] = }, &CommitDelay, 0, 0, 100000, - NULL, NULL, NULL + NULL, NULL, NULL, special_none0 }, { @@ -2954,7 +3019,7 @@ static struct config_int ConfigureNamesInt[] = }, &CommitSiblings, 5, 0, 1000, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -2967,7 +3032,7 @@ static struct config_int ConfigureNamesInt[] = }, &extra_float_digits, 1, -15, 3, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -2980,7 +3045,7 @@ static struct config_int ConfigureNamesInt[] = }, &log_min_duration_sample, -1, -1, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, special_disabled_all }, { @@ -2992,7 +3057,7 @@ static struct config_int ConfigureNamesInt[] = }, &log_min_duration_statement, -1, -1, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, special_disabled_all }, { @@ -3004,7 +3069,7 @@ static struct config_int ConfigureNamesInt[] = }, &Log_autovacuum_min_duration, 600000, -1, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, special_disabled_all }, { @@ -3016,7 +3081,7 @@ static struct config_int ConfigureNamesInt[] = }, &log_parameter_max_length, -1, -1, INT_MAX / 2, - NULL, NULL, NULL + NULL, NULL, NULL, special_unlimited }, { @@ -3028,7 +3093,7 @@ static struct config_int ConfigureNamesInt[] = }, &log_parameter_max_length_on_error, 0, -1, INT_MAX / 2, - NULL, NULL, NULL + NULL, NULL, NULL, special_unlimited }, { @@ -3039,7 +3104,7 @@ static struct config_int ConfigureNamesInt[] = }, &BgWriterDelay, 200, 10, 10000, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -3049,7 +3114,7 @@ static struct config_int ConfigureNamesInt[] = }, &bgwriter_lru_maxpages, 100, 0, INT_MAX / 2, /* Same upper limit as shared_buffers */ - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -3060,7 +3125,7 @@ static struct config_int ConfigureNamesInt[] = }, &bgwriter_flush_after, DEFAULT_BGWRITER_FLUSH_AFTER, 0, WRITEBACK_MAX_PENDING_FLUSHES, - NULL, NULL, NULL + NULL, NULL, NULL, special_disabled0 }, { @@ -3078,7 +3143,7 @@ static struct config_int ConfigureNamesInt[] = 0, #endif 0, MAX_IO_CONCURRENCY, - check_effective_io_concurrency, NULL, NULL + check_effective_io_concurrency, NULL, NULL, special_disabled0 }, { @@ -3096,7 +3161,7 @@ static struct config_int ConfigureNamesInt[] = 0, #endif 0, MAX_IO_CONCURRENCY, - check_maintenance_io_concurrency, NULL, NULL + check_maintenance_io_concurrency, NULL, NULL, NULL }, { @@ -3107,7 +3172,7 @@ static struct config_int ConfigureNamesInt[] = }, &backend_flush_after, DEFAULT_BACKEND_FLUSH_AFTER, 0, WRITEBACK_MAX_PENDING_FLUSHES, - NULL, NULL, NULL + NULL, NULL, NULL, special_disabled0 }, { @@ -3119,7 +3184,7 @@ static struct config_int ConfigureNamesInt[] = }, &max_worker_processes, 8, 0, MAX_BACKENDS, - check_max_worker_processes, NULL, NULL + check_max_worker_processes, NULL, NULL, special_disabled0 }, { @@ -3131,7 +3196,7 @@ static struct config_int ConfigureNamesInt[] = }, &max_logical_replication_workers, 4, 0, MAX_BACKENDS, - NULL, NULL, NULL + NULL, NULL, NULL, special_disabled0 }, { @@ -3143,7 +3208,7 @@ static struct config_int ConfigureNamesInt[] = }, &max_sync_workers_per_subscription, 2, 0, MAX_BACKENDS, - NULL, NULL, NULL + NULL, NULL, NULL, special_disabled0 }, { @@ -3155,7 +3220,7 @@ static struct config_int ConfigureNamesInt[] = }, &Log_RotationAge, HOURS_PER_DAY * MINS_PER_HOUR, 0, INT_MAX / SECS_PER_MINUTE, - NULL, NULL, NULL + NULL, NULL, NULL, special_disabled0 }, { @@ -3167,7 +3232,7 @@ static struct config_int ConfigureNamesInt[] = }, &Log_RotationSize, 10 * 1024, 0, INT_MAX / 1024, - NULL, NULL, NULL + NULL, NULL, NULL, special_disabled0 }, { @@ -3178,7 +3243,7 @@ static struct config_int ConfigureNamesInt[] = }, &max_function_args, FUNC_MAX_ARGS, FUNC_MAX_ARGS, FUNC_MAX_ARGS, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -3189,7 +3254,7 @@ static struct config_int ConfigureNamesInt[] = }, &max_index_keys, INDEX_MAX_KEYS, INDEX_MAX_KEYS, INDEX_MAX_KEYS, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -3200,7 +3265,7 @@ static struct config_int ConfigureNamesInt[] = }, &max_identifier_length, NAMEDATALEN - 1, NAMEDATALEN - 1, NAMEDATALEN - 1, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -3211,7 +3276,7 @@ static struct config_int ConfigureNamesInt[] = }, &block_size, BLCKSZ, BLCKSZ, BLCKSZ, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -3222,7 +3287,7 @@ static struct config_int ConfigureNamesInt[] = }, &segment_size, RELSEG_SIZE, RELSEG_SIZE, RELSEG_SIZE, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -3233,7 +3298,7 @@ static struct config_int ConfigureNamesInt[] = }, &wal_block_size, XLOG_BLCKSZ, XLOG_BLCKSZ, XLOG_BLCKSZ, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -3245,7 +3310,7 @@ static struct config_int ConfigureNamesInt[] = }, &wal_retrieve_retry_interval, 5000, 1, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -3258,7 +3323,7 @@ static struct config_int ConfigureNamesInt[] = DEFAULT_XLOG_SEG_SIZE, WalSegMinSize, WalSegMaxSize, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -3269,7 +3334,7 @@ static struct config_int ConfigureNamesInt[] = }, &autovacuum_naptime, 60, 1, INT_MAX / 1000, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { {"autovacuum_vacuum_threshold", PGC_SIGHUP, AUTOVACUUM, @@ -3278,7 +3343,7 @@ static struct config_int ConfigureNamesInt[] = }, &autovacuum_vac_thresh, 50, 0, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { {"autovacuum_vacuum_insert_threshold", PGC_SIGHUP, AUTOVACUUM, @@ -3287,7 +3352,7 @@ static struct config_int ConfigureNamesInt[] = }, &autovacuum_vac_ins_thresh, 1000, -1, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, special_disabled }, { {"autovacuum_analyze_threshold", PGC_SIGHUP, AUTOVACUUM, @@ -3296,7 +3361,7 @@ static struct config_int ConfigureNamesInt[] = }, &autovacuum_anl_thresh, 50, 0, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { /* see varsup.c for why this is PGC_POSTMASTER not PGC_SIGHUP */ @@ -3308,7 +3373,7 @@ static struct config_int ConfigureNamesInt[] = /* see vacuum_failsafe_age if you change the upper-limit value. */ 200000000, 100000, 2000000000, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { /* see multixact.c for why this is PGC_POSTMASTER not PGC_SIGHUP */ @@ -3318,7 +3383,7 @@ static struct config_int ConfigureNamesInt[] = }, &autovacuum_multixact_freeze_max_age, 400000000, 10000, 2000000000, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { /* see max_connections */ @@ -3328,7 +3393,7 @@ static struct config_int ConfigureNamesInt[] = }, &autovacuum_max_workers, 3, 1, MAX_BACKENDS, - check_autovacuum_max_workers, NULL, NULL + check_autovacuum_max_workers, NULL, NULL, NULL }, { @@ -3338,7 +3403,7 @@ static struct config_int ConfigureNamesInt[] = }, &max_parallel_maintenance_workers, 2, 0, 1024, - NULL, NULL, NULL + NULL, NULL, NULL, special_disabled0 }, { @@ -3349,7 +3414,7 @@ static struct config_int ConfigureNamesInt[] = }, &max_parallel_workers_per_gather, 2, 0, MAX_PARALLEL_WORKER_LIMIT, - NULL, NULL, NULL + NULL, NULL, NULL, special_disabled0 }, { @@ -3360,7 +3425,7 @@ static struct config_int ConfigureNamesInt[] = }, &max_parallel_workers, 8, 0, MAX_PARALLEL_WORKER_LIMIT, - NULL, NULL, NULL + NULL, NULL, NULL, special_disabled0 }, { @@ -3371,7 +3436,7 @@ static struct config_int ConfigureNamesInt[] = }, &autovacuum_work_mem, -1, -1, MAX_KILOBYTES, - check_autovacuum_work_mem, NULL, NULL + check_autovacuum_work_mem, NULL, NULL, NULL }, { @@ -3382,7 +3447,7 @@ static struct config_int ConfigureNamesInt[] = }, &old_snapshot_threshold, -1, -1, MINS_PER_HOUR * HOURS_PER_DAY * 60, - NULL, NULL, NULL + NULL, NULL, NULL, special_disabled }, { @@ -3393,7 +3458,7 @@ static struct config_int ConfigureNamesInt[] = }, &tcp_keepalives_idle, 0, 0, INT_MAX, - NULL, assign_tcp_keepalives_idle, show_tcp_keepalives_idle + NULL, assign_tcp_keepalives_idle, show_tcp_keepalives_idle, special_default0 }, { @@ -3404,7 +3469,7 @@ static struct config_int ConfigureNamesInt[] = }, &tcp_keepalives_interval, 0, 0, INT_MAX, - NULL, assign_tcp_keepalives_interval, show_tcp_keepalives_interval + NULL, assign_tcp_keepalives_interval, show_tcp_keepalives_interval, special_default0 }, { @@ -3415,7 +3480,7 @@ static struct config_int ConfigureNamesInt[] = }, &ssl_renegotiation_limit, 0, 0, 0, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -3427,7 +3492,7 @@ static struct config_int ConfigureNamesInt[] = }, &tcp_keepalives_count, 0, 0, INT_MAX, - NULL, assign_tcp_keepalives_count, show_tcp_keepalives_count + NULL, assign_tcp_keepalives_count, show_tcp_keepalives_count, special_default0 }, { @@ -3438,7 +3503,7 @@ static struct config_int ConfigureNamesInt[] = }, &GinFuzzySearchLimit, 0, 0, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -3450,7 +3515,7 @@ static struct config_int ConfigureNamesInt[] = }, &effective_cache_size, DEFAULT_EFFECTIVE_CACHE_SIZE, 1, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -3461,7 +3526,7 @@ static struct config_int ConfigureNamesInt[] = }, &min_parallel_table_scan_size, (8 * 1024 * 1024) / BLCKSZ, 0, INT_MAX / 3, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -3472,7 +3537,7 @@ static struct config_int ConfigureNamesInt[] = }, &min_parallel_index_scan_size, (512 * 1024) / BLCKSZ, 0, INT_MAX / 3, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -3484,7 +3549,7 @@ static struct config_int ConfigureNamesInt[] = }, &server_version_num, PG_VERSION_NUM, PG_VERSION_NUM, PG_VERSION_NUM, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -3495,7 +3560,7 @@ static struct config_int ConfigureNamesInt[] = }, &log_temp_files, -1, -1, INT_MAX, - NULL, NULL, NULL + NULL, NULL, NULL, special_disabled_all }, { @@ -3506,7 +3571,7 @@ static struct config_int ConfigureNamesInt[] = }, &pgstat_track_activity_query_size, 1024, 100, 1048576, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -3517,7 +3582,7 @@ static struct config_int ConfigureNamesInt[] = }, &gin_pending_list_limit, 4096, 64, MAX_KILOBYTES, - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -3528,7 +3593,7 @@ static struct config_int ConfigureNamesInt[] = }, &tcp_user_timeout, 0, 0, INT_MAX, - NULL, assign_tcp_user_timeout, show_tcp_user_timeout + NULL, assign_tcp_user_timeout, show_tcp_user_timeout, special_default0 }, { @@ -3562,7 +3627,7 @@ static struct config_int ConfigureNamesInt[] = #else /* not DISCARD_CACHES_ENABLED */ 0, 0, 0, #endif /* not DISCARD_CACHES_ENABLED */ - NULL, NULL, NULL + NULL, NULL, NULL, NULL }, { @@ -3573,7 +3638,7 @@ static struct config_int ConfigureNamesInt[] = }, &client_connection_check_interval, 0, 0, INT_MAX, - check_client_connection_check_interval, NULL, NULL + check_client_connection_check_interval, NULL, NULL, special_disabled0 }, { @@ -3590,7 +3655,7 @@ static struct config_int ConfigureNamesInt[] = /* End-of-list marker */ { - {NULL, 0, 0, NULL, NULL}, NULL, 0, 0, 0, NULL, NULL, NULL + {NULL, 0, 0, NULL, NULL}, NULL, 0, 0, 0, NULL, NULL, NULL, NULL } }; @@ -6954,6 +7019,56 @@ parse_int(const char *value, int *result, int flags, const char **hintmsg) return true; } + +/* + * Lookup special values from an array of chars -> int (case-sensitive). + * If the value is found, sets the retval value and returns + * true. If it's not found, return false and leave retval alone. + */ +bool +parse_special_int(const struct config_enum_entry *options, const char *value, + int *retval) +{ + const struct config_enum_entry *entry; + + for (entry = options; entry && entry->name; entry++) + { + if (pg_strcasecmp(value, entry->name) == 0) + { + *retval = entry->val; + return true; + } + } + + /* don't touch the return value in other case */ + return false; +} + +/* + * Lookup special values by int value and set to static string. + * If the value is found, sets the retval value and returns + * true. If it's not found, return false. + */ +bool +special_int_to_value(const struct config_enum_entry *options, int value, + const char **retval) +{ + const struct config_enum_entry *entry; + + for (entry = options; entry && entry->name; entry++) + { + if (value == entry->val) + { + *retval = entry->name; + return true; + } + } + + /* don't touch the return value in other case */ + return false; +} + + /* * Try to parse value as a floating point number in the usual format. * Optionally, the value can be followed by a unit name if "flags" indicates @@ -7017,7 +7132,6 @@ parse_real(const char *value, double *result, int flags, const char **hintmsg) return true; } - /* * Lookup the name for an enum option with the selected value. * Should only ever be called with known-valid values, so throws @@ -7164,8 +7278,8 @@ parse_and_validate_value(struct config_generic *record, struct config_int *conf = (struct config_int *) record; const char *hintmsg; - if (!parse_int(value, &newval->intval, - conf->gen.flags, &hintmsg)) + if (!(conf->special && parse_special_int(conf->special, value, &newval->intval)) && + !parse_int(value, &newval->intval, conf->gen.flags, &hintmsg)) { ereport(elevel, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), @@ -10172,7 +10286,11 @@ _ShowOption(struct config_generic *record, bool use_units) { struct config_int *conf = (struct config_int *) record; - if (conf->show_hook) + /* Special values are prioritized over show hooks */ + if (output_special_values && conf->special && special_int_to_value(conf->special, *conf->variable, &val)) + /* if return is true we have no special action to take here but val was set already */ + ; + else if (conf->show_hook) val = conf->show_hook(); else { diff --git a/src/include/utils/guc_tables.h b/src/include/utils/guc_tables.h index f7e54a87b7..b37122b046 100644 --- a/src/include/utils/guc_tables.h +++ b/src/include/utils/guc_tables.h @@ -197,6 +197,7 @@ struct config_int GucIntCheckHook check_hook; GucIntAssignHook assign_hook; GucShowHook show_hook; + const struct config_enum_entry *special; /* variable fields, initialized at runtime: */ int reset_val; void *reset_extra; diff --git a/src/test/regress/expected/guc.out b/src/test/regress/expected/guc.out index 59da91ff04..af12c4d1c3 100644 --- a/src/test/regress/expected/guc.out +++ b/src/test/regress/expected/guc.out @@ -813,3 +813,48 @@ set default_with_oids to f; -- Should not allow to set it to true. set default_with_oids to t; ERROR: tables declared WITH OIDS are not supported +-- tests for output_special_values and special values +set output_special_values to t; +set log_min_duration_statement = 100; +show log_min_duration_statement; + log_min_duration_statement +---------------------------- + 100ms +(1 row) + +set log_min_duration_statement = -1; +show log_min_duration_statement; + log_min_duration_statement +---------------------------- + disabled +(1 row) + +set log_min_duration_statement = disabled; +show log_min_duration_statement; + log_min_duration_statement +---------------------------- + disabled +(1 row) + +set output_special_values to f; +set log_min_duration_statement = 100; +show log_min_duration_statement; + log_min_duration_statement +---------------------------- + 100ms +(1 row) + +set log_min_duration_statement = -1; +show log_min_duration_statement; + log_min_duration_statement +---------------------------- + -1 +(1 row) + +set log_min_duration_statement = disabled; +show log_min_duration_statement; + log_min_duration_statement +---------------------------- + -1 +(1 row) + diff --git a/src/test/regress/sql/guc.sql b/src/test/regress/sql/guc.sql index c39c11388d..b6a54e0290 100644 --- a/src/test/regress/sql/guc.sql +++ b/src/test/regress/sql/guc.sql @@ -311,3 +311,19 @@ reset check_function_bodies; set default_with_oids to f; -- Should not allow to set it to true. set default_with_oids to t; + +-- tests for output_special_values and special values +set output_special_values to t; +set log_min_duration_statement = 100; +show log_min_duration_statement; +set log_min_duration_statement = -1; +show log_min_duration_statement; +set log_min_duration_statement = disabled; +show log_min_duration_statement; +set output_special_values to f; +set log_min_duration_statement = 100; +show log_min_duration_statement; +set log_min_duration_statement = -1; +show log_min_duration_statement; +set log_min_duration_statement = disabled; +show log_min_duration_statement; -- 2.32.0 (Apple Git-132)