mirror of
https://github.com/postgres/postgres.git
synced 2026-07-06 16:25:55 -04:00
Fix LIKE matching with nondeterministic collations and backslashes.
Commit 85b7efa1c added support for LIKE with nondeterministic
collations, but it included a bug in the de-escaping logic for
literal pattern substrings. That unconditionally skipped all
backslashes, but when it encounters '\\' it should emit the second
backslash as a de-escaped character. That led to acting as though
the escaped backslash was not there.
Bug: #19474
Reported-by: Bowen Shi <zxwsbg12138@gmail.com>
Author: Nitin Motiani <nitinmotiani@google.com>
Reviewed-by: Zsolt Parragi <zsolt.parragi@percona.com>
Reviewed-by: Ewan Young <kdbase.hack@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/19474-5b86a95f3d9a7ecb@postgresql.org
Discussion: https://postgr.es/m/CAH5HC94yU+K8Gcdy12M5BS8gwD_SXLSHzc9k5tNk7JDnpBiFMA@mail.gmail.com
Backpatch-through: 18
This commit is contained in:
parent
431896a84e
commit
d6ffcae32a
3 changed files with 40 additions and 3 deletions
|
|
@ -257,9 +257,8 @@ MatchText(const char *t, int tlen, const char *p, int plen, pg_locale_t locale)
|
|||
for (const char *c = p; c < p1; c++)
|
||||
{
|
||||
if (*c == '\\')
|
||||
;
|
||||
else
|
||||
*(b++) = *c;
|
||||
c++; /* we already checked this isn't the end */
|
||||
*(b++) = *c;
|
||||
}
|
||||
|
||||
subpat = buf;
|
||||
|
|
|
|||
|
|
@ -3006,6 +3006,37 @@ SELECT U&'\0061\0308bc' LIKE U&'_\00e4bc' COLLATE ignore_accents;
|
|||
-- escape character at end of pattern
|
||||
SELECT 'foox' LIKE 'foo\' COLLATE ignore_accents;
|
||||
ERROR: LIKE pattern must not end with escape character
|
||||
-- literal backslash with nondeterministic collation (bug #19474)
|
||||
SELECT 'back\slash' COLLATE ignore_accents LIKE 'back\slash%' ESCAPE '#';
|
||||
?column?
|
||||
----------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
SELECT 'aäb' COLLATE ignore_accents LIKE 'a#äb' ESCAPE '#' AS multibyte_escape;
|
||||
multibyte_escape
|
||||
------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
SELECT 'a\äb' COLLATE ignore_accents LIKE 'a\äb%' ESCAPE '#' AS backslash_multibyte;
|
||||
backslash_multibyte
|
||||
---------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
SELECT 'a\b%c' COLLATE ignore_accents LIKE 'a#\b#%%c' ESCAPE '#' AS mixed_escapes;
|
||||
mixed_escapes
|
||||
---------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
SELECT 'backslash' COLLATE ignore_accents LIKE 'back\\slash%';
|
||||
?column?
|
||||
----------
|
||||
f
|
||||
(1 row)
|
||||
|
||||
-- foreign keys (mixing different nondeterministic collations not allowed)
|
||||
CREATE TABLE test10pk (x text COLLATE case_sensitive PRIMARY KEY);
|
||||
CREATE TABLE test10fk (x text COLLATE case_insensitive REFERENCES test10pk (x) ON UPDATE CASCADE ON DELETE CASCADE); -- error
|
||||
|
|
|
|||
|
|
@ -1083,6 +1083,13 @@ SELECT U&'\0061\0308bc' LIKE U&'_\00e4bc' COLLATE ignore_accents;
|
|||
-- escape character at end of pattern
|
||||
SELECT 'foox' LIKE 'foo\' COLLATE ignore_accents;
|
||||
|
||||
-- literal backslash with nondeterministic collation (bug #19474)
|
||||
SELECT 'back\slash' COLLATE ignore_accents LIKE 'back\slash%' ESCAPE '#';
|
||||
SELECT 'aäb' COLLATE ignore_accents LIKE 'a#äb' ESCAPE '#' AS multibyte_escape;
|
||||
SELECT 'a\äb' COLLATE ignore_accents LIKE 'a\äb%' ESCAPE '#' AS backslash_multibyte;
|
||||
SELECT 'a\b%c' COLLATE ignore_accents LIKE 'a#\b#%%c' ESCAPE '#' AS mixed_escapes;
|
||||
SELECT 'backslash' COLLATE ignore_accents LIKE 'back\\slash%';
|
||||
|
||||
-- foreign keys (mixing different nondeterministic collations not allowed)
|
||||
CREATE TABLE test10pk (x text COLLATE case_sensitive PRIMARY KEY);
|
||||
CREATE TABLE test10fk (x text COLLATE case_insensitive REFERENCES test10pk (x) ON UPDATE CASCADE ON DELETE CASCADE); -- error
|
||||
|
|
|
|||
Loading…
Reference in a new issue