Introduce pg_settings_get_flags() to find flags associated to a GUC

The most meaningful flags are shown, which are the ones useful for the
user and for automating and extending the set of tests supported
currently by check_guc.

This script may actually be removed in the future, but we are not
completely sure yet if and how we want to support the remaining sanity
checks performed there, that are now integrated in the main regression
test suite as of this commit.

Thanks also to Peter Eisentraut and Kyotaro Horiguchi for the
discussion.

Bump catalog version.

Author: Justin Pryzby
Discussion: https://postgr.es/m/20211129030833.GJ17618@telsasoft.com
This commit is contained in:
Michael Paquier 2022-01-31 08:56:41 +09:00
parent 02b8048ba5
commit d10e41d423
6 changed files with 208 additions and 1 deletions

View File

@ -23859,6 +23859,43 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id'));
</para></entry>
</row>
<row>
<entry role="func_table_entry"><para role="func_signature">
<indexterm>
<primary>pg_settings_get_flags</primary>
</indexterm>
<function>pg_settings_get_flags</function> ( <parameter>guc</parameter> <type>text</type> )
<returnvalue>text[]</returnvalue>
</para>
<para>
Returns an array of the flags associated with the given GUC, or
<literal>NULL</literal> if it does not exist. The result is
an empty array if the GUC exists but there are no flags to show.
Only the most useful flags are exposed, as of the following:
<simplelist>
<member>
<literal>EXPLAIN</literal>: parameters included in
<command>EXPLAIN (SETTINGS)</command> commands.
</member>
<member>
<literal>NO_SHOW_ALL</literal>: parameters excluded from
<command>SHOW ALL</command> commands.
</member>
<member>
<literal>NO_RESET_ALL</literal>: parameters excluded from
<command>RESET ALL</command> commands.
</member>
<member>
<literal>NOT_IN_SAMPLE</literal>: parameters not included in
<filename>postgresql.conf</filename> by default.
</member>
<member>
<literal>RUNTIME_COMPUTED</literal>: runtime-computed parameters.
</member>
</simplelist>
</para></entry>
</row>
<row>
<entry role="func_table_entry"><para role="func_signature">
<indexterm>

View File

