mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-24 18:55:04 +08:00
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:
parent
289e2905c8
commit
ab61df9e52
@ -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">
|
<chapter Id="runtime-config">
|
||||||
<title>Server Configuration</title>
|
<title>Server Configuration</title>
|
||||||
@ -4772,24 +4772,6 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir'
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</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">
|
<varlistentry id="guc-sql-inheritance" xreflabel="sql_inheritance">
|
||||||
<term><varname>sql_inheritance</varname> (<type>boolean</type>)</term>
|
<term><varname>sql_inheritance</varname> (<type>boolean</type>)</term>
|
||||||
<indexterm>
|
<indexterm>
|
||||||
|
@ -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">
|
<chapter id="functions">
|
||||||
<title>Functions and Operators</title>
|
<title>Functions and Operators</title>
|
||||||
@ -3308,8 +3308,7 @@ substring('foobar' from '#"o_b#"%' for '#') <lineannotation>NULL</lineannotat
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
<acronym>POSIX</acronym> regular expressions provide a more
|
<acronym>POSIX</acronym> regular expressions provide a more
|
||||||
powerful means for
|
powerful means for pattern matching than the <function>LIKE</function> and
|
||||||
pattern matching than the <function>LIKE</function> and
|
|
||||||
<function>SIMILAR TO</> operators.
|
<function>SIMILAR TO</> operators.
|
||||||
Many Unix tools such as <command>egrep</command>,
|
Many Unix tools such as <command>egrep</command>,
|
||||||
<command>sed</command>, or <command>awk</command> use a pattern
|
<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>
|
<note>
|
||||||
<para>
|
<para>
|
||||||
The form of regular expressions accepted by
|
<productname>PostgreSQL</> always initially presumes that a regular
|
||||||
<productname>PostgreSQL</> can be chosen by setting the <xref
|
expression follows the ARE rules. However, the more limited ERE or
|
||||||
linkend="guc-regex-flavor"> run-time parameter. The usual
|
BRE rules can be chosen by prepending an <firstterm>embedded option</>
|
||||||
setting is <literal>advanced</>, but one might choose
|
to the RE pattern, as described in <xref linkend="posix-metasyntax">.
|
||||||
<literal>extended</> for backwards compatibility with
|
This can be useful for compatibility with applications that expect
|
||||||
pre-7.4 releases of <productname>PostgreSQL</>.
|
exactly the <acronym>POSIX</acronym> 1003.2 rules.
|
||||||
</para>
|
</para>
|
||||||
</note>
|
</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
|
<entry> (where <replaceable>m</> is a nonzero digit, and
|
||||||
<replaceable>nn</> is some more digits, and the decimal value
|
<replaceable>nn</> is some more digits, and the decimal value
|
||||||
<replaceable>mnn</> is not greater than the number of closing capturing
|
<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>
|
a back reference to the <replaceable>mnn</>'th subexpression </entry>
|
||||||
</row>
|
</row>
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -4310,12 +4309,12 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', E'\\s*') AS foo;
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Normally the flavor of RE being used is determined by
|
An RE can begin with one of two special <firstterm>director</> prefixes.
|
||||||
<varname>regex_flavor</>.
|
|
||||||
However, this can be overridden by a <firstterm>director</> prefix.
|
|
||||||
If an RE begins with <literal>***:</>,
|
If an RE begins with <literal>***:</>,
|
||||||
the rest of the RE is taken as an ARE regardless of
|
the rest of the RE is taken as an ARE. (This normally has no effect in
|
||||||
<varname>regex_flavor</>.
|
<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>***=</>,
|
If an RE begins with <literal>***=</>,
|
||||||
the rest of the RE is taken to be a literal string,
|
the rest of the RE is taken to be a literal string,
|
||||||
with all characters considered ordinary characters.
|
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>)</>
|
a sequence <literal>(?</><replaceable>xyz</><literal>)</>
|
||||||
(where <replaceable>xyz</> is one or more alphabetic characters)
|
(where <replaceable>xyz</> is one or more alphabetic characters)
|
||||||
specifies options affecting the rest of the RE.
|
specifies options affecting the rest of the RE.
|
||||||
These options override any previously determined options (including
|
These options override any previously determined options —
|
||||||
both the RE flavor and case sensitivity).
|
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
|
The available option letters are
|
||||||
shown in <xref linkend="posix-embedded-options-table">.
|
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>
|
</para>
|
||||||
|
|
||||||
<table id="posix-embedded-options-table">
|
<table id="posix-embedded-options-table">
|
||||||
@ -4700,10 +4703,6 @@ SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
|
|||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</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>
|
</para>
|
||||||
</sect3>
|
</sect3>
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* Alistair Crooks added the code for the regex caching
|
||||||
* agc - cached the regular expressions used - there's a good chance
|
* agc - cached the regular expressions used - there's a good chance
|
||||||
@ -39,10 +39,6 @@
|
|||||||
(PG_NARGS() > (_n) ? PG_GETARG_TEXT_PP(_n) : NULL)
|
(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 */
|
/* all the options of interest for regex functions */
|
||||||
typedef struct pg_re_flags
|
typedef struct pg_re_flags
|
||||||
{
|
{
|
||||||
@ -347,8 +343,8 @@ RE_compile_and_execute(text *text_re, char *dat, int dat_len,
|
|||||||
static void
|
static void
|
||||||
parse_re_flags(pg_re_flags *flags, text *opts)
|
parse_re_flags(pg_re_flags *flags, text *opts)
|
||||||
{
|
{
|
||||||
/* regex_flavor is always folded into the compile flags */
|
/* regex flavor is always folded into the compile flags */
|
||||||
flags->cflags = regex_flavor;
|
flags->cflags = REG_ADVANCED;
|
||||||
flags->glob = false;
|
flags->glob = false;
|
||||||
|
|
||||||
if (opts)
|
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
|
* interface routines called by the function manager
|
||||||
*/
|
*/
|
||||||
@ -437,7 +423,7 @@ nameregexeq(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_BOOL(RE_compile_and_execute(p,
|
PG_RETURN_BOOL(RE_compile_and_execute(p,
|
||||||
NameStr(*n),
|
NameStr(*n),
|
||||||
strlen(NameStr(*n)),
|
strlen(NameStr(*n)),
|
||||||
regex_flavor,
|
REG_ADVANCED,
|
||||||
0, NULL));
|
0, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -450,7 +436,7 @@ nameregexne(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_BOOL(!RE_compile_and_execute(p,
|
PG_RETURN_BOOL(!RE_compile_and_execute(p,
|
||||||
NameStr(*n),
|
NameStr(*n),
|
||||||
strlen(NameStr(*n)),
|
strlen(NameStr(*n)),
|
||||||
regex_flavor,
|
REG_ADVANCED,
|
||||||
0, NULL));
|
0, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -463,7 +449,7 @@ textregexeq(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_BOOL(RE_compile_and_execute(p,
|
PG_RETURN_BOOL(RE_compile_and_execute(p,
|
||||||
VARDATA_ANY(s),
|
VARDATA_ANY(s),
|
||||||
VARSIZE_ANY_EXHDR(s),
|
VARSIZE_ANY_EXHDR(s),
|
||||||
regex_flavor,
|
REG_ADVANCED,
|
||||||
0, NULL));
|
0, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,7 +462,7 @@ textregexne(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_BOOL(!RE_compile_and_execute(p,
|
PG_RETURN_BOOL(!RE_compile_and_execute(p,
|
||||||
VARDATA_ANY(s),
|
VARDATA_ANY(s),
|
||||||
VARSIZE_ANY_EXHDR(s),
|
VARSIZE_ANY_EXHDR(s),
|
||||||
regex_flavor,
|
REG_ADVANCED,
|
||||||
0, NULL));
|
0, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -496,7 +482,7 @@ nameicregexeq(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_BOOL(RE_compile_and_execute(p,
|
PG_RETURN_BOOL(RE_compile_and_execute(p,
|
||||||
NameStr(*n),
|
NameStr(*n),
|
||||||
strlen(NameStr(*n)),
|
strlen(NameStr(*n)),
|
||||||
regex_flavor | REG_ICASE,
|
REG_ADVANCED | REG_ICASE,
|
||||||
0, NULL));
|
0, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -509,7 +495,7 @@ nameicregexne(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_BOOL(!RE_compile_and_execute(p,
|
PG_RETURN_BOOL(!RE_compile_and_execute(p,
|
||||||
NameStr(*n),
|
NameStr(*n),
|
||||||
strlen(NameStr(*n)),
|
strlen(NameStr(*n)),
|
||||||
regex_flavor | REG_ICASE,
|
REG_ADVANCED | REG_ICASE,
|
||||||
0, NULL));
|
0, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -522,7 +508,7 @@ texticregexeq(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_BOOL(RE_compile_and_execute(p,
|
PG_RETURN_BOOL(RE_compile_and_execute(p,
|
||||||
VARDATA_ANY(s),
|
VARDATA_ANY(s),
|
||||||
VARSIZE_ANY_EXHDR(s),
|
VARSIZE_ANY_EXHDR(s),
|
||||||
regex_flavor | REG_ICASE,
|
REG_ADVANCED | REG_ICASE,
|
||||||
0, NULL));
|
0, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -535,7 +521,7 @@ texticregexne(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_BOOL(!RE_compile_and_execute(p,
|
PG_RETURN_BOOL(!RE_compile_and_execute(p,
|
||||||
VARDATA_ANY(s),
|
VARDATA_ANY(s),
|
||||||
VARSIZE_ANY_EXHDR(s),
|
VARSIZE_ANY_EXHDR(s),
|
||||||
regex_flavor | REG_ICASE,
|
REG_ADVANCED | REG_ICASE,
|
||||||
0, NULL));
|
0, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -555,7 +541,7 @@ textregexsubstr(PG_FUNCTION_ARGS)
|
|||||||
eo;
|
eo;
|
||||||
|
|
||||||
/* Compile RE */
|
/* 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
|
* 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);
|
text *r = PG_GETARG_TEXT_PP(2);
|
||||||
regex_t *re;
|
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));
|
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
|
* We surround the transformed input string with
|
||||||
* ***:^(?: ... )$
|
* ^(?: ... )$
|
||||||
* which is bizarre enough to require some explanation. "***:" is a
|
* which requires some explanation. We need "^" and "$" to force
|
||||||
* director prefix to force the regex to be treated as an ARE regardless
|
* the pattern to match the entire input string as per SQL99 spec.
|
||||||
* of the current regex_flavor setting. We need "^" and "$" to force
|
* The "(?:" and ")" are a non-capturing set of parens; we have to have
|
||||||
* 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
|
* parens in case the string contains "|", else the "^" and "$" will
|
||||||
* be bound into the first and last alternatives which is not what we
|
* 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
|
* 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
|
* We need room for the prefix/postfix plus as many as 2 output bytes per
|
||||||
* input byte
|
* input byte
|
||||||
*/
|
*/
|
||||||
result = (text *) palloc(VARHDRSZ + 10 + 2 * plen);
|
result = (text *) palloc(VARHDRSZ + 6 + 2 * plen);
|
||||||
r = VARDATA(result);
|
r = VARDATA(result);
|
||||||
|
|
||||||
*r++ = '*';
|
|
||||||
*r++ = '*';
|
|
||||||
*r++ = '*';
|
|
||||||
*r++ = ':';
|
|
||||||
*r++ = '^';
|
*r++ = '^';
|
||||||
*r++ = '(';
|
*r++ = '(';
|
||||||
*r++ = '?';
|
*r++ = '?';
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 *patt;
|
||||||
char *rest;
|
char *rest;
|
||||||
Oid typeid = patt_const->consttype;
|
Oid typeid = patt_const->consttype;
|
||||||
bool is_basic = regex_flavor_is_basic();
|
|
||||||
bool is_multibyte = (pg_database_encoding_max_length() > 1);
|
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
|
* 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;
|
pos = 0;
|
||||||
if (strncmp(patt, "***:", 4) == 0)
|
if (strncmp(patt, "***:", 4) == 0)
|
||||||
{
|
|
||||||
pos = 4;
|
pos = 4;
|
||||||
is_basic = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Pattern must be anchored left */
|
/* Pattern must be anchored left */
|
||||||
if (patt[pos] != '^')
|
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:
|
* 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 "(?:".
|
* sequences beginning "(?" are not what they seem, unless they're "(?:".
|
||||||
* (We should recognize that, too, because of similar_escape().)
|
* (We must recognize that 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.
|
|
||||||
*/
|
*/
|
||||||
have_leading_paren = false;
|
have_leading_paren = false;
|
||||||
if (patt[pos] == '(' && !is_basic &&
|
if (patt[pos] == '(' &&
|
||||||
(patt[pos + 1] != '?' || patt[pos + 2] == ':'))
|
(patt[pos + 1] != '?' || patt[pos + 2] == ':'))
|
||||||
{
|
{
|
||||||
have_leading_paren = true;
|
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
|
* Check for quantifiers. Except for +, this means the preceding
|
||||||
* character is optional, so we must remove it from the prefix too!
|
* character is optional, so we must remove it from the prefix too!
|
||||||
* Note: in BREs, \{ is a quantifier.
|
|
||||||
*/
|
*/
|
||||||
if (patt[pos] == '*' ||
|
if (patt[pos] == '*' ||
|
||||||
patt[pos] == '?' ||
|
patt[pos] == '?' ||
|
||||||
patt[pos] == '{' ||
|
patt[pos] == '{')
|
||||||
(patt[pos] == '\\' && patt[pos + 1] == '{'))
|
|
||||||
{
|
{
|
||||||
match_pos = prev_match_pos;
|
match_pos = prev_match_pos;
|
||||||
pos = prev_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,
|
* Normally, backslash quotes the next character. But in AREs,
|
||||||
* backslash followed by alphanumeric is an escape, not a quoted
|
* backslash followed by alphanumeric is an escape, not a quoted
|
||||||
* character. Must treat it as having multiple possible matches. In
|
* character. Must treat it as having multiple possible matches.
|
||||||
* BREs, \( is a parenthesis, so don't trust that either. Note: since
|
* Note: since only ASCII alphanumerics are escapes, we don't have to
|
||||||
* only ASCII alphanumerics are escapes, we don't have to be paranoid
|
* be paranoid about multibyte here.
|
||||||
* about multibyte here.
|
|
||||||
*/
|
*/
|
||||||
if (patt[pos] == '\\')
|
if (patt[pos] == '\\')
|
||||||
{
|
{
|
||||||
if (isalnum((unsigned char) patt[pos + 1]) || patt[pos + 1] == '(')
|
if (isalnum((unsigned char) patt[pos + 1]))
|
||||||
break;
|
break;
|
||||||
pos++;
|
pos++;
|
||||||
if (patt[pos] == '\0')
|
if (patt[pos] == '\0')
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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/postmaster.h"
|
||||||
#include "postmaster/syslogger.h"
|
#include "postmaster/syslogger.h"
|
||||||
#include "postmaster/walwriter.h"
|
#include "postmaster/walwriter.h"
|
||||||
#include "regex/regex.h"
|
|
||||||
#include "storage/bufmgr.h"
|
#include "storage/bufmgr.h"
|
||||||
#include "storage/fd.h"
|
#include "storage/fd.h"
|
||||||
#include "tcop/tcopprot.h"
|
#include "tcop/tcopprot.h"
|
||||||
@ -248,13 +247,6 @@ static const struct config_enum_entry log_statement_options[] = {
|
|||||||
{NULL, 0, false}
|
{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[] = {
|
static const struct config_enum_entry isolation_level_options[] = {
|
||||||
{"serializable", XACT_SERIALIZABLE, false},
|
{"serializable", XACT_SERIALIZABLE, false},
|
||||||
{"repeatable read", XACT_REPEATABLE_READ, false},
|
{"repeatable read", XACT_REPEATABLE_READ, false},
|
||||||
@ -2658,15 +2650,6 @@ static struct config_enum ConfigureNamesEnum[] =
|
|||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{
|
|
||||||
{"regex_flavor", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
|
|
||||||
gettext_noop("Sets the regular expression \"flavor\"."),
|
|
||||||
NULL
|
|
||||||
},
|
|
||||||
®ex_flavor,
|
|
||||||
REG_ADVANCED, regex_flavor_options, NULL, NULL
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
{
|
||||||
{"session_replication_role", PGC_SUSET, CLIENT_CONN_STATEMENT,
|
{"session_replication_role", PGC_SUSET, CLIENT_CONN_STATEMENT,
|
||||||
gettext_noop("Sets the session's behavior for triggers and rewrite rules."),
|
gettext_noop("Sets the session's behavior for triggers and rewrite rules."),
|
||||||
|
@ -488,7 +488,6 @@
|
|||||||
#backslash_quote = safe_encoding # on, off, or safe_encoding
|
#backslash_quote = safe_encoding # on, off, or safe_encoding
|
||||||
#default_with_oids = off
|
#default_with_oids = off
|
||||||
#escape_string_warning = on
|
#escape_string_warning = on
|
||||||
#regex_flavor = advanced # advanced, extended, or basic
|
|
||||||
#sql_inheritance = on
|
#sql_inheritance = on
|
||||||
#standard_conforming_strings = off
|
#standard_conforming_strings = off
|
||||||
#synchronize_seqscans = on
|
#synchronize_seqscans = on
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* 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 void pg_regfree(regex_t *);
|
||||||
extern size_t pg_regerror(int, const regex_t *, char *, size_t);
|
extern size_t pg_regerror(int, const regex_t *, char *, size_t);
|
||||||
|
|
||||||
/*
|
|
||||||
* guc configuration variables
|
|
||||||
*/
|
|
||||||
extern int regex_flavor;
|
|
||||||
|
|
||||||
#endif /* _REGEX_H_ */
|
#endif /* _REGEX_H_ */
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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_table_no_flags(PG_FUNCTION_ARGS);
|
||||||
extern Datum regexp_split_to_array(PG_FUNCTION_ARGS);
|
extern Datum regexp_split_to_array(PG_FUNCTION_ARGS);
|
||||||
extern Datum regexp_split_to_array_no_flags(PG_FUNCTION_ARGS);
|
extern Datum regexp_split_to_array_no_flags(PG_FUNCTION_ARGS);
|
||||||
extern bool regex_flavor_is_basic(void);
|
|
||||||
|
|
||||||
/* regproc.c */
|
/* regproc.c */
|
||||||
extern Datum regprocin(PG_FUNCTION_ARGS);
|
extern Datum regprocin(PG_FUNCTION_ARGS);
|
||||||
|
@ -607,95 +607,95 @@ DROP ROLE temp_reset_user;
|
|||||||
--
|
--
|
||||||
-- Tests for function-local GUC settings
|
-- Tests for function-local GUC settings
|
||||||
--
|
--
|
||||||
set regex_flavor = advanced;
|
set work_mem = '3MB';
|
||||||
create function report_guc(text) returns text as
|
create function report_guc(text) returns text as
|
||||||
$$ select current_setting($1) $$ language sql
|
$$ 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');
|
||||||
report_guc | current_setting
|
report_guc | current_setting
|
||||||
------------+-----------------
|
------------+-----------------
|
||||||
basic | advanced
|
1MB | 3MB
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- this should draw only a warning
|
-- this should draw only a warning
|
||||||
alter function report_guc(text) set search_path = no_such_schema;
|
alter function report_guc(text) set search_path = no_such_schema;
|
||||||
NOTICE: schema "no_such_schema" does not exist
|
NOTICE: schema "no_such_schema" does not exist
|
||||||
-- with error occurring here
|
-- 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
|
ERROR: schema "no_such_schema" does not exist
|
||||||
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');
|
||||||
report_guc | current_setting
|
report_guc | current_setting
|
||||||
------------+-----------------
|
------------+-----------------
|
||||||
extended | advanced
|
2MB | 3MB
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
alter function report_guc(text) reset all;
|
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
|
report_guc | current_setting
|
||||||
------------+-----------------
|
------------+-----------------
|
||||||
advanced | advanced
|
3MB | 3MB
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- SET LOCAL is restricted by a function SET option
|
-- SET LOCAL is restricted by a function SET option
|
||||||
create or replace function myfunc(int) returns text as $$
|
create or replace function myfunc(int) returns text as $$
|
||||||
begin
|
begin
|
||||||
set local regex_flavor = extended;
|
set local work_mem = '2MB';
|
||||||
return current_setting('regex_flavor');
|
return current_setting('work_mem');
|
||||||
end $$
|
end $$
|
||||||
language plpgsql
|
language plpgsql
|
||||||
set regex_flavor = basic;
|
set work_mem = '1MB';
|
||||||
select myfunc(0), current_setting('regex_flavor');
|
select myfunc(0), current_setting('work_mem');
|
||||||
myfunc | current_setting
|
myfunc | current_setting
|
||||||
----------+-----------------
|
--------+-----------------
|
||||||
extended | advanced
|
2MB | 3MB
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
alter function myfunc(int) reset all;
|
alter function myfunc(int) reset all;
|
||||||
select myfunc(0), current_setting('regex_flavor');
|
select myfunc(0), current_setting('work_mem');
|
||||||
myfunc | current_setting
|
myfunc | current_setting
|
||||||
----------+-----------------
|
--------+-----------------
|
||||||
extended | extended
|
2MB | 2MB
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
set regex_flavor = advanced;
|
set work_mem = '3MB';
|
||||||
-- but SET isn't
|
-- but SET isn't
|
||||||
create or replace function myfunc(int) returns text as $$
|
create or replace function myfunc(int) returns text as $$
|
||||||
begin
|
begin
|
||||||
set regex_flavor = extended;
|
set work_mem = '2MB';
|
||||||
return current_setting('regex_flavor');
|
return current_setting('work_mem');
|
||||||
end $$
|
end $$
|
||||||
language plpgsql
|
language plpgsql
|
||||||
set regex_flavor = basic;
|
set work_mem = '1MB';
|
||||||
select myfunc(0), current_setting('regex_flavor');
|
select myfunc(0), current_setting('work_mem');
|
||||||
myfunc | current_setting
|
myfunc | current_setting
|
||||||
----------+-----------------
|
--------+-----------------
|
||||||
extended | extended
|
2MB | 2MB
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
set regex_flavor = advanced;
|
set work_mem = '3MB';
|
||||||
-- it should roll back on error, though
|
-- it should roll back on error, though
|
||||||
create or replace function myfunc(int) returns text as $$
|
create or replace function myfunc(int) returns text as $$
|
||||||
begin
|
begin
|
||||||
set regex_flavor = extended;
|
set work_mem = '2MB';
|
||||||
perform 1/$1;
|
perform 1/$1;
|
||||||
return current_setting('regex_flavor');
|
return current_setting('work_mem');
|
||||||
end $$
|
end $$
|
||||||
language plpgsql
|
language plpgsql
|
||||||
set regex_flavor = basic;
|
set work_mem = '1MB';
|
||||||
select myfunc(0);
|
select myfunc(0);
|
||||||
ERROR: division by zero
|
ERROR: division by zero
|
||||||
CONTEXT: SQL statement "SELECT 1/ $1 "
|
CONTEXT: SQL statement "SELECT 1/ $1 "
|
||||||
PL/pgSQL function "myfunc" line 3 at PERFORM
|
PL/pgSQL function "myfunc" line 3 at PERFORM
|
||||||
select current_setting('regex_flavor');
|
select current_setting('work_mem');
|
||||||
current_setting
|
current_setting
|
||||||
-----------------
|
-----------------
|
||||||
advanced
|
3MB
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
select myfunc(1), current_setting('regex_flavor');
|
select myfunc(1), current_setting('work_mem');
|
||||||
myfunc | current_setting
|
myfunc | current_setting
|
||||||
----------+-----------------
|
--------+-----------------
|
||||||
extended | extended
|
2MB | 2MB
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
@ -186,68 +186,68 @@ DROP ROLE temp_reset_user;
|
|||||||
-- Tests for function-local GUC settings
|
-- Tests for function-local GUC settings
|
||||||
--
|
--
|
||||||
|
|
||||||
set regex_flavor = advanced;
|
set work_mem = '3MB';
|
||||||
|
|
||||||
create function report_guc(text) returns text as
|
create function report_guc(text) returns text as
|
||||||
$$ select current_setting($1) $$ language sql
|
$$ 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
|
-- this should draw only a warning
|
||||||
alter function report_guc(text) set search_path = no_such_schema;
|
alter function report_guc(text) set search_path = no_such_schema;
|
||||||
|
|
||||||
-- with error occurring here
|
-- 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;
|
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
|
-- SET LOCAL is restricted by a function SET option
|
||||||
create or replace function myfunc(int) returns text as $$
|
create or replace function myfunc(int) returns text as $$
|
||||||
begin
|
begin
|
||||||
set local regex_flavor = extended;
|
set local work_mem = '2MB';
|
||||||
return current_setting('regex_flavor');
|
return current_setting('work_mem');
|
||||||
end $$
|
end $$
|
||||||
language plpgsql
|
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;
|
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
|
-- but SET isn't
|
||||||
create or replace function myfunc(int) returns text as $$
|
create or replace function myfunc(int) returns text as $$
|
||||||
begin
|
begin
|
||||||
set regex_flavor = extended;
|
set work_mem = '2MB';
|
||||||
return current_setting('regex_flavor');
|
return current_setting('work_mem');
|
||||||
end $$
|
end $$
|
||||||
language plpgsql
|
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
|
-- it should roll back on error, though
|
||||||
create or replace function myfunc(int) returns text as $$
|
create or replace function myfunc(int) returns text as $$
|
||||||
begin
|
begin
|
||||||
set regex_flavor = extended;
|
set work_mem = '2MB';
|
||||||
perform 1/$1;
|
perform 1/$1;
|
||||||
return current_setting('regex_flavor');
|
return current_setting('work_mem');
|
||||||
end $$
|
end $$
|
||||||
language plpgsql
|
language plpgsql
|
||||||
set regex_flavor = basic;
|
set work_mem = '1MB';
|
||||||
|
|
||||||
select myfunc(0);
|
select myfunc(0);
|
||||||
select current_setting('regex_flavor');
|
select current_setting('work_mem');
|
||||||
select myfunc(1), current_setting('regex_flavor');
|
select myfunc(1), current_setting('work_mem');
|
||||||
|
Loading…
Reference in New Issue
Block a user