postgres.git / summary / log / commit / refs

commit    9ca3dfba7989ab62e172cfd611d8acdfd56606ac
Author:   Andrew Dunstan <andrew@dunslane.net>
Date:     Sat Aug 22 21:45:54 2026 +0000

    Provide a C-ctype variant expected file for test_regex_utf8
    
    test_regex_utf8 decides whether to run by looking at the database
    encoding alone, but two of its cases, [[:graph:]] and [[:print:]] over
    E'xᔀሷ', depend on the ctype as well.  In a database with encoding
    UTF8 and locale C they match just the x, because isgraph() and isprint()
    are false for anything outside ASCII, and the file fails.
    
    No buildfarm animal builds such a cluster, which is why this went
    unnoticed. A pending buildfarm client change will let an
    animal be configured that way.
    
    Fix by providing a second expected file holding the C-ctype answers, in
    the manner of json_encoding.sql, which carries expected files for UTF8
    and for SQL_ASCII.  The .sql needs no change.
    
    This applies to releases 15 and 16 only. A better solution is available
    for release 17 and up.
    
    Backpatch to v15, v16 only.


.../test_regex/expected/test_regex_utf8_2.out | 206 +++++++++++++++++++++ 1 file changed, 206 insertions(+) diff --git a/src/test/modules/test_regex/expected/test_regex_utf8_2.out b/src/test/modules/test_regex/expected/test_regex_utf8_2.out new file mode 100644 index 00000000000..46693c8b74f --- /dev/null +++ b/src/test/modules/test_regex/expected/test_regex_utf8_2.out @@ -0,0 +1,206 @@ +/* + * This test must be run in a database with UTF-8 encoding, + * because other encodings don't support all the characters used. + */ +SELECT getdatabaseencoding() <> 'UTF8' + AS skip_test \gset +\if :skip_test +\quit +\endif +set client_encoding = utf8; +set standard_conforming_strings = on; +-- Run the Tcl test cases that require Unicode +-- expectMatch 9.44 EMP* {a[\u00fe-\u0507][\u00ff-\u0300]b} \ +-- "a\u0102\u02ffb" "a\u0102\u02ffb" +select * from test_regex('a[\u00fe-\u0507][\u00ff-\u0300]b', E'a\u0102\u02ffb', 'EMP*'); + test_regex +---------------------------------------- + {0,REG_UBBS,REG_UNONPOSIX,REG_UUNPORT} + {aĂ˿b} +(2 rows) + +-- expectMatch 13.27 P "a\\U00001234x" "a\u1234x" "a\u1234x" +select * from test_regex('a\U00001234x', E'a\u1234x', 'P'); + test_regex +------------------- + {0,REG_UNONPOSIX} + {aሴx} +(2 rows) + +-- expectMatch 13.28 P {a\U00001234x} "a\u1234x" "a\u1234x" +select * from test_regex('a\U00001234x', E'a\u1234x', 'P'); + test_regex +------------------- + {0,REG_UNONPOSIX} + {aሴx} +(2 rows) + +-- expectMatch 13.29 P "a\\U0001234x" "a\u1234x" "a\u1234x" +-- Tcl has relaxed their code to allow 1-8 hex digits, but Postgres hasn't +select * from test_regex('a\U0001234x', E'a\u1234x', 'P'); +ERROR: invalid regular expression: invalid escape \ sequence +-- expectMatch 13.30 P {a\U0001234x} "a\u1234x" "a\u1234x" +-- Tcl has relaxed their code to allow 1-8 hex digits, but Postgres hasn't +select * from test_regex('a\U0001234x', E'a\u1234x', 'P'); +ERROR: invalid regular expression: invalid escape \ sequence +-- expectMatch 13.31 P "a\\U000012345x" "a\u12345x" "a\u12345x" +select * from test_regex('a\U000012345x', E'a\u12345x', 'P'); + test_regex +------------------- + {0,REG_UNONPOSIX} + {aሴ5x} +(2 rows) + +-- expectMatch 13.32 P {a\U000012345x} "a\u12345x" "a\u12345x" +select * from test_regex('a\U000012345x', E'a\u12345x', 'P'); + test_regex +------------------- + {0,REG_UNONPOSIX} + {aሴ5x} +(2 rows) + +-- expectMatch 13.33 P "a\\U1000000x" "a\ufffd0x" "a\ufffd0x" +-- Tcl allows this as a standalone character, but Postgres doesn't +select * from test_regex('a\U1000000x', E'a\ufffd0x', 'P'); +ERROR: invalid regular expression: invalid escape \ sequence +-- expectMatch 13.34 P {a\U1000000x} "a\ufffd0x" "a\ufffd0x" +-- Tcl allows this as a standalone character, but Postgres doesn't +select * from test_regex('a\U1000000x', E'a\ufffd0x', 'P'); +ERROR: invalid regular expression: invalid escape \ sequence +-- Additional tests, not derived from Tcl +-- Exercise logic around high character ranges a bit more +select * from test_regex('a + [\u1000-\u1100]* + [\u3000-\u3100]* + [\u1234-\u25ff]+ + [\u2000-\u35ff]* + [\u2600-\u2f00]* + \u1236\u1236x', + E'a\u1234\u1236\u1236x', 'xEMP'); + test_regex +---------------------------------------- + {0,REG_UBBS,REG_UNONPOSIX,REG_UUNPORT} + {aሴሶሶx} +(2 rows) + +select * from test_regex('[[:alnum:]]*[[:upper:]]*[\u1000-\u2000]*\u1237', + E'\u1500\u1237', 'ELMP'); + test_regex +---------------------------------------------------- + {0,REG_UBBS,REG_UNONPOSIX,REG_UUNPORT,REG_ULOCALE} + {ᔀሷ} +(2 rows) + +select * from test_regex('[[:alnum:]]*[[:upper:]]*[\u1000-\u2000]*\u1237', + E'A\u1239', 'ELMP'); + test_regex +---------------------------------------------------- + {0,REG_UBBS,REG_UNONPOSIX,REG_UUNPORT,REG_ULOCALE} +(1 row) + +select * from test_regex('[[:alnum:]]*[[:upper:]]*[\u1000-\u2000]*\u1237', + E'\u1500\u1237', 'iELMP'); + test_regex +---------------------------------------------------- + {0,REG_UBBS,REG_UNONPOSIX,REG_UUNPORT,REG_ULOCALE} + {ᔀሷ} +(2 rows) + +-- systematically test char classes +select * from test_regex('[[:alnum:]]+', E'x*\u1500\u1237', 'L'); + test_regex +----------------- + {0,REG_ULOCALE} + {x} +(2 rows) + +select * from test_regex('[[:alpha:]]+', E'x*\u1500\u1237', 'L'); + test_regex +----------------- + {0,REG_ULOCALE} + {x} +(2 rows) + +select * from test_regex('[[:ascii:]]+', E'x\u1500\u1237', 'L'); + test_regex +----------------- + {0,REG_ULOCALE} + {x} +(2 rows) + +select * from test_regex('[[:blank:]]+', E'x \t\u1500\u1237', 'L'); + test_regex +----------------- + {0,REG_ULOCALE} + {" "} +(2 rows) + +select * from test_regex('[[:cntrl:]]+', E'x\u1500\u1237', 'L'); + test_regex +----------------- + {0,REG_ULOCALE} +(1 row) + +select * from test_regex('[[:digit:]]+', E'x9\u1500\u1237', 'L'); + test_regex +----------------- + {0,REG_ULOCALE} + {9} +(2 rows) + +select * from test_regex('[[:graph:]]+', E'x\u1500\u1237', 'L'); + test_regex +----------------- + {0,REG_ULOCALE} + {x} +(2 rows) + +select * from test_regex('[[:lower:]]+', E'x\u1500\u1237', 'L'); + test_regex +----------------- + {0,REG_ULOCALE} + {x} +(2 rows) + +select * from test_regex('[[:print:]]+', E'x\u1500\u1237', 'L'); + test_regex +----------------- + {0,REG_ULOCALE} + {x} +(2 rows) + +select * from test_regex('[[:punct:]]+', E'x.\u1500\u1237', 'L'); + test_regex +----------------- + {0,REG_ULOCALE} + {.} +(2 rows) + +select * from test_regex('[[:space:]]+', E'x \t\u1500\u1237', 'L'); + test_regex +----------------- + {0,REG_ULOCALE} + {" "} +(2 rows) + +select * from test_regex('[[:upper:]]+', E'xX\u1500\u1237', 'L'); + test_regex +----------------- + {0,REG_ULOCALE} + {X} +(2 rows) + +select * from test_regex('[[:xdigit:]]+', E'xa9\u1500\u1237', 'L'); + test_regex +----------------- + {0,REG_ULOCALE} + {a9} +(2 rows) + +select * from test_regex('[[:word:]]+', E'x_*\u1500\u1237', 'L'); + test_regex +----------------- + {0,REG_ULOCALE} + {x_} +(2 rows) + [parent: ea3227bf2162]