Remove regex_flavor GUC, so that regular expressions are always "advanced"

style by default.  Per discussion, there seems to be hardly anything that
really relies on being able to change the regex flavor, so the ability to
select it via embedded options ought to be enough for any stragglers.
Also, if we didn't remove the GUC, we'd really be morally obligated to
mark the regex functions non-immutable, which'd possibly create performance
issues.
This commit is contained in:
Tom Lane 2009-10-21 20:38:58 +00:00
parent 289e2905c8
commit ab61df9e52
10 changed files with 114 additions and 189 deletions

View File

@ -1,4 +1,4 @@
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.231 2009/10/21 20:22:38 tgl Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.232 2009/10/21 20:38:58 tgl Exp $ -->
<chapter Id="runtime-config">
<title>Server Configuration</title>
@ -4772,24 +4772,6 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir'
</listitem>
</varlistentry>
<varlistentry id="guc-regex-flavor" xreflabel="regex_flavor">
<term><varname>regex_flavor</varname> (<type>enum</type>)</term>
<indexterm><primary>regular expressions</></>
<indexterm>
<primary><varname>regex_flavor</> configuration parameter</primary>
</indexterm>
<listitem>
<para>
The regular expression <quote>flavor</> can be set to
<literal>advanced</>, <literal>extended</>, or <literal>basic</>.
The default is <literal>advanced</>. The <literal>extended</>
setting might be useful for exact backwards compatibility with
pre-7.4 releases of <productname>PostgreSQL</>. See
<xref linkend="posix-syntax-details"> for details.
</para>
</listitem>
</varlistentry>
<varlistentry id="guc-sql-inheritance" xreflabel="sql_inheritance">
<term><varname>sql_inheritance</varname> (<type>boolean</type>)</term>
<indexterm>

View File

