[HACKERS] [PATCH] Add two-arg for of current_setting(NAME, FALLBACK)

Поиск
Список
Период
Сортировка
От David Christensen
Тема [HACKERS] [PATCH] Add two-arg for of current_setting(NAME, FALLBACK)
Дата
Msg-id 1426804862-5899-1-git-send-email-david@endpoint.com
обсуждение исходный текст
Ответы Re: [HACKERS] [PATCH] Add two-arg for of current_setting(NAME, FALLBACK)  (Pavel Stehule <pavel.stehule@gmail.com>)
Re: [HACKERS] [PATCH] Add two-arg for of current_setting(NAME, FALLBACK)  ("David G. Johnston" <david.g.johnston@gmail.com>)
Re: [HACKERS] [PATCH] Add two-arg for of current_setting(NAME,FALLBACK)  (Nico Williams <nico@cryptonector.com>)
Список pgsql-hackers
The two-arg form of the current_setting() function will allow a
fallback value to be returned instead of throwing an error when an
unknown GUC is provided.  This would come in most useful when using
custom GUCs; e.g.:
 -- errors out if the 'foo.bar' setting is unset SELECT current_setting('foo.bar');
 -- returns current setting of foo.bar, or 'default' if not set SELECT current_setting('foo.bar', 'default')

This would save you having to wrap the use of the function in an
exception block just to catch and utilize a default setting value
within a function.
---src/backend/utils/misc/guc.c      | 50 ++++++++++++++++++++++++++++++++++++---src/include/catalog/pg_proc.h     |  2
++src/include/utils/builtins.h     |  1 +src/include/utils/guc.h           |  1 +src/test/regress/expected/guc.out | 19
+++++++++++++++src/test/regress/sql/guc.sql     | 12 ++++++++++6 files changed, 82 insertions(+), 3 deletions(-)
 

diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 26275bd..002a926 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -7703,13 +7703,32 @@ ShowAllGUCConfig(DestReceiver *dest)char *GetConfigOptionByName(const char *name, const char
**varname){
+    return GetConfigOptionByNameFallback(name, NULL, varname);
+}
+
+/*
+ * Return GUC variable value by name; optionally return canonical form of
+ * name.  If GUC is NULL then optionally return a fallback value instead of an
+ * error.  Return value is palloc'd.
+ */
+char *
+GetConfigOptionByNameFallback(const char *name, const char *default_value, const char **varname)
+{    struct config_generic *record;    record = find_option(name, false, ERROR);    if (record == NULL)
-        ereport(ERROR,
-                (errcode(ERRCODE_UNDEFINED_OBJECT),
-               errmsg("unrecognized configuration parameter \"%s\"", name)));
+    {
+        if (default_value) {
+            return pstrdup(default_value);
+        }
+        else
+        {
+            ereport(ERROR,
+                    (errcode(ERRCODE_UNDEFINED_OBJECT),
+                   errmsg("unrecognized configuration parameter \"%s\"", name)));
+        }
+    }    if ((record->flags & GUC_SUPERUSER_ONLY) && !superuser())        ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
@@ -8008,6 +8027,31 @@ show_config_by_name(PG_FUNCTION_ARGS)}/*
+ * show_config_by_name_fallback - equiv to SHOW X command but implemented as
+ * a function.  If X does not exist, return a fallback datum instead of erroring
+ */
+Datum
+show_config_by_name_fallback(PG_FUNCTION_ARGS)
+{
+    char       *varname;
+    char       *varfallback;
+    char       *varval;
+    
+    /* Get the GUC variable name */
+    varname = TextDatumGetCString(PG_GETARG_DATUM(0));
+
+    /* Get the fallback value */
+    varfallback = TextDatumGetCString(PG_GETARG_DATUM(1));
+    
+    /* Get the value */
+    varval = GetConfigOptionByNameFallback(varname, varfallback, NULL);
+
+    /* Convert to text */
+    PG_RETURN_TEXT_P(cstring_to_text(varval));
+}
+
+
+/* * show_all_settings - equiv to SHOW ALL command but implemented as * a Table Function. */
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 6a757f3..71efed2 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -3025,6 +3025,8 @@ DESCR("convert bitstring to int8");DATA(insert OID = 2077 (  current_setting    PGNSP PGUID 12 1
00 0 f f f f t f s 1 0 25 "25" _null_ _null_ _null_ _null_ show_config_by_name _null_ _null_ _null_ ));DESCR("SHOW X as
afunction");
 
+DATA(insert OID = 3280 (  current_setting    PGNSP PGUID 12 1 0 0 0 f f f f t f s 2 0 25 "25 25" _null_ _null_ _null_
_null_show_config_by_name_fallback _null_ _null_ _null_ ));
 
+DESCR("SHOW X as a function");DATA(insert OID = 2078 (  set_config        PGNSP PGUID 12 1 0 0 0 f f f f f f v 3 0 25
"2525 16" _null_ _null_ _null_ _null_ set_config_by_name _null_ _null_ _null_ ));DESCR("SET X as a
function");DATA(insertOID = 2084 (  pg_show_all_settings    PGNSP PGUID 12 1 1000 0 0 f f f f t t s 0 0 2249 ""
"{25,25,25,25,25,25,25,25,25,25,25,1009,25,25,25,23}""{o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}"
"{name,setting,unit,category,short_desc,extra_desc,context,vartype,source,min_val,max_val,enumvals,boot_val,reset_val,sourcefile,sourceline}"
_null_show_all_settings _null_ _null_ _null_ ));
 
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index bc4517d..e3d9fbb 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -1088,6 +1088,7 @@ extern Datum quote_nullable(PG_FUNCTION_ARGS);/* guc.c */extern Datum
show_config_by_name(PG_FUNCTION_ARGS);
+extern Datum show_config_by_name_fallback(PG_FUNCTION_ARGS);extern Datum set_config_by_name(PG_FUNCTION_ARGS);extern
Datumshow_all_settings(PG_FUNCTION_ARGS);
 
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index d3100d1..145ad5d 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -352,6 +352,7 @@ extern int set_config_option(const char *name, const char *value,                  bool
is_reload);externvoid AlterSystemSetConfigFile(AlterSystemStmt *setstmt);extern char *GetConfigOptionByName(const char
*name,const char **varname);
 