@ -9634,6 +9634,45 @@ GetConfigOptionByName(const char *name, const char **varname, bool missing_ok)
return _ShowOption(record, true);
}
/*
* Return some of the flags associated to the specified GUC in the shape of
* a text array, and NULL if it does not exist. An empty array is returned
* if the GUC exists without any meaningful flags to show.
*/
Datum
pg_settings_get_flags(PG_FUNCTION_ARGS)
{
#define MAX_GUC_FLAGS 5
char *varname = TextDatumGetCString(PG_GETARG_DATUM(0));
struct config_generic *record;
int cnt = 0;
Datum flags[MAX_GUC_FLAGS];
ArrayType *a;
record = find_option(varname, false, true, ERROR);
/* return NULL if no such variable */
if (record == NULL)
PG_RETURN_NULL();
if (record->flags & GUC_EXPLAIN)
flags[cnt++] = CStringGetTextDatum("EXPLAIN");
if (record->flags & GUC_NO_RESET_ALL)
flags[cnt++] = CStringGetTextDatum("NO_RESET_ALL");
if (record->flags & GUC_NO_SHOW_ALL)
flags[cnt++] = CStringGetTextDatum("NO_SHOW_ALL");
if (record->flags & GUC_NOT_IN_SAMPLE)
flags[cnt++] = CStringGetTextDatum("NOT_IN_SAMPLE");
if (record->flags & GUC_RUNTIME_COMPUTED)
flags[cnt++] = CStringGetTextDatum("RUNTIME_COMPUTED");
Assert(cnt <= MAX_GUC_FLAGS);
/* Returns the record as Datum */
a = construct_array(flags, cnt, TEXTOID, -1, false, TYPALIGN_INT);
PG_RETURN_ARRAYTYPE_P(a);
}
/*
* Return GUC variable value by variable number; optionally return canonical
* form of name. Return value is palloc'd.

View File

@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 202201271
#define CATALOG_VERSION_NO 202201311
#endif

View File

@ -6096,6 +6096,11 @@
proargmodes => '{o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}',
proargnames => '{name,setting,unit,category,short_desc,extra_desc,context,vartype,source,min_val,max_val,enumvals,boot_val,reset_val,sourcefile,sourceline,pending_restart}',
prosrc => 'show_all_settings' },
{ oid => '8921', descr => 'return flags for specified GUC',
proname => 'pg_settings_get_flags', provolatile => 's', prorettype => '_text',
proargtypes => 'text', prosrc => 'pg_settings_get_flags' },
{ oid => '3329', descr => 'show config file settings',
proname => 'pg_show_all_file_settings', prorows => '1000', proretset => 't',
provolatile => 'v', prorettype => 'record', proargtypes => '',

View File

@ -813,3 +813,86 @@ 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
-- Test GUC categories and flag patterns
SELECT pg_settings_get_flags(NULL);
pg_settings_get_flags
-----------------------
(1 row)
SELECT pg_settings_get_flags('does_not_exist');
pg_settings_get_flags
-----------------------
(1 row)
CREATE TABLE tab_settings_flags AS SELECT name, category,
'EXPLAIN' = ANY(flags) AS explain,
'NO_RESET_ALL' = ANY(flags) AS no_reset_all,
'NO_SHOW_ALL' = ANY(flags) AS no_show_all,
'NOT_IN_SAMPLE' = ANY(flags) AS not_in_sample,
'RUNTIME_COMPUTED' = ANY(flags) AS runtime_computed
FROM pg_show_all_settings() AS psas,
pg_settings_get_flags(psas.name) AS flags;
-- Developer GUCs should be flagged with GUC_NOT_IN_SAMPLE:
SELECT name FROM tab_settings_flags
WHERE category = 'Developer Options' AND NOT not_in_sample
ORDER BY 1;
name
------
(0 rows)
-- Most query-tuning GUCs are flagged as valid for EXPLAIN.
-- default_statistics_target is an exception.
SELECT name FROM tab_settings_flags
WHERE category ~ '^Query Tuning' AND NOT explain
ORDER BY 1;
name
---------------------------
default_statistics_target
(1 row)
-- Runtime-computed GUCs should be part of the preset category.
SELECT name FROM tab_settings_flags
WHERE NOT category = 'Preset Options' AND runtime_computed
ORDER BY 1;
name
------
(0 rows)
-- Preset GUCs are flagged as NOT_IN_SAMPLE.
SELECT name FROM tab_settings_flags
WHERE category = 'Preset Options' AND NOT not_in_sample
ORDER BY 1;
name
------
(0 rows)
-- NO_SHOW_ALL implies NO_RESET_ALL, and vice-versa.
SELECT name FROM tab_settings_flags
WHERE no_show_all AND NOT no_reset_all
ORDER BY 1;
name
------
(0 rows)
-- Exceptions are transaction_*.
SELECT name FROM tab_settings_flags
WHERE NOT no_show_all AND no_reset_all
ORDER BY 1;
name
------------------------
transaction_deferrable
transaction_isolation
transaction_read_only
(3 rows)
-- NO_SHOW_ALL implies NOT_IN_SAMPLE.
SELECT name FROM tab_settings_flags
WHERE no_show_all AND NOT not_in_sample
ORDER BY 1;
name
------
(0 rows)
DROP TABLE tab_settings_flags;

View File

@ -311,3 +311,46 @@ reset check_function_bodies;
set default_with_oids to f;
-- Should not allow to set it to true.
set default_with_oids to t;
-- Test GUC categories and flag patterns
SELECT pg_settings_get_flags(NULL);
SELECT pg_settings_get_flags('does_not_exist');
CREATE TABLE tab_settings_flags AS SELECT name, category,
'EXPLAIN' = ANY(flags) AS explain,
'NO_RESET_ALL' = ANY(flags) AS no_reset_all,
'NO_SHOW_ALL' = ANY(flags) AS no_show_all,
'NOT_IN_SAMPLE' = ANY(flags) AS not_in_sample,
'RUNTIME_COMPUTED' = ANY(flags) AS runtime_computed
FROM pg_show_all_settings() AS psas,
pg_settings_get_flags(psas.name) AS flags;
-- Developer GUCs should be flagged with GUC_NOT_IN_SAMPLE:
SELECT name FROM tab_settings_flags
WHERE category = 'Developer Options' AND NOT not_in_sample
ORDER BY 1;
-- Most query-tuning GUCs are flagged as valid for EXPLAIN.
-- default_statistics_target is an exception.
SELECT name FROM tab_settings_flags
WHERE category ~ '^Query Tuning' AND NOT explain
ORDER BY 1;
-- Runtime-computed GUCs should be part of the preset category.
SELECT name FROM tab_settings_flags
WHERE NOT category = 'Preset Options' AND runtime_computed
ORDER BY 1;
-- Preset GUCs are flagged as NOT_IN_SAMPLE.
SELECT name FROM tab_settings_flags
WHERE category = 'Preset Options' AND NOT not_in_sample
ORDER BY 1;
-- NO_SHOW_ALL implies NO_RESET_ALL, and vice-versa.
SELECT name FROM tab_settings_flags
WHERE no_show_all AND NOT no_reset_all
ORDER BY 1;
-- Exceptions are transaction_*.
SELECT name FROM tab_settings_flags
WHERE NOT no_show_all AND no_reset_all
ORDER BY 1;
-- NO_SHOW_ALL implies NOT_IN_SAMPLE.
SELECT name FROM tab_settings_flags
WHERE no_show_all AND NOT not_in_sample
ORDER BY 1;
DROP TABLE tab_settings_flags;