@ -1,4 +1,4 @@
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.490 2009/10/13 22:46:13 petere Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.491 2009/10/21 20:38:58 tgl Exp $ -->
<chapter id="functions">
<title>Functions and Operators</title>
@ -3308,8 +3308,7 @@ substring('foobar' from '#"o_b#"%' for '#') <lineannotation>NULL</lineannotat
<para>
<acronym>POSIX</acronym> regular expressions provide a more
powerful means for
pattern matching than the <function>LIKE</function> and
powerful means for pattern matching than the <function>LIKE</function> and
<function>SIMILAR TO</> operators.
Many Unix tools such as <command>egrep</command>,
<command>sed</command>, or <command>awk</command> use a pattern
@ -3572,12 +3571,12 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', E'\\s*') AS foo;
<note>
<para>
The form of regular expressions accepted by
<productname>PostgreSQL</> can be chosen by setting the <xref
linkend="guc-regex-flavor"> run-time parameter. The usual
setting is <literal>advanced</>, but one might choose
<literal>extended</> for backwards compatibility with
pre-7.4 releases of <productname>PostgreSQL</>.
<productname>PostgreSQL</> always initially presumes that a regular
expression follows the ARE rules. However, the more limited ERE or
BRE rules can be chosen by prepending an <firstterm>embedded option</>
to the RE pattern, as described in <xref linkend="posix-metasyntax">.
This can be useful for compatibility with applications that expect
exactly the <acronym>POSIX</acronym> 1003.2 rules.
</para>
</note>
@ -4278,7 +4277,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', E'\\s*') AS foo;
<entry> (where <replaceable>m</> is a nonzero digit, and
<replaceable>nn</> is some more digits, and the decimal value
<replaceable>mnn</> is not greater than the number of closing capturing
parentheses seen so far)
parentheses seen so far)
a back reference to the <replaceable>mnn</>'th subexpression </entry>
</row>
</tbody>
@ -4310,12 +4309,12 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', E'\\s*') AS foo;
</para>
<para>
Normally the flavor of RE being used is determined by
<varname>regex_flavor</>.
However, this can be overridden by a <firstterm>director</> prefix.
An RE can begin with one of two special <firstterm>director</> prefixes.
If an RE begins with <literal>***:</>,
the rest of the RE is taken as an ARE regardless of
<varname>regex_flavor</>.
the rest of the RE is taken as an ARE. (This normally has no effect in
<productname>PostgreSQL</>, since REs are assumed to be AREs;
but it does have an effect if ERE or BRE mode had been specified by
the <replaceable>flags</> parameter to a regex function.)
If an RE begins with <literal>***=</>,
the rest of the RE is taken to be a literal string,
with all characters considered ordinary characters.
@ -4326,10 +4325,14 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', E'\\s*') AS foo;
a sequence <literal>(?</><replaceable>xyz</><literal>)</>
(where <replaceable>xyz</> is one or more alphabetic characters)
specifies options affecting the rest of the RE.
These options override any previously determined options (including
both the RE flavor and case sensitivity).
These options override any previously determined options &mdash;
in particular, they can override the case-sensitivity behavior implied by
a regex operator, or the <replaceable>flags</> parameter to a regex
function.
The available option letters are
shown in <xref linkend="posix-embedded-options-table">.
Note that these same option letters are used in the <replaceable>flags</>
parameters of regex functions.
</para>
<table id="posix-embedded-options-table">
@ -4700,10 +4703,6 @@ SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
</para>
</listitem>
</itemizedlist>
While these differences are unlikely to create a problem for most
applications, you can avoid them if necessary by
setting <varname>regex_flavor</> to <literal>extended</>.
</para>
</sect3>

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/regexp.c,v 1.83 2009/10/10 03:50:15 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/regexp.c,v 1.84 2009/10/21 20:38:58 tgl Exp $
*
* Alistair Crooks added the code for the regex caching
* agc - cached the regular expressions used - there's a good chance
@ -39,10 +39,6 @@
(PG_NARGS() > (_n) ? PG_GETARG_TEXT_PP(_n) : NULL)
/* GUC-settable flavor parameter */
int regex_flavor = REG_ADVANCED;
/* all the options of interest for regex functions */
typedef struct pg_re_flags
{
@ -347,8 +343,8 @@ RE_compile_and_execute(text *text_re, char *dat, int dat_len,
static void
parse_re_flags(pg_re_flags *flags, text *opts)
{
/* regex_flavor is always folded into the compile flags */
flags->cflags = regex_flavor;
/* regex flavor is always folded into the compile flags */
flags->cflags = REG_ADVANCED;
flags->glob = false;
if (opts)
@ -414,16 +410,6 @@ parse_re_flags(pg_re_flags *flags, text *opts)
}
/*
* report whether regex_flavor is currently BASIC
*/
bool
regex_flavor_is_basic(void)
{
return (regex_flavor == REG_BASIC);
}
/*
* interface routines called by the function manager
*/
@ -437,7 +423,7 @@ nameregexeq(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(RE_compile_and_execute(p,
NameStr(*n),
strlen(NameStr(*n)),
regex_flavor,
REG_ADVANCED,
0, NULL));
}
@ -450,7 +436,7 @@ nameregexne(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(!RE_compile_and_execute(p,
NameStr(*n),
strlen(NameStr(*n)),
regex_flavor,
REG_ADVANCED,
0, NULL));
}
@ -463,7 +449,7 @@ textregexeq(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(RE_compile_and_execute(p,
VARDATA_ANY(s),
VARSIZE_ANY_EXHDR(s),
regex_flavor,
REG_ADVANCED,
0, NULL));
}
@ -476,7 +462,7 @@ textregexne(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(!RE_compile_and_execute(p,
VARDATA_ANY(s),
VARSIZE_ANY_EXHDR(s),
regex_flavor,
REG_ADVANCED,
0, NULL));
}
@ -496,7 +482,7 @@ nameicregexeq(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(RE_compile_and_execute(p,
NameStr(*n),
strlen(NameStr(*n)),
regex_flavor | REG_ICASE,
REG_ADVANCED | REG_ICASE,
0, NULL));
}
@ -509,7 +495,7 @@ nameicregexne(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(!RE_compile_and_execute(p,
NameStr(*n),
strlen(NameStr(*n)),
regex_flavor | REG_ICASE,
REG_ADVANCED | REG_ICASE,
0, NULL));
}
@ -522,7 +508,7 @@ texticregexeq(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(RE_compile_and_execute(p,
VARDATA_ANY(s),
VARSIZE_ANY_EXHDR(s),
regex_flavor | REG_ICASE,
REG_ADVANCED | REG_ICASE,
0, NULL));
}
@ -535,7 +521,7 @@ texticregexne(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(!RE_compile_and_execute(p,
VARDATA_ANY(s),
VARSIZE_ANY_EXHDR(s),
regex_flavor | REG_ICASE,
REG_ADVANCED | REG_ICASE,
0, NULL));
}
@ -555,7 +541,7 @@ textregexsubstr(PG_FUNCTION_ARGS)
eo;
/* Compile RE */
re = RE_compile_and_cache(p, regex_flavor);
re = RE_compile_and_cache(p, REG_ADVANCED);
/*
* We pass two regmatch_t structs to get info about the overall match and
@ -611,7 +597,7 @@ textregexreplace_noopt(PG_FUNCTION_ARGS)
text *r = PG_GETARG_TEXT_PP(2);
regex_t *re;
re = RE_compile_and_cache(p, regex_flavor);
re = RE_compile_and_cache(p, REG_ADVANCED);
PG_RETURN_TEXT_P(replace_text_regexp(s, (void *) re, r, false));
}
@ -684,12 +670,10 @@ similar_escape(PG_FUNCTION_ARGS)
/*----------
* We surround the transformed input string with
* ***:^(?: ... )$
* which is bizarre enough to require some explanation. "***:" is a
* director prefix to force the regex to be treated as an ARE regardless
* of the current regex_flavor setting. We need "^" and "$" to force
* the pattern to match the entire input string as per SQL99 spec. The
* "(?:" and ")" are a non-capturing set of parens; we have to have
* ^(?: ... )$
* which requires some explanation. We need "^" and "$" to force
* the pattern to match the entire input string as per SQL99 spec.
* The "(?:" and ")" are a non-capturing set of parens; we have to have
* parens in case the string contains "|", else the "^" and "$" will
* be bound into the first and last alternatives which is not what we
* want, and the parens must be non capturing because we don't want them
@ -701,13 +685,9 @@ similar_escape(PG_FUNCTION_ARGS)
* We need room for the prefix/postfix plus as many as 2 output bytes per
* input byte
*/
result = (text *) palloc(VARHDRSZ + 10 + 2 * plen);
result = (text *) palloc(VARHDRSZ + 6 + 2 * plen);
r = VARDATA(result);
*r++ = '*';
*r++ = '*';
*r++ = '*';
*r++ = ':';
*r++ = '^';
*r++ = '(';
*r++ = '?';

View File

@ -15,7 +15,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.262 2009/08/04 16:08:36 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.263 2009/10/21 20:38:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -4580,7 +4580,6 @@ regex_fixed_prefix(Const *patt_const, bool case_insensitive,
char *patt;
char *rest;
Oid typeid = patt_const->consttype;
bool is_basic = regex_flavor_is_basic();
bool is_multibyte = (pg_database_encoding_max_length() > 1);
/*
@ -4598,14 +4597,12 @@ regex_fixed_prefix(Const *patt_const, bool case_insensitive,
/*
* Check for ARE director prefix. It's worth our trouble to recognize
* this because similar_escape() uses it.
* this because similar_escape() used to use it, and some other code
* might still use it, to force ARE mode.
*/
pos = 0;
if (strncmp(patt, "***:", 4) == 0)
{
pos = 4;
is_basic = false;
}
/* Pattern must be anchored left */
if (patt[pos] != '^')
@ -4641,17 +4638,11 @@ regex_fixed_prefix(Const *patt_const, bool case_insensitive,
/*
* We special-case the syntax '^(...)$' because psql uses it. But beware:
* in BRE mode these parentheses are just ordinary characters. Also,
* sequences beginning "(?" are not what they seem, unless they're "(?:".
* (We should recognize that, too, because of similar_escape().)
*
* Note: it's a bit bogus to be depending on the current regex_flavor
* setting here, because the setting could change before the pattern is
* used. We minimize the risk by trusting the flavor as little as we can,
* but perhaps it would be a good idea to get rid of the "basic" setting.
* (We must recognize that because of similar_escape().)
*/
have_leading_paren = false;
if (patt[pos] == '(' && !is_basic &&
if (patt[pos] == '(' &&
(patt[pos + 1] != '?' || patt[pos + 2] == ':'))
{
have_leading_paren = true;
@ -4691,12 +4682,10 @@ regex_fixed_prefix(Const *patt_const, bool case_insensitive,
/*
* Check for quantifiers. Except for +, this means the preceding
* character is optional, so we must remove it from the prefix too!
* Note: in BREs, \{ is a quantifier.
*/
if (patt[pos] == '*' ||
patt[pos] == '?' ||
patt[pos] == '{' ||
(patt[pos] == '\\' && patt[pos + 1] == '{'))
patt[pos] == '{')
{
match_pos = prev_match_pos;
pos = prev_pos;
@ -4711,14 +4700,13 @@ regex_fixed_prefix(Const *patt_const, bool case_insensitive,
/*
* Normally, backslash quotes the next character. But in AREs,
* backslash followed by alphanumeric is an escape, not a quoted
* character. Must treat it as having multiple possible matches. In
* BREs, \( is a parenthesis, so don't trust that either. Note: since
* only ASCII alphanumerics are escapes, we don't have to be paranoid
* about multibyte here.
* character. Must treat it as having multiple possible matches.
* Note: since only ASCII alphanumerics are escapes, we don't have to
* be paranoid about multibyte here.
*/
if (patt[pos] == '\\')
{
if (isalnum((unsigned char) patt[pos + 1]) || patt[pos + 1] == '(')
if (isalnum((unsigned char) patt[pos + 1]))
break;
pos++;
if (patt[pos] == '\0')

View File

@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>.
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.522 2009/10/21 20:22:38 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.523 2009/10/21 20:38:58 tgl Exp $
*
*--------------------------------------------------------------------
*/
@ -54,7 +54,6 @@
#include "postmaster/postmaster.h"
#include "postmaster/syslogger.h"
#include "postmaster/walwriter.h"
#include "regex/regex.h"
#include "storage/bufmgr.h"
#include "storage/fd.h"
#include "tcop/tcopprot.h"
@ -248,13 +247,6 @@ static const struct config_enum_entry log_statement_options[] = {
{NULL, 0, false}
};
static const struct config_enum_entry regex_flavor_options[] = {
{"advanced", REG_ADVANCED, false},
{"extended", REG_EXTENDED, false},
{"basic", REG_BASIC, false},
{NULL, 0, false}
};
static const struct config_enum_entry isolation_level_options[] = {
{"serializable", XACT_SERIALIZABLE, false},
{"repeatable read", XACT_REPEATABLE_READ, false},
@ -2658,15 +2650,6 @@ static struct config_enum ConfigureNamesEnum[] =
},
#endif
{
{"regex_flavor", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
gettext_noop("Sets the regular expression \"flavor\"."),
NULL
},
&regex_flavor,
REG_ADVANCED, regex_flavor_options, NULL, NULL
},
{
{"session_replication_role", PGC_SUSET, CLIENT_CONN_STATEMENT,
gettext_noop("Sets the session's behavior for triggers and rewrite rules."),

View File

@ -488,7 +488,6 @@
#backslash_quote = safe_encoding # on, off, or safe_encoding
#default_with_oids = off
#escape_string_warning = on
#regex_flavor = advanced # advanced, extended, or basic
#sql_inheritance = on
#standard_conforming_strings = off
#synchronize_seqscans = on

View File

@ -29,7 +29,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $PostgreSQL: pgsql/src/include/regex/regex.h,v 1.31 2009/06/11 14:49:12 momjian Exp $
* $PostgreSQL: pgsql/src/include/regex/regex.h,v 1.32 2009/10/21 20:38:58 tgl Exp $
*/
/*
@ -166,9 +166,4 @@ extern int pg_regexec(regex_t *, const pg_wchar *, size_t, size_t, rm_detail_t *
extern void pg_regfree(regex_t *);
extern size_t pg_regerror(int, const regex_t *, char *, size_t);
/*
* guc configuration variables
*/
extern int regex_flavor;
#endif /* _REGEX_H_ */

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.340 2009/10/09 21:02:56 petere Exp $
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.341 2009/10/21 20:38:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -525,7 +525,6 @@ extern Datum regexp_split_to_table(PG_FUNCTION_ARGS);
extern Datum regexp_split_to_table_no_flags(PG_FUNCTION_ARGS);
extern Datum regexp_split_to_array(PG_FUNCTION_ARGS);
extern Datum regexp_split_to_array_no_flags(PG_FUNCTION_ARGS);
extern bool regex_flavor_is_basic(void);
/* regproc.c */
extern Datum regprocin(PG_FUNCTION_ARGS);

View File

@ -607,95 +607,95 @@ DROP ROLE temp_reset_user;
--
-- Tests for function-local GUC settings
--
set regex_flavor = advanced;
set work_mem = '3MB';
create function report_guc(text) returns text as
$$ select current_setting($1) $$ language sql
set regex_flavor = basic;
select report_guc('regex_flavor'), current_setting('regex_flavor');
set work_mem = '1MB';
select report_guc('work_mem'), current_setting('work_mem');
report_guc | current_setting
------------+-----------------
basic | advanced
1MB | 3MB
(1 row)
-- this should draw only a warning
alter function report_guc(text) set search_path = no_such_schema;
NOTICE: schema "no_such_schema" does not exist
-- with error occurring here
select report_guc('regex_flavor'), current_setting('regex_flavor');
select report_guc('work_mem'), current_setting('work_mem');
ERROR: schema "no_such_schema" does not exist
alter function report_guc(text) reset search_path set regex_flavor = extended;
select report_guc('regex_flavor'), current_setting('regex_flavor');
alter function report_guc(text) reset search_path set work_mem = '2MB';
select report_guc('work_mem'), current_setting('work_mem');
report_guc | current_setting
------------+-----------------
extended | advanced
2MB | 3MB
(1 row)
alter function report_guc(text) reset all;
select report_guc('regex_flavor'), current_setting('regex_flavor');
select report_guc('work_mem'), current_setting('work_mem');
report_guc | current_setting
------------+-----------------
advanced | advanced
3MB | 3MB
(1 row)
-- SET LOCAL is restricted by a function SET option
create or replace function myfunc(int) returns text as $$
begin
set local regex_flavor = extended;
return current_setting('regex_flavor');
set local work_mem = '2MB';
return current_setting('work_mem');
end $$
language plpgsql
set regex_flavor = basic;
select myfunc(0), current_setting('regex_flavor');
myfunc | current_setting
----------+-----------------
extended | advanced
set work_mem = '1MB';
select myfunc(0), current_setting('work_mem');
myfunc | current_setting
--------+-----------------
2MB | 3MB
(1 row)
alter function myfunc(int) reset all;
select myfunc(0), current_setting('regex_flavor');
myfunc | current_setting
----------+-----------------
extended | extended
select myfunc(0), current_setting('work_mem');
myfunc | current_setting
--------+-----------------
2MB | 2MB
(1 row)
set regex_flavor = advanced;
set work_mem = '3MB';
-- but SET isn't
create or replace function myfunc(int) returns text as $$
begin
set regex_flavor = extended;
return current_setting('regex_flavor');
set work_mem = '2MB';
return current_setting('work_mem');
end $$
language plpgsql
set regex_flavor = basic;
select myfunc(0), current_setting('regex_flavor');
myfunc | current_setting
----------+-----------------
extended | extended
set work_mem = '1MB';
select myfunc(0), current_setting('work_mem');
myfunc | current_setting
--------+-----------------
2MB | 2MB
(1 row)
set regex_flavor = advanced;
set work_mem = '3MB';
-- it should roll back on error, though
create or replace function myfunc(int) returns text as $$
begin
set regex_flavor = extended;
set work_mem = '2MB';
perform 1/$1;
return current_setting('regex_flavor');
return current_setting('work_mem');
end $$
language plpgsql
set regex_flavor = basic;
set work_mem = '1MB';
select myfunc(0);
ERROR: division by zero
CONTEXT: SQL statement "SELECT 1/ $1 "
PL/pgSQL function "myfunc" line 3 at PERFORM
select current_setting('regex_flavor');
select current_setting('work_mem');
current_setting
-----------------
advanced
3MB
(1 row)
select myfunc(1), current_setting('regex_flavor');
myfunc | current_setting
----------+-----------------
extended | extended
select myfunc(1), current_setting('work_mem');
myfunc | current_setting
--------+-----------------
2MB | 2MB
(1 row)

View File

@ -186,68 +186,68 @@ DROP ROLE temp_reset_user;
-- Tests for function-local GUC settings
--
set regex_flavor = advanced;
set work_mem = '3MB';
create function report_guc(text) returns text as
$$ select current_setting($1) $$ language sql
set regex_flavor = basic;
set work_mem = '1MB';
select report_guc('regex_flavor'), current_setting('regex_flavor');
select report_guc('work_mem'), current_setting('work_mem');
-- this should draw only a warning
alter function report_guc(text) set search_path = no_such_schema;
-- with error occurring here
select report_guc('regex_flavor'), current_setting('regex_flavor');
select report_guc('work_mem'), current_setting('work_mem');
alter function report_guc(text) reset search_path set regex_flavor = extended;
alter function report_guc(text) reset search_path set work_mem = '2MB';
select report_guc('regex_flavor'), current_setting('regex_flavor');
select report_guc('work_mem'), current_setting('work_mem');
alter function report_guc(text) reset all;
select report_guc('regex_flavor'), current_setting('regex_flavor');
select report_guc('work_mem'), current_setting('work_mem');
-- SET LOCAL is restricted by a function SET option
create or replace function myfunc(int) returns text as $$
begin
set local regex_flavor = extended;
return current_setting('regex_flavor');
set local work_mem = '2MB';
return current_setting('work_mem');
end $$
language plpgsql
set regex_flavor = basic;
set work_mem = '1MB';
select myfunc(0), current_setting('regex_flavor');
select myfunc(0), current_setting('work_mem');
alter function myfunc(int) reset all;
select myfunc(0), current_setting('regex_flavor');
select myfunc(0), current_setting('work_mem');
set regex_flavor = advanced;
set work_mem = '3MB';
-- but SET isn't
create or replace function myfunc(int) returns text as $$
begin
set regex_flavor = extended;
return current_setting('regex_flavor');
set work_mem = '2MB';
return current_setting('work_mem');
end $$
language plpgsql
set regex_flavor = basic;
set work_mem = '1MB';
select myfunc(0), current_setting('regex_flavor');
select myfunc(0), current_setting('work_mem');
set regex_flavor = advanced;
set work_mem = '3MB';
-- it should roll back on error, though
create or replace function myfunc(int) returns text as $$
begin
set regex_flavor = extended;
set work_mem = '2MB';
perform 1/$1;
return current_setting('regex_flavor');
return current_setting('work_mem');
end $$
language plpgsql
set regex_flavor = basic;
set work_mem = '1MB';
select myfunc(0);
select current_setting('regex_flavor');
select myfunc(1), current_setting('regex_flavor');
select current_setting('work_mem');
select myfunc(1), current_setting('work_mem');