+extern char *GetConfigOptionByNameFallback(const char *name, const char *fallback, const char **varname);extern void
GetConfigOptionByNum(intvarnum, const char **values, bool *noshow);extern int    GetNumConfigOptions(void);
 
diff --git a/src/test/regress/expected/guc.out b/src/test/regress/expected/guc.out
index 4f0065c..905969b 100644
--- a/src/test/regress/expected/guc.out
+++ b/src/test/regress/expected/guc.out
@@ -736,3 +736,22 @@ NOTICE:  text search configuration "no_such_config" does not existselect
func_with_bad_set();ERROR: invalid value for parameter "default_text_search_config": "no_such_config"reset
check_function_bodies;
+-- check multi-arg custom current_setting
+-- this should error:
+select current_setting('nosuch.setting');
+ERROR:  unrecognized configuration parameter "nosuch.setting"
+-- this should return 'fallback'
+select current_setting('nosuch.setting','fallback');
+ current_setting 
+-----------------
+ fallback
+(1 row)
+
+-- this should return 'nada', not 'fallback'
+set nosuch.setting = 'nada';
+select current_setting('nosuch.setting','fallback');
+ current_setting 
+-----------------
+ nada
+(1 row)
+
diff --git a/src/test/regress/sql/guc.sql b/src/test/regress/sql/guc.sql
index 3de8a6b..48c0bed 100644
--- a/src/test/regress/sql/guc.sql
+++ b/src/test/regress/sql/guc.sql
@@ -275,3 +275,15 @@ set default_text_search_config = no_such_config;select func_with_bad_set();reset
check_function_bodies;
+
+-- check multi-arg custom current_setting
+
+-- this should error:
+select current_setting('nosuch.setting');
+
+-- this should return 'fallback'
+select current_setting('nosuch.setting','fallback');
+
+-- this should return 'nada', not 'fallback'
+set nosuch.setting = 'nada';
+select current_setting('nosuch.setting','fallback');
-- 
2.3.3




В списке pgsql-hackers по дате отправления:

Предыдущее
От: Bruce Momjian
Дата:
Сообщение: Re: Add regression tests for autocommit-off mode for psql and fix some omissions
Следующее
От: Bruce Momjian
Дата:
Сообщение: Re: proposal: doc: simplify examples of dynamic SQL