Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1n2Olo-0005sT-MH for pgsql-hackers@arkaria.postgresql.org; Wed, 29 Dec 2021 02:32:53 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1n2Olm-0007Ua-DO for pgsql-hackers@arkaria.postgresql.org; Wed, 29 Dec 2021 02:32:50 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1n2Oll-0007UQ-Te for pgsql-hackers@lists.postgresql.org; Wed, 29 Dec 2021 02:32:50 +0000 Received: from mail-io1-xd34.google.com ([2607:f8b0:4864:20::d34]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1n2Olg-0001Ei-GH for pgsql-hackers@lists.postgresql.org; Wed, 29 Dec 2021 02:32:49 +0000 Received: by mail-io1-xd34.google.com with SMTP id s6so15582250ioj.0 for ; Tue, 28 Dec 2021 18:32:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=telsasoft-com.20210112.gappssmtp.com; s=20210112; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=ccgtYtMmX0z1yen1b9yTjJKtHaFOlYK2pfcwUhmojeU=; b=NeSskQ8KzrCofnMBZr+IzsJ3IVga2Kvfdb2tUP9MrHyg7FRoSah2CO5JVibNc4KFMy MTgZfOEysE+4CJnNEnCVEXSov7hezFxFb7UPdYRTxpN8Cref+EFM58H+C4Bffv3iiw9w g00sEsV3YkttQz2CQgqXQ7nWY3F6n/NCd4stof7/WzBTixRmcMjUaXLay3rZKDJH2QQQ 8EXJqy7scS4PZbaQQKXuKPzf12/FMIe9WK/Amwm4GMlpQMEqLLO23sTB89EUizmHrbbG MxAsK7IiQfKYIqALkdkgAgaG15jIUZoC6Y5DoZI/mn9yduvUiadZdifadEMxJlWXTp1t RWmA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=ccgtYtMmX0z1yen1b9yTjJKtHaFOlYK2pfcwUhmojeU=; b=HaktRtMG/6y7XwWwN8AnVF2NsYTH4ht/LgebeXpyJVReozN9irIasrz5ql74t1Y2B/ MY9IJQYJ1NoTuIWq+JwhYySuK3jN7yhmGHqFOOZJqDVGk0quJF2LeEfJg1AcTebZnVuU TMfENwnLVxgHL72Jt8/qzmQj5/bk9ZAaSaX2b5hVp+UeblPflFoJpNkSSanQmEs4TH/2 rMykczMPQ26vQxd7B4OQJa2fvYfwvDZRNtnXwmNkdISmelqQSUQzschKEKxF0oRTgMRS uNI0wnNqpwpnrD/tuZsTmfd2SitBlZV5Os8drG0YvONa4A7k6hUGVZtH8+sy8OnqL0s7 jRLw== X-Gm-Message-State: AOAM5338Y62/v5LxYsytvYX07j8eyMblw/bjTEje44VQUwl2GrmK6cM6 ivldXG38w1D58zcfupeFZBTBaRsqey59MQ== X-Google-Smtp-Source: ABdhPJzrGaekIr4rqU+8SXymGGUhIDrsJMZZgjGBmQmV1y64bl8FGU1LRxlycHE+4aN3sm/hRAniJg== X-Received: by 2002:a02:c503:: with SMTP id s3mr10902691jam.157.1640745162872; Tue, 28 Dec 2021 18:32:42 -0800 (PST) Received: from pryzbyj.telsasoft (charmander.telsasoft.com. [50.244.222.1]) by smtp.gmail.com with ESMTPSA id n2sm12137464ioc.0.2021.12.28.18.32.41 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 28 Dec 2021 18:32:41 -0800 (PST) Received: by pryzbyj.telsasoft (Postfix, from userid 1000) id CE01D800764; Tue, 28 Dec 2021 20:32:40 -0600 (CST) Date: Tue, 28 Dec 2021 20:32:40 -0600 From: Justin Pryzby To: Michael Paquier Cc: Peter Eisentraut , pgsql-hackers@lists.postgresql.org, Bruce Momjian , Tom Lane Subject: Re: GUC flags Message-ID: <20211229023240.GM24477@telsasoft.com> References: <20211202051734.GN17618@telsasoft.com> <20211206053805.GG17618@telsasoft.com> <20211206133655.GH17618@telsasoft.com> <20211209155322.GG17618@telsasoft.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="a8sldprk+5E/pDEv" Content-Disposition: inline In-Reply-To: <20211209155322.GG17618@telsasoft.com> User-Agent: Mutt/1.9.4 (2018-02-28) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --a8sldprk+5E/pDEv Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Thu, Dec 09, 2021 at 09:53:23AM -0600, Justin Pryzby wrote: > On Thu, Dec 09, 2021 at 05:17:54PM +0900, Michael Paquier wrote: > > On Wed, Dec 08, 2021 at 01:23:51PM +0100, Peter Eisentraut wrote: > > > I wasn't really aware of this script either. But I think it's a good idea > > > to have it. But only if it's run automatically as part of a test suite run. > > > > Okay. If we do that, I am wondering whether it would be better to > > rewrite this script in perl then, so as there is no need to worry > > about the compatibility of grep. And also, it would make sense to > > return a non-zero exit code if an incompatibility is found for the > > automation part. > > One option is to expose the GUC flags in pg_settings, so this can all be done > in SQL regression tests. > > Maybe the flags should be text strings, so it's a nicer user-facing interface. > But then the field would be pretty wide, even though we're only adding it for > regression tests. The only other alternative I can think of is to make a > sql-callable function like pg_get_guc_flags(text guc). Rebased on cab5b9ab2c066ba904f13de2681872dcda31e207. And added 0003, which changes to instead exposes the flags as a function, to avoid changing pg_settings and exposing internally-defined integer flags in that somewhat prominent view. -- Justin --a8sldprk+5E/pDEv Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v3-0001-check_guc-fix-absurd-number-of-false-positives.patch" From 7f620514e85d19e5fb3b108c4de3f6f41f295114 Mon Sep 17 00:00:00 2001 From: Justin Pryzby Date: Sun, 5 Dec 2021 23:22:04 -0600 Subject: [PATCH v3 1/3] check_guc: fix absurd number of false positives Avoid false positives; Avoid various assumptions; Avoid list of exceptions; Simplify shell/awk/sed/grep; This requires GNU awk for RS as a regex. --- src/backend/utils/misc/check_guc | 69 +++++--------------------------- 1 file changed, 10 insertions(+), 59 deletions(-) diff --git a/src/backend/utils/misc/check_guc b/src/backend/utils/misc/check_guc index b171ef0e4ff..323ca13191b 100755 --- a/src/backend/utils/misc/check_guc +++ b/src/backend/utils/misc/check_guc @@ -1,78 +1,29 @@ -#!/bin/sh +#! /bin/sh +set -e -## currently, this script makes a lot of assumptions: +## this script makes some assumptions about the formatting of files it parses. ## in postgresql.conf.sample: ## 1) the valid config settings may be preceded by a '#', but NOT '# ' ## (we use this to skip comments) -## 2) the valid config settings will be followed immediately by ' =' -## (at least one space preceding the '=') -## in guc.c: -## 3) the options have PGC_ on the same line as the option -## 4) the options have '{' on the same line as the option - -## Problems -## 1) Don't know what to do with TRANSACTION ISOLATION LEVEL - -## if an option is valid but shows up in only one file (guc.c but not -## postgresql.conf.sample), it should be listed here so that it -## can be ignored -INTENTIONALLY_NOT_INCLUDED="debug_deadlocks in_hot_standby \ -is_superuser lc_collate lc_ctype lc_messages lc_monetary lc_numeric lc_time \ -pre_auth_delay role seed server_encoding server_version server_version_num \ -session_authorization trace_lock_oidmin trace_lock_table trace_locks trace_lwlocks \ -trace_notify trace_userlocks transaction_isolation transaction_read_only \ -zero_damaged_pages" ### What options are listed in postgresql.conf.sample, but don't appear ### in guc.c? -# grab everything that looks like a setting and convert it to lower case -SETTINGS=`grep ' =' postgresql.conf.sample | -grep -v '^# ' | # strip comments -sed -e 's/^#//' | -awk '{print $1}'` - -SETTINGS=`echo "$SETTINGS" | tr 'A-Z' 'a-z'` +# grab everything that looks like a setting +SETTINGS=`sed '/^#[[:alnum:]]/!d; s/^#//; s/ =.*//; /^include/d' postgresql.conf.sample` for i in $SETTINGS ; do - hidden=0 ## it sure would be nice to replace this with an sql "not in" statement - ## it doesn't seem to make sense to have things in .sample and not in guc.c -# for hidethis in $INTENTIONALLY_NOT_INCLUDED ; do -# if [ "$hidethis" = "$i" ] ; then -# hidden=1 -# fi -# done - if [ "$hidden" -eq 0 ] ; then - grep -i '"'$i'"' guc.c > /dev/null - if [ $? -ne 0 ] ; then - echo "$i seems to be missing from guc.c"; - fi; - fi + grep -i "\"$i\"" guc.c >/dev/null || + echo "$i seems to be missing from guc.c"; done ### What options are listed in guc.c, but don't appear ### in postgresql.conf.sample? # grab everything that looks like a setting and convert it to lower case - -SETTINGS=`grep '{.* PGC_' guc.c | awk '{print $1}' | \ - sed -e 's/{//g' -e 's/"//g' -e 's/,//'` - -SETTINGS=`echo "$SETTINGS" | tr 'A-Z' 'a-z'` - +SETTINGS=`gawk -F '[",]' 'BEGIN{RS="\n\t\\\\{\n"} /",[[:space:]]*PGC_.*.*gettext_noop/ && !/NOT_IN_SAMPLE/{print tolower($2)}' guc.c` for i in $SETTINGS ; do - hidden=0 - ## it sure would be nice to replace this with an sql "not in" statement - for hidethis in $INTENTIONALLY_NOT_INCLUDED ; do - if [ "$hidethis" = "$i" ] ; then - hidden=1 - fi - done - if [ "$hidden" -eq 0 ] ; then - grep -i '#'$i' ' postgresql.conf.sample > /dev/null - if [ $? -ne 0 ] ; then - echo "$i seems to be missing from postgresql.conf.sample"; - fi - fi + grep "#$i " postgresql.conf.sample >/dev/null || + echo "$i seems to be missing from postgresql.conf.sample"; done -- 2.17.1 --a8sldprk+5E/pDEv Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v3-0002-Expose-GUC-flags-in-pg_settings-retire-.-check_gu.patch" From e567e0ea90adde3f13f0bfcd5cf769ca71f60e78 Mon Sep 17 00:00:00 2001 From: Justin Pryzby Date: Wed, 8 Dec 2021 12:06:35 -0600 Subject: [PATCH v3 2/3] Expose GUC flags in pg_settings; retire ./check_guc --- src/backend/utils/misc/check_guc | 29 ------- src/backend/utils/misc/guc.c | 8 +- src/include/catalog/pg_proc.dat | 6 +- src/test/regress/expected/guc.out | 124 ++++++++++++++++++++++++++++ src/test/regress/expected/rules.out | 5 +- src/test/regress/sql/guc.sql | 74 +++++++++++++++++ 6 files changed, 211 insertions(+), 35 deletions(-) delete mode 100755 src/backend/utils/misc/check_guc diff --git a/src/backend/utils/misc/check_guc b/src/backend/utils/misc/check_guc deleted file mode 100755 index 323ca13191b..00000000000 --- a/src/backend/utils/misc/check_guc +++ /dev/null @@ -1,29 +0,0 @@ -#! /bin/sh -set -e - -## this script makes some assumptions about the formatting of files it parses. -## in postgresql.conf.sample: -## 1) the valid config settings may be preceded by a '#', but NOT '# ' -## (we use this to skip comments) - -### What options are listed in postgresql.conf.sample, but don't appear -### in guc.c? - -# grab everything that looks like a setting -SETTINGS=`sed '/^#[[:alnum:]]/!d; s/^#//; s/ =.*//; /^include/d' postgresql.conf.sample` - -for i in $SETTINGS ; do - ## it sure would be nice to replace this with an sql "not in" statement - grep -i "\"$i\"" guc.c >/dev/null || - echo "$i seems to be missing from guc.c"; -done - -### What options are listed in guc.c, but don't appear -### in postgresql.conf.sample? - -# grab everything that looks like a setting and convert it to lower case -SETTINGS=`gawk -F '[",]' 'BEGIN{RS="\n\t\\\\{\n"} /",[[:space:]]*PGC_.*.*gettext_noop/ && !/NOT_IN_SAMPLE/{print tolower($2)}' guc.c` -for i in $SETTINGS ; do - grep "#$i " postgresql.conf.sample >/dev/null || - echo "$i seems to be missing from postgresql.conf.sample"; -done diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index f9504d3aec4..822dfed2b6c 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -9849,6 +9849,10 @@ GetConfigOptionByNum(int varnum, const char **values, bool *noshow) } values[16] = (conf->status & GUC_PENDING_RESTART) ? "t" : "f"; + + /* flags */ + snprintf(buffer, sizeof(buffer), "%d", conf->flags); + values[17] = pstrdup(buffer); } /* @@ -9904,7 +9908,7 @@ show_config_by_name_missing_ok(PG_FUNCTION_ARGS) * show_all_settings - equiv to SHOW ALL command but implemented as * a Table Function. */ -#define NUM_PG_SETTINGS_ATTS 17 +#define NUM_PG_SETTINGS_ATTS 18 Datum show_all_settings(PG_FUNCTION_ARGS) @@ -9966,6 +9970,8 @@ show_all_settings(PG_FUNCTION_ARGS) INT4OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 17, "pending_restart", BOOLOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 18, "flags", + INT4OID, -1, 0); /* * Generate attribute metadata needed later to produce tuples from raw diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 4d992dc2241..ee86d869057 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -6092,9 +6092,9 @@ { oid => '2084', descr => 'SHOW ALL as a function', proname => 'pg_show_all_settings', prorows => '1000', proretset => 't', provolatile => 's', prorettype => 'record', proargtypes => '', - proallargtypes => '{text,text,text,text,text,text,text,text,text,text,text,_text,text,text,text,int4,bool}', - 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}', + proallargtypes => '{text,text,text,text,text,text,text,text,text,text,text,_text,text,text,text,int4,bool,int4}', + proargmodes => '{o,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,flags}', prosrc => 'show_all_settings' }, { oid => '3329', descr => 'show config file settings', proname => 'pg_show_all_file_settings', prorows => '1000', proretset => 't', diff --git a/src/test/regress/expected/guc.out b/src/test/regress/expected/guc.out index 59da91ff04d..d0f3cda22c8 100644 --- a/src/test/regress/expected/guc.out +++ b/src/test/regress/expected/guc.out @@ -813,3 +813,127 @@ 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 flags. +-- +begin; +CREATE TEMP TABLE pg_settings AS SELECT name, category, + (flags&4) != 0 AS no_show_all, + (flags&8) != 0 AS no_reset_all, + (flags&32) != 0 AS not_in_sample, + (flags&1048576) != 0 AS guc_explain, + (flags&2097152) != 0 AS guc_computed + FROM pg_settings; +-- test that GUCS are in postgresql.conf +SELECT lower(name) FROM pg_settings WHERE NOT not_in_sample EXCEPT +SELECT regexp_replace(ln, '^#?([_[:alpha:]]+) = .*', '\1') AS guc +FROM (SELECT regexp_split_to_table(pg_read_file('postgresql.conf'), '\n') AS ln) conf +WHERE ln ~ '^#?[[:alpha:]]' +ORDER BY 1; + lower +----------------------------- + config_file + plpgsql.check_asserts + plpgsql.extra_errors + plpgsql.extra_warnings + plpgsql.print_strict_params + plpgsql.variable_conflict +(6 rows) + +-- test that lines in postgresql.conf that look like GUCs are GUCs +SELECT regexp_replace(ln, '^#?([_[:alpha:]]+) = .*', '\1') AS guc +FROM (SELECT regexp_split_to_table(pg_read_file('postgresql.conf'), '\n') AS ln) conf +WHERE ln ~ '^#?[[:alpha:]]' +EXCEPT SELECT lower(name) FROM pg_settings WHERE NOT not_in_sample +ORDER BY 1; + guc +------------------- + include + include_dir + include_if_exists +(3 rows) + +-- test that section:DEVELOPER GUCs are flagged GUC_NOT_IN_SAMPLE: +SELECT * FROM pg_settings +WHERE category='Developer Options' AND NOT not_in_sample +ORDER BY 1; + name | category | no_show_all | no_reset_all | not_in_sample | guc_explain | guc_computed +------+----------+-------------+--------------+---------------+-------------+-------------- +(0 rows) + +-- Maybe the converse: +SELECT * FROM pg_settings +WHERE category NOT IN ('Developer Options', 'Preset Options') AND not_in_sample +ORDER BY 1; + name | category | no_show_all | no_reset_all | not_in_sample | guc_explain | guc_computed +------------------------+-------------------------------------------------+-------------+--------------+---------------+-------------+-------------- + application_name | Reporting and Logging / What to Log | f | f | t | f | f + transaction_deferrable | Client Connection Defaults / Statement Behavior | f | t | t | f | f + transaction_isolation | Client Connection Defaults / Statement Behavior | f | t | t | f | f + transaction_read_only | Client Connection Defaults / Statement Behavior | f | t | t | f | f +(4 rows) + +-- Most Query Tuning GUCs are flagged as EXPLAIN: +SELECT * FROM pg_settings +WHERE category ~ '^Query Tuning' AND NOT guc_explain +ORDER BY 1; + name | category | no_show_all | no_reset_all | not_in_sample | guc_explain | guc_computed +---------------------------+--------------------------------------+-------------+--------------+---------------+-------------+-------------- + default_statistics_target | Query Tuning / Other Planner Options | f | f | f | f | f +(1 row) + +-- Maybe the converse: +SELECT * FROM pg_settings +WHERE guc_explain AND NOT category ~ '^Query Tuning|^Resource Usage' +ORDER BY 1; + name | category | no_show_all | no_reset_all | not_in_sample | guc_explain | guc_computed +---------------------+-------------------------------------------------+-------------+--------------+---------------+-------------+-------------- + force_parallel_mode | Developer Options | f | f | t | t | f + search_path | Client Connection Defaults / Statement Behavior | f | f | f | t | f +(2 rows) + +-- GUCs flagged RUNTIME are Preset +SELECT * FROM pg_settings +WHERE guc_computed AND NOT category='Preset Options' +ORDER BY 1; + name | category | no_show_all | no_reset_all | not_in_sample | guc_explain | guc_computed +------+----------+-------------+--------------+---------------+-------------+-------------- +(0 rows) + +-- PRESET GUCs are flagged NOT_IN_SAMPLE +SELECT * FROM pg_settings +WHERE category='Preset Options' AND NOT not_in_sample +ORDER BY 1; + name | category | no_show_all | no_reset_all | not_in_sample | guc_explain | guc_computed +------+----------+-------------+--------------+---------------+-------------+-------------- +(0 rows) + +-- NO_SHOW_ALL implies NO_RESET_ALL: +SELECT * FROM pg_settings +WHERE no_show_all AND NOT no_reset_all +ORDER BY 1; + name | category | no_show_all | no_reset_all | not_in_sample | guc_explain | guc_computed +------+----------+-------------+--------------+---------------+-------------+-------------- +(0 rows) + +-- Usually the converse: +SELECT * FROM pg_settings +WHERE NOT no_show_all AND no_reset_all +ORDER BY 1; + name | category | no_show_all | no_reset_all | not_in_sample | guc_explain | guc_computed +------------------------+-------------------------------------------------+-------------+--------------+---------------+-------------+-------------- + transaction_deferrable | Client Connection Defaults / Statement Behavior | f | t | t | f | f + transaction_isolation | Client Connection Defaults / Statement Behavior | f | t | t | f | f + transaction_read_only | Client Connection Defaults / Statement Behavior | f | t | t | f | f +(3 rows) + +-- NO_SHOW_ALL implies NOT_IN_SAMPLE: +SELECT * FROM pg_settings +WHERE no_show_all AND NOT not_in_sample +ORDER BY 1; + name | category | no_show_all | no_reset_all | not_in_sample | guc_explain | guc_computed +------+----------+-------------+--------------+---------------+-------------+-------------- +(0 rows) + +DROP TABLE pg_settings; +rollback; diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index b58b062b10d..2db00f2a8df 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -1724,8 +1724,9 @@ pg_settings| SELECT a.name, a.reset_val, a.sourcefile, a.sourceline, - a.pending_restart - FROM pg_show_all_settings() a(name, setting, unit, category, short_desc, extra_desc, context, vartype, source, min_val, max_val, enumvals, boot_val, reset_val, sourcefile, sourceline, pending_restart); + a.pending_restart, + a.flags + FROM pg_show_all_settings() a(name, setting, unit, category, short_desc, extra_desc, context, vartype, source, min_val, max_val, enumvals, boot_val, reset_val, sourcefile, sourceline, pending_restart, flags); pg_shadow| SELECT pg_authid.rolname AS usename, pg_authid.oid AS usesysid, pg_authid.rolcreatedb AS usecreatedb, diff --git a/src/test/regress/sql/guc.sql b/src/test/regress/sql/guc.sql index c39c11388d5..66eb28823b3 100644 --- a/src/test/regress/sql/guc.sql +++ b/src/test/regress/sql/guc.sql @@ -311,3 +311,77 @@ 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 flags. +-- +begin; +CREATE TEMP TABLE pg_settings AS SELECT name, category, + (flags&4) != 0 AS no_show_all, + (flags&8) != 0 AS no_reset_all, + (flags&32) != 0 AS not_in_sample, + (flags&1048576) != 0 AS guc_explain, + (flags&2097152) != 0 AS guc_computed + FROM pg_settings; + +-- test that GUCS are in postgresql.conf +SELECT lower(name) FROM pg_settings WHERE NOT not_in_sample EXCEPT +SELECT regexp_replace(ln, '^#?([_[:alpha:]]+) = .*', '\1') AS guc +FROM (SELECT regexp_split_to_table(pg_read_file('postgresql.conf'), '\n') AS ln) conf +WHERE ln ~ '^#?[[:alpha:]]' +ORDER BY 1; + +-- test that lines in postgresql.conf that look like GUCs are GUCs +SELECT regexp_replace(ln, '^#?([_[:alpha:]]+) = .*', '\1') AS guc +FROM (SELECT regexp_split_to_table(pg_read_file('postgresql.conf'), '\n') AS ln) conf +WHERE ln ~ '^#?[[:alpha:]]' +EXCEPT SELECT lower(name) FROM pg_settings WHERE NOT not_in_sample +ORDER BY 1; + +-- test that section:DEVELOPER GUCs are flagged GUC_NOT_IN_SAMPLE: +SELECT * FROM pg_settings +WHERE category='Developer Options' AND NOT not_in_sample +ORDER BY 1; + +-- Maybe the converse: +SELECT * FROM pg_settings +WHERE category NOT IN ('Developer Options', 'Preset Options') AND not_in_sample +ORDER BY 1; + +-- Most Query Tuning GUCs are flagged as EXPLAIN: +SELECT * FROM pg_settings +WHERE category ~ '^Query Tuning' AND NOT guc_explain +ORDER BY 1; + +-- Maybe the converse: +SELECT * FROM pg_settings +WHERE guc_explain AND NOT category ~ '^Query Tuning|^Resource Usage' +ORDER BY 1; + +-- GUCs flagged RUNTIME are Preset +SELECT * FROM pg_settings +WHERE guc_computed AND NOT category='Preset Options' +ORDER BY 1; + +-- PRESET GUCs are flagged NOT_IN_SAMPLE +SELECT * FROM pg_settings +WHERE category='Preset Options' AND NOT not_in_sample +ORDER BY 1; + +-- NO_SHOW_ALL implies NO_RESET_ALL: +SELECT * FROM pg_settings +WHERE no_show_all AND NOT no_reset_all +ORDER BY 1; + +-- Usually the converse: +SELECT * FROM pg_settings +WHERE NOT no_show_all AND no_reset_all +ORDER BY 1; + +-- NO_SHOW_ALL implies NOT_IN_SAMPLE: +SELECT * FROM pg_settings +WHERE no_show_all AND NOT not_in_sample +ORDER BY 1; + +DROP TABLE pg_settings; +rollback; -- 2.17.1 --a8sldprk+5E/pDEv Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v3-0003-f-pg_get_guc_flags.patch" From 1d5d95c9146f75f012f0b3df133f0e82859c0bde Mon Sep 17 00:00:00 2001 From: Justin Pryzby Date: Sun, 26 Dec 2021 20:12:16 -0600 Subject: [PATCH v3 3/3] f!pg_get_guc_flags --- src/backend/utils/misc/guc.c | 26 +++++++++++++++++++------- src/include/catalog/pg_proc.dat | 10 +++++++--- src/test/regress/expected/guc.out | 2 +- src/test/regress/expected/rules.out | 5 ++--- src/test/regress/sql/guc.sql | 2 +- 5 files changed, 30 insertions(+), 15 deletions(-) diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 822dfed2b6c..91ff2a18875 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -9849,10 +9849,6 @@ GetConfigOptionByNum(int varnum, const char **values, bool *noshow) } values[16] = (conf->status & GUC_PENDING_RESTART) ? "t" : "f"; - - /* flags */ - snprintf(buffer, sizeof(buffer), "%d", conf->flags); - values[17] = pstrdup(buffer); } /* @@ -9904,11 +9900,29 @@ show_config_by_name_missing_ok(PG_FUNCTION_ARGS) PG_RETURN_TEXT_P(cstring_to_text(varval)); } +/* + * Return the flags for the specified GUC, or NULL if it doesn't exist. + */ +Datum +pg_get_guc_flags(PG_FUNCTION_ARGS) +{ + char *varname = TextDatumGetCString(PG_GETARG_DATUM(0)); + struct config_generic *record; + + record = find_option(varname, false, true, ERROR); + + /* return NULL if no such variable */ + if (record == NULL) + PG_RETURN_NULL(); + + PG_RETURN_INT32(record->flags); +} + /* * show_all_settings - equiv to SHOW ALL command but implemented as * a Table Function. */ -#define NUM_PG_SETTINGS_ATTS 18 +#define NUM_PG_SETTINGS_ATTS 17 Datum show_all_settings(PG_FUNCTION_ARGS) @@ -9970,8 +9984,6 @@ show_all_settings(PG_FUNCTION_ARGS) INT4OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 17, "pending_restart", BOOLOID, -1, 0); - TupleDescInitEntry(tupdesc, (AttrNumber) 18, "flags", - INT4OID, -1, 0); /* * Generate attribute metadata needed later to produce tuples from raw diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index ee86d869057..7fa701fe815 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -6092,10 +6092,14 @@ { oid => '2084', descr => 'SHOW ALL as a function', proname => 'pg_show_all_settings', prorows => '1000', proretset => 't', provolatile => 's', prorettype => 'record', proargtypes => '', - proallargtypes => '{text,text,text,text,text,text,text,text,text,text,text,_text,text,text,text,int4,bool,int4}', - proargmodes => '{o,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,flags}', + proallargtypes => '{text,text,text,text,text,text,text,text,text,text,text,_text,text,text,text,int4,bool}', + 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 => '6116', descr => 'return flags for specified GUC', + proname => 'pg_get_guc_flags', provolatile => 's', + prorettype => 'int4', proargtypes => 'text', + prosrc => 'pg_get_guc_flags' }, { oid => '3329', descr => 'show config file settings', proname => 'pg_show_all_file_settings', prorows => '1000', proretset => 't', provolatile => 'v', prorettype => 'record', proargtypes => '', diff --git a/src/test/regress/expected/guc.out b/src/test/regress/expected/guc.out index d0f3cda22c8..f7dd6c0b299 100644 --- a/src/test/regress/expected/guc.out +++ b/src/test/regress/expected/guc.out @@ -823,7 +823,7 @@ CREATE TEMP TABLE pg_settings AS SELECT name, category, (flags&32) != 0 AS not_in_sample, (flags&1048576) != 0 AS guc_explain, (flags&2097152) != 0 AS guc_computed - FROM pg_settings; + FROM pg_settings, pg_get_guc_flags(name) AS flags; -- test that GUCS are in postgresql.conf SELECT lower(name) FROM pg_settings WHERE NOT not_in_sample EXCEPT SELECT regexp_replace(ln, '^#?([_[:alpha:]]+) = .*', '\1') AS guc diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index 2db00f2a8df..b58b062b10d 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -1724,9 +1724,8 @@ pg_settings| SELECT a.name, a.reset_val, a.sourcefile, a.sourceline, - a.pending_restart, - a.flags - FROM pg_show_all_settings() a(name, setting, unit, category, short_desc, extra_desc, context, vartype, source, min_val, max_val, enumvals, boot_val, reset_val, sourcefile, sourceline, pending_restart, flags); + a.pending_restart + FROM pg_show_all_settings() a(name, setting, unit, category, short_desc, extra_desc, context, vartype, source, min_val, max_val, enumvals, boot_val, reset_val, sourcefile, sourceline, pending_restart); pg_shadow| SELECT pg_authid.rolname AS usename, pg_authid.oid AS usesysid, pg_authid.rolcreatedb AS usecreatedb, diff --git a/src/test/regress/sql/guc.sql b/src/test/regress/sql/guc.sql index 66eb28823b3..81eac9b8ed2 100644 --- a/src/test/regress/sql/guc.sql +++ b/src/test/regress/sql/guc.sql @@ -322,7 +322,7 @@ CREATE TEMP TABLE pg_settings AS SELECT name, category, (flags&32) != 0 AS not_in_sample, (flags&1048576) != 0 AS guc_explain, (flags&2097152) != 0 AS guc_computed - FROM pg_settings; + FROM pg_settings, pg_get_guc_flags(name) AS flags; -- test that GUCS are in postgresql.conf SELECT lower(name) FROM pg_settings WHERE NOT not_in_sample EXCEPT -- 2.17.1 --a8sldprk+5E/pDEv--