Add an optional missing_ok argument to SQL function current_setting().
This allows convenient checking for existence of a GUC from SQL, which is particularly useful when dealing with custom variables. David Christensen, reviewed by Jeevan Chalke
This commit is contained in:
parent
7261172430
commit
10fb48d66d
@ -363,7 +363,7 @@ tsa_tsearch2(PG_FUNCTION_ARGS)
|
|||||||
tgargs[i + 1] = trigger->tgargs[i];
|
tgargs[i + 1] = trigger->tgargs[i];
|
||||||
|
|
||||||
tgargs[1] = pstrdup(GetConfigOptionByName("default_text_search_config",
|
tgargs[1] = pstrdup(GetConfigOptionByName("default_text_search_config",
|
||||||
NULL));
|
NULL, false));
|
||||||
tgargs_old = trigger->tgargs;
|
tgargs_old = trigger->tgargs;
|
||||||
trigger->tgargs = tgargs;
|
trigger->tgargs = tgargs;
|
||||||
trigger->tgnargs++;
|
trigger->tgnargs++;
|
||||||
|
@ -16444,7 +16444,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
|
|||||||
<indexterm>
|
<indexterm>
|
||||||
<primary>current_setting</primary>
|
<primary>current_setting</primary>
|
||||||
</indexterm>
|
</indexterm>
|
||||||
<literal><function>current_setting(<parameter>setting_name</parameter>)</function></literal>
|
<literal><function>current_setting(<parameter>setting_name</parameter> [, <parameter>missing_ok</parameter> ])</function></literal>
|
||||||
</entry>
|
</entry>
|
||||||
<entry><type>text</type></entry>
|
<entry><type>text</type></entry>
|
||||||
<entry>get current value of setting</entry>
|
<entry>get current value of setting</entry>
|
||||||
@ -16492,6 +16492,11 @@ SELECT current_setting('datestyle');
|
|||||||
ISO, MDY
|
ISO, MDY
|
||||||
(1 row)
|
(1 row)
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
|
If there is no setting named <parameter>setting_name</parameter>,
|
||||||
|
<function>current_setting</function> throws an error
|
||||||
|
unless <parameter>missing_ok</parameter> is supplied and is
|
||||||
|
<literal>true</literal>.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
@ -7131,7 +7131,7 @@ ExtractSetVariableArgs(VariableSetStmt *stmt)
|
|||||||
case VAR_SET_VALUE:
|
case VAR_SET_VALUE:
|
||||||
return flatten_set_variable_args(stmt->name, stmt->args);
|
return flatten_set_variable_args(stmt->name, stmt->args);
|
||||||
case VAR_SET_CURRENT:
|
case VAR_SET_CURRENT:
|
||||||
return GetConfigOptionByName(stmt->name, NULL);
|
return GetConfigOptionByName(stmt->name, NULL, false);
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -7200,7 +7200,7 @@ set_config_by_name(PG_FUNCTION_ARGS)
|
|||||||
true, 0, false);
|
true, 0, false);
|
||||||
|
|
||||||
/* get the new current value */
|
/* get the new current value */
|
||||||
new_value = GetConfigOptionByName(name, NULL);
|
new_value = GetConfigOptionByName(name, NULL, false);
|
||||||
|
|
||||||
/* Convert return string to text */
|
/* Convert return string to text */
|
||||||
PG_RETURN_TEXT_P(cstring_to_text(new_value));
|
PG_RETURN_TEXT_P(cstring_to_text(new_value));
|
||||||
@ -7627,7 +7627,7 @@ GetPGVariableResultDesc(const char *name)
|
|||||||
const char *varname;
|
const char *varname;
|
||||||
|
|
||||||
/* Get the canonical spelling of name */
|
/* Get the canonical spelling of name */
|
||||||
(void) GetConfigOptionByName(name, &varname);
|
(void) GetConfigOptionByName(name, &varname, false);
|
||||||
|
|
||||||
/* need a tuple descriptor representing a single TEXT column */
|
/* need a tuple descriptor representing a single TEXT column */
|
||||||
tupdesc = CreateTemplateTupleDesc(1, false);
|
tupdesc = CreateTemplateTupleDesc(1, false);
|
||||||
@ -7650,7 +7650,7 @@ ShowGUCConfigOption(const char *name, DestReceiver *dest)
|
|||||||
char *value;
|
char *value;
|
||||||
|
|
||||||
/* Get the value and canonical spelling of name */
|
/* Get the value and canonical spelling of name */
|
||||||
value = GetConfigOptionByName(name, &varname);
|
value = GetConfigOptionByName(name, &varname, false);
|
||||||
|
|
||||||
/* need a tuple descriptor representing a single TEXT column */
|
/* need a tuple descriptor representing a single TEXT column */
|
||||||
tupdesc = CreateTemplateTupleDesc(1, false);
|
tupdesc = CreateTemplateTupleDesc(1, false);
|
||||||
@ -7734,19 +7734,30 @@ ShowAllGUCConfig(DestReceiver *dest)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return GUC variable value by name; optionally return canonical
|
* Return GUC variable value by name; optionally return canonical form of
|
||||||
* form of name. Return value is palloc'd.
|
* name. If the GUC is unset, then throw an error unless missing_ok is true,
|
||||||
|
* in which case return NULL. Return value is palloc'd (but *varname isn't).
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
GetConfigOptionByName(const char *name, const char **varname)
|
GetConfigOptionByName(const char *name, const char **varname, bool missing_ok)
|
||||||
{
|
{
|
||||||
struct config_generic *record;
|
struct config_generic *record;
|
||||||
|
|
||||||
record = find_option(name, false, ERROR);
|
record = find_option(name, false, ERROR);
|
||||||
if (record == NULL)
|
if (record == NULL)
|
||||||
|
{
|
||||||
|
if (missing_ok)
|
||||||
|
{
|
||||||
|
if (varname)
|
||||||
|
*varname = NULL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||||
errmsg("unrecognized configuration parameter \"%s\"", name)));
|
errmsg("unrecognized configuration parameter \"%s\"", name)));
|
||||||
|
}
|
||||||
|
|
||||||
if ((record->flags & GUC_SUPERUSER_ONLY) && !superuser())
|
if ((record->flags & GUC_SUPERUSER_ONLY) && !superuser())
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||||
@ -8033,14 +8044,34 @@ GetNumConfigOptions(void)
|
|||||||
Datum
|
Datum
|
||||||
show_config_by_name(PG_FUNCTION_ARGS)
|
show_config_by_name(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
char *varname;
|
char *varname = TextDatumGetCString(PG_GETARG_DATUM(0));
|
||||||
char *varval;
|
char *varval;
|
||||||
|
|
||||||
/* Get the GUC variable name */
|
/* Get the value */
|
||||||
varname = TextDatumGetCString(PG_GETARG_DATUM(0));
|
varval = GetConfigOptionByName(varname, NULL, false);
|
||||||
|
|
||||||
|
/* Convert to text */
|
||||||
|
PG_RETURN_TEXT_P(cstring_to_text(varval));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* show_config_by_name_missing_ok - equiv to SHOW X command but implemented as
|
||||||
|
* a function. If X does not exist, suppress the error and just return NULL
|
||||||
|
* if missing_ok is TRUE.
|
||||||
|
*/
|
||||||
|
Datum
|
||||||
|
show_config_by_name_missing_ok(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
char *varname = TextDatumGetCString(PG_GETARG_DATUM(0));
|
||||||
|
bool missing_ok = PG_GETARG_BOOL(1);
|
||||||
|
char *varval;
|
||||||
|
|
||||||
/* Get the value */
|
/* Get the value */
|
||||||
varval = GetConfigOptionByName(varname, NULL);
|
varval = GetConfigOptionByName(varname, NULL, missing_ok);
|
||||||
|
|
||||||
|
/* return NULL if no such variable */
|
||||||
|
if (varval == NULL)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
/* Convert to text */
|
/* Convert to text */
|
||||||
PG_RETURN_TEXT_P(cstring_to_text(varval));
|
PG_RETURN_TEXT_P(cstring_to_text(varval));
|
||||||
|
@ -53,6 +53,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 201506282
|
#define CATALOG_VERSION_NO 201507021
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -3067,6 +3067,8 @@ DESCR("convert bitstring to int8");
|
|||||||
|
|
||||||
DATA(insert OID = 2077 ( current_setting PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 25 "25" _null_ _null_ _null_ _null_ _null_ show_config_by_name _null_ _null_ _null_ ));
|
DATA(insert OID = 2077 ( current_setting PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 25 "25" _null_ _null_ _null_ _null_ _null_ show_config_by_name _null_ _null_ _null_ ));
|
||||||
DESCR("SHOW X as a function");
|
DESCR("SHOW X as a function");
|
||||||
|
DATA(insert OID = 3294 ( current_setting PGNSP PGUID 12 1 0 0 0 f f f f t f s 2 0 25 "25 16" _null_ _null_ _null_ _null_ _null_ show_config_by_name_missing_ok _null_ _null_ _null_ ));
|
||||||
|
DESCR("SHOW X as a function, optionally no error for missing variable");
|
||||||
DATA(insert OID = 2078 ( set_config PGNSP PGUID 12 1 0 0 0 f f f f f f v 3 0 25 "25 25 16" _null_ _null_ _null_ _null_ _null_ set_config_by_name _null_ _null_ _null_ ));
|
DATA(insert OID = 2078 ( set_config PGNSP PGUID 12 1 0 0 0 f f f f f f v 3 0 25 "25 25 16" _null_ _null_ _null_ _null_ _null_ set_config_by_name _null_ _null_ _null_ ));
|
||||||
DESCR("SET X as a function");
|
DESCR("SET X as a function");
|
||||||
DATA(insert OID = 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,16}" "{o,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,pending_restart}" _null_ _null_ show_all_settings _null_ _null_ _null_ ));
|
DATA(insert OID = 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,16}" "{o,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,pending_restart}" _null_ _null_ show_all_settings _null_ _null_ _null_ ));
|
||||||
|
@ -1114,6 +1114,7 @@ extern Datum quote_nullable(PG_FUNCTION_ARGS);
|
|||||||
|
|
||||||
/* guc.c */
|
/* guc.c */
|
||||||
extern Datum show_config_by_name(PG_FUNCTION_ARGS);
|
extern Datum show_config_by_name(PG_FUNCTION_ARGS);
|
||||||
|
extern Datum show_config_by_name_missing_ok(PG_FUNCTION_ARGS);
|
||||||
extern Datum set_config_by_name(PG_FUNCTION_ARGS);
|
extern Datum set_config_by_name(PG_FUNCTION_ARGS);
|
||||||
extern Datum show_all_settings(PG_FUNCTION_ARGS);
|
extern Datum show_all_settings(PG_FUNCTION_ARGS);
|
||||||
extern Datum show_all_file_settings(PG_FUNCTION_ARGS);
|
extern Datum show_all_file_settings(PG_FUNCTION_ARGS);
|
||||||
|
@ -365,7 +365,8 @@ extern int set_config_option(const char *name, const char *value,
|
|||||||
GucAction action, bool changeVal, int elevel,
|
GucAction action, bool changeVal, int elevel,
|
||||||
bool is_reload);
|
bool is_reload);
|
||||||
extern void AlterSystemSetConfigFile(AlterSystemStmt *setstmt);
|
extern void AlterSystemSetConfigFile(AlterSystemStmt *setstmt);
|
||||||
extern char *GetConfigOptionByName(const char *name, const char **varname);
|
extern char *GetConfigOptionByName(const char *name, const char **varname,
|
||||||
|
bool missing_ok);
|
||||||
extern void GetConfigOptionByNum(int varnum, const char **values, bool *noshow);
|
extern void GetConfigOptionByNum(int varnum, const char **values, bool *noshow);
|
||||||
extern int GetNumConfigOptions(void);
|
extern int GetNumConfigOptions(void);
|
||||||
|
|
||||||
|
@ -720,6 +720,37 @@ select myfunc(1), current_setting('work_mem');
|
|||||||
2MB | 2MB
|
2MB | 2MB
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
-- check current_setting()'s behavior with invalid setting name
|
||||||
|
select current_setting('nosuch.setting'); -- FAIL
|
||||||
|
ERROR: unrecognized configuration parameter "nosuch.setting"
|
||||||
|
select current_setting('nosuch.setting', false); -- FAIL
|
||||||
|
ERROR: unrecognized configuration parameter "nosuch.setting"
|
||||||
|
select current_setting('nosuch.setting', true) is null;
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- after this, all three cases should yield 'nada'
|
||||||
|
set nosuch.setting = 'nada';
|
||||||
|
select current_setting('nosuch.setting');
|
||||||
|
current_setting
|
||||||
|
-----------------
|
||||||
|
nada
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select current_setting('nosuch.setting', false);
|
||||||
|
current_setting
|
||||||
|
-----------------
|
||||||
|
nada
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select current_setting('nosuch.setting', true);
|
||||||
|
current_setting
|
||||||
|
-----------------
|
||||||
|
nada
|
||||||
|
(1 row)
|
||||||
|
|
||||||
-- Normally, CREATE FUNCTION should complain about invalid values in
|
-- Normally, CREATE FUNCTION should complain about invalid values in
|
||||||
-- function SET options; but not if check_function_bodies is off,
|
-- function SET options; but not if check_function_bodies is off,
|
||||||
-- because that creates ordering hazards for pg_dump
|
-- because that creates ordering hazards for pg_dump
|
||||||
|
@ -258,6 +258,19 @@ select myfunc(0);
|
|||||||
select current_setting('work_mem');
|
select current_setting('work_mem');
|
||||||
select myfunc(1), current_setting('work_mem');
|
select myfunc(1), current_setting('work_mem');
|
||||||
|
|
||||||
|
-- check current_setting()'s behavior with invalid setting name
|
||||||
|
|
||||||
|
select current_setting('nosuch.setting'); -- FAIL
|
||||||
|
select current_setting('nosuch.setting', false); -- FAIL
|
||||||
|
select current_setting('nosuch.setting', true) is null;
|
||||||
|
|
||||||
|
-- after this, all three cases should yield 'nada'
|
||||||
|
set nosuch.setting = 'nada';
|
||||||
|
|
||||||
|
select current_setting('nosuch.setting');
|
||||||
|
select current_setting('nosuch.setting', false);
|
||||||
|
select current_setting('nosuch.setting', true);
|
||||||
|
|
||||||
-- Normally, CREATE FUNCTION should complain about invalid values in
|
-- Normally, CREATE FUNCTION should complain about invalid values in
|
||||||
-- function SET options; but not if check_function_bodies is off,
|
-- function SET options; but not if check_function_bodies is off,
|
||||||
-- because that creates ordering hazards for pg_dump
|
-- because that creates ordering hazards for pg_dump
|
||||||
|
Loading…
x
Reference in New Issue
Block a user