constants, identifiers, numbers, or comma-separated lists of
these, as appropriate for the particular parameter.
Values that are neither numbers nor valid identifiers must be quoted.
+ If the parameter accepts a list of values, <literal>NULL</literal>
+ can be written to specify an empty list.
<literal>DEFAULT</literal> can be written to specify removing the
parameter and its value from <filename>postgresql.auto.conf</filename>.
</para>
in <filename>postgresql.conf</filename>:
<programlisting>
ALTER SYSTEM RESET wal_level;
-</programlisting></para>
+</programlisting>
+ </para>
+
+ <para>
+ Set the list of preloaded extension modules to be empty:
+<programlisting>
+ALTER SYSTEM SET shared_preload_libraries TO NULL;
+</programlisting>
+ </para>
</refsect1>
<refsect1>
<refsynopsisdiv>
<synopsis>
-SET [ SESSION | LOCAL ] <replaceable class="parameter">configuration_parameter</replaceable> { TO | = } { <replaceable class="parameter">value</replaceable> | '<replaceable class="parameter">value</replaceable>' | DEFAULT }
-SET [ SESSION | LOCAL ] TIME ZONE { <replaceable class="parameter">value</replaceable> | '<replaceable class="parameter">value</replaceable>' | LOCAL | DEFAULT }
+SET [ SESSION | LOCAL ] <replaceable class="parameter">configuration_parameter</replaceable> { TO | = } { <replaceable class="parameter">value</replaceable> [, ...] | DEFAULT }
+SET [ SESSION | LOCAL ] TIME ZONE { <replaceable class="parameter">value</replaceable> | LOCAL | DEFAULT }
</synopsis>
</refsynopsisdiv>
<term><replaceable class="parameter">configuration_parameter</replaceable></term>
<listitem>
<para>
- Name of a settable run-time parameter. Available parameters are
+ Name of a settable configuration parameter. Available parameters are
documented in <xref linkend="runtime-config"/> and below.
</para>
</listitem>
<term><replaceable class="parameter">value</replaceable></term>
<listitem>
<para>
- New value of parameter. Values can be specified as string
+ New value of the parameter. Values can be specified as string
constants, identifiers, numbers, or comma-separated lists of
these, as appropriate for the particular parameter.
+ Values that are neither numbers nor valid identifiers must be quoted.
+ If the parameter accepts a list of values, <literal>NULL</literal>
+ can be written to specify an empty list.
<literal>DEFAULT</literal> can be written to specify
resetting the parameter to its default value (that is, whatever
value it would have had if no <command>SET</command> had been executed
Set the schema search path:
<programlisting>
SET search_path TO my_schema, public;
+</programlisting>
+ Note that this is not the same as
+<programlisting>
+SET search_path TO 'my_schema, public';
+</programlisting>
+ which would have the effect of setting <varname>search_path</varname>
+ to contain a single, probably-nonexistent schema name.
+ </para>
+
+ <para>
+ Set the list of temporary tablespace names to be empty:
+<programlisting>
+SET temp_tablespaces TO NULL;
</programlisting>
</para>
n->location = @3;
$$ = n;
}
+ | var_name TO NULL_P
+ {
+ VariableSetStmt *n = makeNode(VariableSetStmt);
+
+ n->kind = VAR_SET_VALUE;
+ n->name = $1;
+ n->args = list_make1(makeNullAConst(@3));
+ n->location = @3;
+ $$ = n;
+ }
+ | var_name '=' NULL_P
+ {
+ VariableSetStmt *n = makeNode(VariableSetStmt);
+
+ n->kind = VAR_SET_VALUE;
+ n->name = $1;
+ n->args = list_make1(makeNullAConst(@3));
+ n->location = @3;
+ $$ = n;
+ }
| var_name TO DEFAULT
{
VariableSetStmt *n = makeNode(VariableSetStmt);
* string literals. (The elements may be double-quoted as-is,
* but we can't just feed them to the SQL parser; it would do
* the wrong thing with elements that are zero-length or
- * longer than NAMEDATALEN.)
+ * longer than NAMEDATALEN.) Also, we need a special case for
+ * empty lists.
*
* Variables that are not so marked should just be emitted as
* simple string literals. If the variable is not known to
/* this shouldn't fail really */
elog(ERROR, "invalid list syntax in proconfig item");
}
+ /* Special case: represent an empty list as NULL */
+ if (namelist == NIL)
+ appendStringInfoString(&buf, "NULL");
foreach(lc, namelist)
{
char *curname = (char *) lfirst(lc);
nextp++; /* skip leading whitespace */
if (*nextp == '\0')
- return true; /* allow empty string */
+ return true; /* empty string represents empty list */
/* At the top of the loop, we are at start of a new identifier. */
do
nextp++; /* skip leading whitespace */
if (*nextp == '\0')
- return true; /* allow empty string */
+ return true; /* empty string represents empty list */
/* At the top of the loop, we are at start of a new directory. */
do
nextp++; /* skip leading whitespace */
if (*nextp == '\0')
- return true; /* allow empty string */
+ return true; /* empty string represents empty list */
/* At the top of the loop, we are at start of a new identifier. */
do
else
flags = 0;
- /* Complain if list input and non-list variable */
- if ((flags & GUC_LIST_INPUT) == 0 &&
- list_length(args) != 1)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("SET %s takes only one argument", name)));
+ /*
+ * Handle special cases for list input.
+ */
+ if (flags & GUC_LIST_INPUT)
+ {
+ /* NULL represents an empty list. */
+ if (list_length(args) == 1)
+ {
+ Node *arg = (Node *) linitial(args);
+
+ if (IsA(arg, A_Const) &&
+ ((A_Const *) arg)->isnull)
+ return pstrdup("");
+ }
+ }
+ else
+ {
+ /* Complain if list input and non-list variable. */
+ if (list_length(args) != 1)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("SET %s takes only one argument", name)));
+ }
initStringInfo(&buf);
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(arg));
con = (A_Const *) arg;
+ /* Complain if NULL is used with a non-list variable. */
+ if (con->isnull)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("NULL is an invalid value for %s", name)));
+
switch (nodeTag(&con->val))
{
case T_Integer:
Datum interval;
char *intervalout;
+ /* gram.y ensures this is only reachable for TIME ZONE */
+ Assert(!(flags & GUC_LIST_QUOTE));
+
typenameTypeIdAndMod(NULL, typeName, &typoid, &typmod);
Assert(typoid == INTERVALOID);
nextp++; /* skip leading whitespace */
if (*nextp == '\0')
- return true; /* allow empty string */
+ return true; /* empty string represents empty list */
/* At the top of the loop, we are at start of a new identifier. */
do
* elements as string literals. (The elements may be double-quoted as-is,
* but we can't just feed them to the SQL parser; it would do the wrong
* thing with elements that are zero-length or longer than NAMEDATALEN.)
+ * Also, we need a special case for empty lists.
*
* Variables that are not so marked should just be emitted as simple
* string literals. If the variable is not known to
/* this shouldn't fail really */
if (SplitGUCList(pos, ',', &namelist))
{
+ /* Special case: represent an empty list as NULL */
+ if (*namelist == NULL)
+ appendPQExpBufferStr(buf, "NULL");
for (nameptr = namelist; *nameptr; nameptr++)
{
if (nameptr != namelist)
* and then quote the elements as string literals. (The elements may
* be double-quoted as-is, but we can't just feed them to the SQL
* parser; it would do the wrong thing with elements that are
- * zero-length or longer than NAMEDATALEN.)
+ * zero-length or longer than NAMEDATALEN.) Also, we need a special
+ * case for empty lists.
*
* Variables that are not so marked should just be emitted as simple
* string literals. If the variable is not known to
/* this shouldn't fail really */
if (SplitGUCList(pos, ',', &namelist))
{
+ /* Special case: represent an empty list as NULL */
+ if (*namelist == NULL)
+ appendPQExpBufferStr(q, "NULL");
for (nameptr = namelist; *nameptr; nameptr++)
{
if (nameptr != namelist)
2006-08-13 12:34:56-07
(1 row)
+-- Check handling of list GUCs
+SET search_path = 'pg_catalog', Foo, 'Bar', '';
+SHOW search_path;
+ search_path
+----------------------------
+ pg_catalog, foo, "Bar", ""
+(1 row)
+
+SET search_path = null; -- means empty list
+SHOW search_path;
+ search_path
+-------------
+
+(1 row)
+
+SET search_path = null, null; -- syntax error
+ERROR: syntax error at or near ","
+LINE 1: SET search_path = null, null;
+ ^
+SET enable_seqscan = null; -- error
+ERROR: NULL is an invalid value for enable_seqscan
+RESET search_path;
-- SET LOCAL has no effect outside of a transaction
SET LOCAL vacuum_cost_delay TO 50;
WARNING: SET LOCAL can only be used in transaction blocks
SET extra_float_digits TO 2
SET work_mem TO '4MB'
SET datestyle to iso, mdy
+ SET temp_tablespaces to NULL
SET local_preload_libraries TO "Mixed/Case", 'c:/''a"/path', '', '0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789'
IMMUTABLE STRICT;
SELECT pg_get_functiondef('func_with_set_params()'::regprocedure);
SET extra_float_digits TO '2' +
SET work_mem TO '4MB' +
SET "DateStyle" TO 'iso, mdy' +
+ SET temp_tablespaces TO NULL +
SET local_preload_libraries TO 'Mixed/Case', 'c:/''a"/path', '', '0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789'+
AS $function$select 1;$function$ +
SHOW datestyle;
SELECT '2006-08-13 12:34:56'::timestamptz;
+-- Check handling of list GUCs
+SET search_path = 'pg_catalog', Foo, 'Bar', '';
+SHOW search_path;
+SET search_path = null; -- means empty list
+SHOW search_path;
+SET search_path = null, null; -- syntax error
+SET enable_seqscan = null; -- error
+RESET search_path;
+
-- SET LOCAL has no effect outside of a transaction
SET LOCAL vacuum_cost_delay TO 50;
SHOW vacuum_cost_delay;
SET extra_float_digits TO 2
SET work_mem TO '4MB'
SET datestyle to iso, mdy
+ SET temp_tablespaces to NULL
SET local_preload_libraries TO "Mixed/Case", 'c:/''a"/path', '', '0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789'
IMMUTABLE STRICT;
SELECT pg_get_functiondef('func_with_set_params()'::regprocedure);