From: Bruce Momjian Date: Sun, 26 Jun 2005 03:04:37 +0000 (+0000) Subject: Add E'' syntax so eventually normal strings can treat backslashes X-Git-Tag: REL8_1_0BETA1~464 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bb3cce4ec9cc157a8dfc80b5b1770c2beac0a57e;p=postgresql Add E'' syntax so eventually normal strings can treat backslashes literally. Add GUC variables: "escape_string_warning" - warn about backslashes in non-E strings "escape_string_syntax" - supports E'' syntax? "standard_compliant_strings" - treats backslashes literally in '' Update code to use E'' when escapes are used. --- diff --git a/contrib/tsearch2/expected/tsearch2.out b/contrib/tsearch2/expected/tsearch2.out index 9e050ae279..6c266a29ac 100644 --- a/contrib/tsearch2/expected/tsearch2.out +++ b/contrib/tsearch2/expected/tsearch2.out @@ -47,37 +47,37 @@ SELECT '1 2'::tsvector; '1' '2' (1 row) -SELECT '\'1 2\''::tsvector; +SELECT '''1 2'''::tsvector; tsvector ---------- '1 2' (1 row) -SELECT '\'1 \\\'2\''::tsvector; +SELECT E'''1 \\''2'''::tsvector; tsvector ---------- '1 \'2' (1 row) -SELECT '\'1 \\\'2\'3'::tsvector; +SELECT E'''1 \\''2''3'::tsvector; tsvector ------------- '3' '1 \'2' (1 row) -SELECT '\'1 \\\'2\' 3'::tsvector; +SELECT E'''1 \\''2'' 3'::tsvector; tsvector ------------- '3' '1 \'2' (1 row) -SELECT '\'1 \\\'2\' \' 3\' 4 '::tsvector; +SELECT E'''1 \\''2'' '' 3'' 4 '::tsvector; tsvector ------------------ '4' ' 3' '1 \'2' (1 row) -select '\'w\':4A,3B,2C,1D,5 a:8'; +select '''w'':4A,3B,2C,1D,5 a:8'; ?column? ----------------------- 'w':4A,3B,2C,1D,5 a:8 @@ -126,13 +126,13 @@ SELECT ' 1 '::tsquery; '1' (1 row) -SELECT '\'1 2\''::tsquery; +SELECT '''1 2'''::tsquery; tsquery --------- '1 2' (1 row) -SELECT '\'1 \\\'2\''::tsquery; +SELECT E'''1 \\''2'''::tsquery; tsquery --------- '1 \'2' @@ -330,13 +330,13 @@ SELECT '1&(2&(4&(5|!6)))'::tsquery; '1' & '2' & '4' & ( '5' | !'6' ) (1 row) -SELECT '1&(\'2\'&(\' 4\'&(\\|5 | \'6 \\\' !|&\')))'::tsquery; +SELECT E'1&(''2''&('' 4''&(\\|5 | ''6 \\'' !|&'')))'::tsquery; tsquery ------------------------------------------ '1' & '2' & ' 4' & ( '|5' | '6 \' !|&' ) (1 row) -SELECT '\'the wether\':dc & \' sKies \':BC & a:d b:a'; +SELECT '''the wether'':dc & '' sKies '':BC & a:d b:a'; ?column? ------------------------------------------ 'the wether':dc & ' sKies ':BC & a:d b:a @@ -382,7 +382,7 @@ select * from token_type('default'); 23 | entity | HTML Entity (23 rows) -select * from parse('default', '345 qwe@efd.r \' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005 teodor@stack.net qwe-wer asdf qwer jf sdjk ewr1> ewri2 +select * from parse('default', '345 qwe@efd.r '' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005 teodor@stack.net qwe-wer asdf qwer jf sdjk ewr1> ewri2 /usr/local/fff /awdf/dwqe/4325 rewt/ewr wefjn /wqe-324/ewr gist.h gist.h.c gist.c. readline 4.2 4.2. 4.2, readline-4.2 readline-4.2. 234 wow < jqw <> qwerty'); tokid | token @@ -529,7 +529,7 @@ select * from parse('default', '345 qwe@efd.r \' http://www.com/ http://aew.werc 1 | qwerty (138 rows) -SELECT to_tsvector('default', '345 qwe@efd.r \' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005 teodor@stack.net qwe-wer asdf qwer jf sdjk ewr1> ewri2 +SELECT to_tsvector('default', '345 qwe@efd.r '' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005 teodor@stack.net qwe-wer asdf qwer jf sdjk ewr1> ewri2 /usr/local/fff /awdf/dwqe/4325 rewt/ewr wefjn /wqe-324/ewr gist.h gist.h.c gist.c. readline 4.2 4.2. 4.2, readline-4.2 readline-4.2. 234 wow < jqw <> qwerty'); to_tsvector @@ -543,7 +543,7 @@ SELECT length(to_tsvector('default', '345 qw')); 2 (1 row) -SELECT length(to_tsvector('default', '345 qwe@efd.r \' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005 teodor@stack.net qwe-wer asdf qwer jf sdjk ewr1> ewri2 +SELECT length(to_tsvector('default', '345 qwe@efd.r '' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005 teodor@stack.net qwe-wer asdf qwer jf sdjk ewr1> ewri2 /usr/local/fff /awdf/dwqe/4325 rewt/ewr wefjn /wqe-324/ewr gist.h gist.h.c gist.c. readline 4.2 4.2. 4.2, readline-4.2 readline-4.2. 234 wow < jqw <> qwerty')); length @@ -563,7 +563,7 @@ select to_tsquery('simple', 'qwe & sKies '); 'qwe' & 'skies' (1 row) -select to_tsquery('default', '\'the wether\':dc & \' sKies \':BC '); +select to_tsquery('default', '''the wether'':dc & '' sKies '':BC '); to_tsquery ------------------------ 'wether':CD & 'sky':BC @@ -729,7 +729,7 @@ SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty'); (1 row) drop trigger tsvectorupdate on test_tsvector; -create function wow(text) returns text as 'select $1 || \' copyright\'; ' language sql; +create function wow(text) returns text as 'select $1 || '' copyright''; ' language sql; create trigger tsvectorupdate before update or insert on test_tsvector for each row execute procedure tsearch2(a, wow, t); insert into test_tsvector (t) values ('345 qwerty'); diff --git a/contrib/tsearch2/sql/tsearch2.sql b/contrib/tsearch2/sql/tsearch2.sql index 0a980608f7..52e709d74b 100644 --- a/contrib/tsearch2/sql/tsearch2.sql +++ b/contrib/tsearch2/sql/tsearch2.sql @@ -12,12 +12,12 @@ SELECT '1 '::tsvector; SELECT ' 1'::tsvector; SELECT ' 1 '::tsvector; SELECT '1 2'::tsvector; -SELECT '\'1 2\''::tsvector; -SELECT '\'1 \\\'2\''::tsvector; -SELECT '\'1 \\\'2\'3'::tsvector; -SELECT '\'1 \\\'2\' 3'::tsvector; -SELECT '\'1 \\\'2\' \' 3\' 4 '::tsvector; -select '\'w\':4A,3B,2C,1D,5 a:8'; +SELECT '''1 2'''::tsvector; +SELECT E'''1 \\''2'''::tsvector; +SELECT E'''1 \\''2''3'::tsvector; +SELECT E'''1 \\''2'' 3'::tsvector; +SELECT E'''1 \\''2'' '' 3'' 4 '::tsvector; +select '''w'':4A,3B,2C,1D,5 a:8'; select 'a:3A b:2a'::tsvector || 'ba:1234 a:1B'; select setweight('w:12B w:13* w:12,5,6 a:1,3* a:3 w asd:1dc asd zxc:81,567,222A'::tsvector, 'c'); select strip('w:12B w:13* w:12,5,6 a:1,3* a:3 w asd:1dc asd'::tsvector); @@ -28,8 +28,8 @@ SELECT '1'::tsquery; SELECT '1 '::tsquery; SELECT ' 1'::tsquery; SELECT ' 1 '::tsquery; -SELECT '\'1 2\''::tsquery; -SELECT '\'1 \\\'2\''::tsquery; +SELECT '''1 2'''::tsquery; +SELECT E'''1 \\''2'''::tsquery; SELECT '!1'::tsquery; SELECT '1|2'::tsquery; SELECT '1|!2'::tsquery; @@ -62,31 +62,31 @@ SELECT '1&(2&(4&(5&6)))'::tsquery; SELECT '1&2&4&5&6'::tsquery; SELECT '1&(2&(4&(5|6)))'::tsquery; SELECT '1&(2&(4&(5|!6)))'::tsquery; -SELECT '1&(\'2\'&(\' 4\'&(\\|5 | \'6 \\\' !|&\')))'::tsquery; -SELECT '\'the wether\':dc & \' sKies \':BC & a:d b:a'; +SELECT E'1&(''2''&('' 4''&(\\|5 | ''6 \\'' !|&'')))'::tsquery; +SELECT '''the wether'':dc & '' sKies '':BC & a:d b:a'; select lexize('simple', 'ASD56 hsdkf'); select lexize('en_stem', 'SKIES Problems identity'); select * from token_type('default'); -select * from parse('default', '345 qwe@efd.r \' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005 teodor@stack.net qwe-wer asdf qwer jf sdjk ewr1> ewri2 +select * from parse('default', '345 qwe@efd.r '' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005 teodor@stack.net qwe-wer asdf qwer jf sdjk ewr1> ewri2 /usr/local/fff /awdf/dwqe/4325 rewt/ewr wefjn /wqe-324/ewr gist.h gist.h.c gist.c. readline 4.2 4.2. 4.2, readline-4.2 readline-4.2. 234 wow < jqw <> qwerty'); -SELECT to_tsvector('default', '345 qwe@efd.r \' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005 teodor@stack.net qwe-wer asdf qwer jf sdjk ewr1> ewri2 +SELECT to_tsvector('default', '345 qwe@efd.r '' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005 teodor@stack.net qwe-wer asdf qwer jf sdjk ewr1> ewri2 /usr/local/fff /awdf/dwqe/4325 rewt/ewr wefjn /wqe-324/ewr gist.h gist.h.c gist.c. readline 4.2 4.2. 4.2, readline-4.2 readline-4.2. 234 wow < jqw <> qwerty'); SELECT length(to_tsvector('default', '345 qw')); -SELECT length(to_tsvector('default', '345 qwe@efd.r \' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005 teodor@stack.net qwe-wer asdf qwer jf sdjk ewr1> ewri2 +SELECT length(to_tsvector('default', '345 qwe@efd.r '' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005 teodor@stack.net qwe-wer asdf qwer jf sdjk ewr1> ewri2 /usr/local/fff /awdf/dwqe/4325 rewt/ewr wefjn /wqe-324/ewr gist.h gist.h.c gist.c. readline 4.2 4.2. 4.2, readline-4.2 readline-4.2. 234 wow < jqw <> qwerty')); select to_tsquery('default', 'qwe & sKies '); select to_tsquery('simple', 'qwe & sKies '); -select to_tsquery('default', '\'the wether\':dc & \' sKies \':BC '); +select to_tsquery('default', '''the wether'':dc & '' sKies '':BC '); select to_tsquery('default', 'asd&(and|fghj)'); select to_tsquery('default', '(asd&and)|fghj'); select to_tsquery('default', '(asd&!and)|fghj'); @@ -135,7 +135,7 @@ UPDATE test_tsvector SET t = null WHERE t = '345 qwerty'; SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty'); drop trigger tsvectorupdate on test_tsvector; -create function wow(text) returns text as 'select $1 || \' copyright\'; ' language sql; +create function wow(text) returns text as 'select $1 || '' copyright''; ' language sql; create trigger tsvectorupdate before update or insert on test_tsvector for each row execute procedure tsearch2(a, wow, t); insert into test_tsvector (t) values ('345 qwerty'); diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index 4333445392..3841b0dee2 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1,5 +1,5 @@ @@ -3757,6 +3757,30 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' + + escape_string_warning (boolean) + stringsescape + + escape_string_warning configuration parameter + + + + When on, a warning is issued if a backslash + (\) appears in a ordinary, non-escape syntax + ('') string. To log the statement that generated the + warning, set log_min_error_statement to + error. The default is off. + + + Escape string syntax (E'') should be used for + escapes, because in future versions of + PostgreSQL ordinary strings will have + the standard-compliant behavior of treating backslashes + literally. + + + + @@ -3964,6 +3988,37 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' + + escape_string_syntax (boolean) + stringsescape + + escape_string_syntax configuration parameter + + + + Reports whether escape string syntax (E'') is + supported. This variable is used by applications that need to + determine if escape string syntax can be used in their code. + + + + + + standard_compliant_strings (boolean) + stringsescape + + standard_compliant_strings configuration parameter + + + + Reports whether ordinary, non-escape syntax strings + ('') treat backslashes literally, as specified in + the SQL standard. This variable is used by applications that + need to know how ordinary strings are processed`. + + + + diff --git a/doc/src/sgml/syntax.sgml b/doc/src/sgml/syntax.sgml index 45b6a80564..3d8d457c56 100644 --- a/doc/src/sgml/syntax.sgml +++ b/doc/src/sgml/syntax.sgml @@ -1,5 +1,5 @@ @@ -247,9 +247,10 @@ UPDATE "my_table" SET "a" = 5; write two adjacent single quotes, e.g. 'Dianne''s horse'. PostgreSQL also allows single quotes - to be escaped with a backslash (\), so for - example the same string could be written - 'Dianne\'s horse'. + to be escaped with a backslash (\'). However, + future versions of PostgreSQL will not + support this so applications using this should convert to the + standard-compliant method outlined above. @@ -268,6 +269,20 @@ UPDATE "my_table" SET "a" = 5; include a backslash in a string constant, write two backslashes. + + + While ordinary strings now support C-style backslash escapes, + future versions will generate warnings for such usage and + eventually treat backslashes as literal characters to be + standard-compliant. The proper way to specify escape processing is + to use the escape string syntax to indicate that escape + processing is desired. Escape string syntax is specified by placing + the the letter E (upper or lower case) before + the string, e.g. E'\041'. This method will work in all + future versions of PostgreSQL. + + + The character with the code zero cannot be in a string constant. diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l index 0a250e8dbe..4c556a5fba 100644 --- a/src/backend/parser/scan.l +++ b/src/backend/parser/scan.l @@ -24,7 +24,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/scan.l,v 1.125 2005/06/15 16:28:06 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/parser/scan.l,v 1.126 2005/06/26 03:03:38 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -48,7 +48,9 @@ extern YYSTYPE yylval; static int xcdepth = 0; /* depth of nesting in slash-star comments */ -static char *dolqstart; /* current $foo$ quote start string */ +static char *dolqstart; /* current $foo$ quote start string */ +static bool warn_on_first_escape; +bool escape_string_warning; /* * literalbuf is used to accumulate literal values when multiple rules @@ -64,6 +66,7 @@ static int literalalloc; /* current allocated buffer size */ static void addlit(char *ytext, int yleng); static void addlitchar(unsigned char ychar); static char *litbufdup(void); +static void check_escape_warning(void); /* * When we parse a token that requires multiple lexer rules to process, @@ -185,6 +188,10 @@ xhinside [^']* /* National character */ xnstart [nN]{quote} +/* Quote string does not warn about escapes */ +xestart [eE]{quote} +xeinside [^']* + /* Extended quote * xqdouble implements embedded quote, '''' */ @@ -410,6 +417,13 @@ other . } {xqstart} { + warn_on_first_escape = true; + token_start = yytext; + BEGIN(xq); + startlit(); + } +{xestart} { + warn_on_first_escape = false; token_start = yytext; BEGIN(xq); startlit(); @@ -428,14 +442,36 @@ other . addlit(yytext, yyleng); } {xqescape} { + if (yytext[1] == '\'') + { + if (warn_on_first_escape && escape_string_warning) + ereport(WARNING, + (errcode(ERRCODE_INVALID_USE_OF_ESCAPE_CHARACTER), + errmsg("Invalid use of \\' in a normal string"), + errhint("Use '' to place quotes in strings, or use the escape string syntax (E'')."))); + } + else if (yytext[1] == '\\') + { + if (warn_on_first_escape && escape_string_warning) + ereport(WARNING, + (errcode(ERRCODE_INVALID_USE_OF_ESCAPE_CHARACTER), + errmsg("Invalid use of \\\\ in a normal string"), + errhint("Use the escape string syntax for backslashes, e.g. E'\\\\'."))); + } + else + check_escape_warning(); addlitchar(unescape_single_char(yytext[1])); } {xqoctesc} { unsigned char c = strtoul(yytext+1, NULL, 8); + + check_escape_warning(); addlitchar(c); } {xqhexesc} { unsigned char c = strtoul(yytext+2, NULL, 16); + + check_escape_warning(); addlitchar(c); } {quotecontinue} { @@ -810,3 +846,14 @@ unescape_single_char(unsigned char c) return c; } } + +static void +check_escape_warning(void) +{ + if (warn_on_first_escape && escape_string_warning) + ereport(WARNING, + (errcode(ERRCODE_INVALID_USE_OF_ESCAPE_CHARACTER), + errmsg("Invalid use of escapes in an ordinary string"), + errhint("Use the escape string syntax for escapes, e.g. E'\\r\\n'."))); + warn_on_first_escape = false; /* warn only once per string */ +} diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 05ce93cf58..1738604942 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -10,7 +10,7 @@ * Written by Peter Eisentraut . * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.268 2005/06/17 22:32:47 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.269 2005/06/26 03:03:41 momjian Exp $ * *-------------------------------------------------------------------- */ @@ -189,7 +189,9 @@ static int max_function_args; static int max_index_keys; static int max_identifier_length; static int block_size; -static bool integer_datetimes; +static bool integer_datetimes; +static bool escape_string_syntax; +static bool standard_compliant_strings; /* should be static, but commands/variable.c needs to get at it */ char *session_authorization_string; @@ -873,6 +875,35 @@ static struct config_bool ConfigureNamesBool[] = false, NULL, NULL }, + { + {"escape_string_warning", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS, + gettext_noop("Warn about backslash escapes in ordinary, non-escape-syntax strings."), + NULL + }, + &escape_string_warning, + false, NULL, NULL + }, + + { + {"escape_string_syntax", PGC_INTERNAL, PRESET_OPTIONS, + gettext_noop("Escape string syntax (E'') is supported."), + NULL, + GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE + }, + &escape_string_syntax, + true, NULL, NULL + }, + + { + {"standard_compliant_strings", PGC_INTERNAL, PRESET_OPTIONS, + gettext_noop("'' strings treat backslashes literally."), + NULL, + GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE + }, + &standard_compliant_strings, + false, NULL, NULL + }, + /* End-of-list marker */ { {NULL, 0, 0, NULL, NULL}, NULL, false, NULL, NULL diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index 4c5a1ed59e..72f447c76b 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -330,6 +330,7 @@ #regex_flavor = advanced # advanced, extended, or basic #sql_inheritance = true #default_with_oids = false +#escape_string_warning = false # - Other Platforms & Clients - diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index dd830f7c03..2442f43ddc 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -42,7 +42,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * Portions taken from FreeBSD. * - * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.85 2005/06/21 04:02:32 tgl Exp $ + * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.86 2005/06/26 03:03:45 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -1692,7 +1692,7 @@ setup_privileges(void) char **priv_lines; static char *privileges_setup[] = { "UPDATE pg_class " - " SET relacl = '{\"=r/\\\\\"$POSTGRES_SUPERUSERNAME\\\\\"\"}' " + " SET relacl = E'{\"=r/\\\\\"$POSTGRES_SUPERUSERNAME\\\\\"\"}' " " WHERE relkind IN ('r', 'v', 'S') AND relacl IS NULL;\n", "GRANT USAGE ON SCHEMA pg_catalog TO PUBLIC;\n", "GRANT CREATE, USAGE ON SCHEMA public TO PUBLIC;\n", @@ -1987,8 +1987,10 @@ escape_quotes(const char *src) for (i = 0, j = 0; i < len; i++) { - if (src[i] == '\'' || src[i] == '\\') + if (src[i] == '\\') result[j++] = '\\'; + if (src[i] == '\'') /* ANSI standard, '' */ + result[j++] = '\''; result[j++] = src[i]; } result[j] = '\0'; diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index 75158a58bf..c6a0d3e208 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * - * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.61 2005/06/21 15:22:18 tgl Exp $ + * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.62 2005/06/26 03:03:48 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -538,7 +538,7 @@ dumpTablespaces(PGconn *conn) "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, " "spclocation, spcacl " "FROM pg_catalog.pg_tablespace " - "WHERE spcname NOT LIKE 'pg\\_%'"); + "WHERE spcname NOT LIKE E'pg\\_%'"); if (PQntuples(res) > 0) printf("--\n-- Tablespaces\n--\n\n"); diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index 392421dc6f..b7397515b7 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -3,7 +3,7 @@ * * Copyright (c) 2000-2005, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.117 2005/06/14 23:59:31 momjian Exp $ + * $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.118 2005/06/26 03:03:56 momjian Exp $ */ #include "postgres_fe.h" #include "describe.h" @@ -1766,7 +1766,7 @@ listSchemas(const char *pattern, bool verbose) appendPQExpBuffer(&buf, "\nFROM pg_catalog.pg_namespace n LEFT JOIN pg_catalog.pg_user u\n" " ON n.nspowner=u.usesysid\n" - "WHERE (n.nspname NOT LIKE 'pg\\\\_temp\\\\_%%' OR\n" + "WHERE (n.nspname NOT LIKE E'pg\\\\_temp\\\\_%%' OR\n" " n.nspname = (pg_catalog.current_schemas(true))[1])\n"); /* temp schema is first */ processNamePattern(&buf, pattern, true, false, diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 892835075a..049024ae40 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.370 2005/06/24 20:53:32 tgl Exp $ + * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.371 2005/06/26 03:04:01 momjian Exp $ * * NOTES * The script catalog/genbki.sh reads this file and generates .bki @@ -1462,7 +1462,7 @@ DATA(insert OID = 1156 ( timestamptz_ge PGNSP PGUID 12 f f t f i 2 16 "1184 1 DESCR("greater-than-or-equal"); DATA(insert OID = 1157 ( timestamptz_gt PGNSP PGUID 12 f f t f i 2 16 "1184 1184" _null_ _null_ _null_ timestamp_gt - _null_ )); DESCR("greater-than"); -DATA(insert OID = 1158 ( to_timestamp PGNSP PGUID 14 f f t f i 1 1184 "701" _null_ _null_ _null_ "select (\'epoch\'::timestamptz + $1 * \'1 second\'::interval)" - _null_ )); +DATA(insert OID = 1158 ( to_timestamp PGNSP PGUID 14 f f t f i 1 1184 "701" _null_ _null_ _null_ "select (''epoch''::timestamptz + $1 * ''1 second''::interval)" - _null_ )); DESCR("convert UNIX epoch to timestamptz"); DATA(insert OID = 1159 ( timezone PGNSP PGUID 12 f f t f i 2 1114 "25 1184" _null_ _null_ _null_ timestamptz_zone - _null_ )); DESCR("adjust timestamp to new time zone"); @@ -1542,7 +1542,7 @@ DESCR("adjust interval precision"); DATA(insert OID = 1215 ( obj_description PGNSP PGUID 14 f f t f s 2 25 "26 19" _null_ _null_ _null_ "select description from pg_catalog.pg_description where objoid = $1 and classoid = (select oid from pg_catalog.pg_class where relname = $2 and relnamespace = PGNSP) and objsubid = 0" - _null_ )); DESCR("get description for object id and catalog name"); -DATA(insert OID = 1216 ( col_description PGNSP PGUID 14 f f t f s 2 25 "26 23" _null_ _null_ _null_ "select description from pg_catalog.pg_description where objoid = $1 and classoid = \'pg_catalog.pg_class\'::regclass and objsubid = $2" - _null_ )); +DATA(insert OID = 1216 ( col_description PGNSP PGUID 14 f f t f s 2 25 "26 23" _null_ _null_ _null_ "select description from pg_catalog.pg_description where objoid = $1 and classoid = ''pg_catalog.pg_class''::regclass and objsubid = $2" - _null_ )); DESCR("get description for table column"); DATA(insert OID = 1217 ( date_trunc PGNSP PGUID 12 f f t f s 2 1184 "25 1184" _null_ _null_ _null_ timestamptz_trunc - _null_ )); @@ -2186,9 +2186,9 @@ DATA(insert OID = 877 ( substr PGNSP PGUID 12 f f t f i 3 25 "25 23 23" _nu DESCR("return portion of string"); DATA(insert OID = 878 ( translate PGNSP PGUID 12 f f t f i 3 25 "25 25 25" _null_ _null_ _null_ translate - _null_ )); DESCR("map a set of character appearing in string"); -DATA(insert OID = 879 ( lpad PGNSP PGUID 14 f f t f i 2 25 "25 23" _null_ _null_ _null_ "select pg_catalog.lpad($1, $2, \' \')" - _null_ )); +DATA(insert OID = 879 ( lpad PGNSP PGUID 14 f f t f i 2 25 "25 23" _null_ _null_ _null_ "select pg_catalog.lpad($1, $2, '' '')" - _null_ )); DESCR("left-pad string to length"); -DATA(insert OID = 880 ( rpad PGNSP PGUID 14 f f t f i 2 25 "25 23" _null_ _null_ _null_ "select pg_catalog.rpad($1, $2, \' \')" - _null_ )); +DATA(insert OID = 880 ( rpad PGNSP PGUID 14 f f t f i 2 25 "25 23" _null_ _null_ _null_ "select pg_catalog.rpad($1, $2, '' '')" - _null_ )); DESCR("right-pad string to length"); DATA(insert OID = 881 ( ltrim PGNSP PGUID 12 f f t f i 1 25 "25" _null_ _null_ _null_ ltrim1 - _null_ )); DESCR("trim spaces from left end of string"); diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h index ed2748e8b2..c08ecd4db4 100644 --- a/src/include/utils/guc.h +++ b/src/include/utils/guc.h @@ -7,7 +7,7 @@ * Copyright (c) 2000-2005, PostgreSQL Global Development Group * Written by Peter Eisentraut . * - * $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.60 2005/03/25 16:17:28 tgl Exp $ + * $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.61 2005/06/26 03:04:12 momjian Exp $ *-------------------------------------------------------------------- */ #ifndef GUC_H @@ -120,6 +120,7 @@ extern bool SQL_inheritance; extern bool Australian_timezones; extern bool default_with_oids; +extern bool escape_string_warning; extern int log_min_error_statement; extern int log_min_messages; diff --git a/src/test/regress/expected/arrays.out b/src/test/regress/expected/arrays.out index 80eab4a13d..dcc9e9c1ab 100644 --- a/src/test/regress/expected/arrays.out +++ b/src/test/regress/expected/arrays.out @@ -436,7 +436,7 @@ select '{{1,{2}},{2,3}}'::text[]; ERROR: malformed array literal: "{{1,{2}},{2,3}}" select '{{},{}}'::text[]; ERROR: malformed array literal: "{{},{}}" -select '{{1,2},\\{2,3}}'::text[]; +select E'{{1,2},\\{2,3}}'::text[]; ERROR: malformed array literal: "{{1,2},\{2,3}}" select '{{"1 2" x},{3}}'::text[]; ERROR: malformed array literal: "{{"1 2" x},{3}}" diff --git a/src/test/regress/expected/copy2.out b/src/test/regress/expected/copy2.out index 40dd7f24af..78f2060570 100644 --- a/src/test/regress/expected/copy2.out +++ b/src/test/regress/expected/copy2.out @@ -49,7 +49,7 @@ CONTEXT: COPY x, line 1: "2002 232 40 50 60 70 80" -- various COPY options: delimiters, oids, NULL string COPY x (b, c, d, e) from stdin with oids delimiter ',' null 'x'; COPY x from stdin WITH DELIMITER AS ';' NULL AS ''; -COPY x from stdin WITH DELIMITER AS ':' NULL AS '\\X'; +COPY x from stdin WITH DELIMITER AS ':' NULL AS E'\\X'; -- check results of copy in SELECT * FROM x; a | b | c | d | e @@ -176,8 +176,8 @@ CREATE TABLE y ( col1 text, col2 text ); -INSERT INTO y VALUES ('Jackson, Sam', '\\h'); -INSERT INTO y VALUES ('It is "perfect".','\t'); +INSERT INTO y VALUES ('Jackson, Sam', E'\\h'); +INSERT INTO y VALUES ('It is "perfect".',E'\t'); INSERT INTO y VALUES ('', NULL); COPY y TO stdout WITH CSV; "Jackson, Sam",\h @@ -187,7 +187,7 @@ COPY y TO stdout WITH CSV QUOTE '''' DELIMITER '|'; Jackson, Sam|\h It is "perfect".| ''| -COPY y TO stdout WITH CSV FORCE QUOTE col2 ESCAPE '\\'; +COPY y TO stdout WITH CSV FORCE QUOTE col2 ESCAPE E'\\'; "Jackson, Sam","\\h" "It is \"perfect\"."," " "", diff --git a/src/test/regress/expected/int8.out b/src/test/regress/expected/int8.out index 164285dd65..c62d133074 100644 --- a/src/test/regress/expected/int8.out +++ b/src/test/regress/expected/int8.out @@ -280,7 +280,7 @@ SELECT '' AS to_char_15, to_char(q2, 'S 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 . 9 9 9' | -4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 . 0 0 0 (5 rows) -SELECT '' AS to_char_16, to_char(q2, '99999 "text" 9999 "9999" 999 "\\"text between quote marks\\"" 9999') FROM INT8_TBL; +SELECT '' AS to_char_16, to_char(q2, E'99999 "text" 9999 "9999" 999 "\\"text between quote marks\\"" 9999') FROM INT8_TBL; to_char_16 | to_char ------------+----------------------------------------------------------- | text 9999 "text between quote marks" 456 diff --git a/src/test/regress/expected/numeric.out b/src/test/regress/expected/numeric.out index 7d075a2a8e..6f88c541e4 100644 --- a/src/test/regress/expected/numeric.out +++ b/src/test/regress/expected/numeric.out @@ -1072,7 +1072,7 @@ SELECT '' AS to_char_19, to_char(val, 'FMS 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 . 9 9 | -2 4 9 2 6 8 0 4 . 0 4 5 0 4 7 4 2 (10 rows) -SELECT '' AS to_char_20, to_char(val, '99999 "text" 9999 "9999" 999 "\\"text between quote marks\\"" 9999') FROM num_data; +SELECT '' AS to_char_20, to_char(val, E'99999 "text" 9999 "9999" 999 "\\"text between quote marks\\"" 9999') FROM num_data; to_char_20 | to_char ------------+----------------------------------------------------------- | text 9999 "text between quote marks" 0 diff --git a/src/test/regress/expected/rowtypes.out b/src/test/regress/expected/rowtypes.out index 384e5ad6d5..ce3bd80db7 100644 --- a/src/test/regress/expected/rowtypes.out +++ b/src/test/regress/expected/rowtypes.out @@ -25,7 +25,7 @@ select '(Joe,von Blow)'::fullname, '(Joe,d''Blow)'::fullname; (Joe,"von Blow") | (Joe,d'Blow) (1 row) -select '(Joe,"von""Blow")'::fullname, '(Joe,d\\\\Blow)'::fullname; +select '(Joe,"von""Blow")'::fullname, E'(Joe,d\\\\Blow)'::fullname; fullname | fullname -------------------+----------------- (Joe,"von""Blow") | (Joe,"d\\Blow") diff --git a/src/test/regress/expected/timestamp.out b/src/test/regress/expected/timestamp.out index d6f14ff6ef..06da4578a9 100644 --- a/src/test/regress/expected/timestamp.out +++ b/src/test/regress/expected/timestamp.out @@ -1044,7 +1044,7 @@ SELECT '' AS to_char_5, to_char(d1, 'HH HH12 HH24 MI SS SSSS') | 05 05 17 32 01 63121 (64 rows) -SELECT '' AS to_char_6, to_char(d1, '"HH:MI:SS is" HH:MI:SS "\\"text between quote marks\\""') +SELECT '' AS to_char_6, to_char(d1, E'"HH:MI:SS is" HH:MI:SS "\\"text between quote marks\\""') FROM TIMESTAMP_TBL; to_char_6 | to_char -----------+------------------------------------------------- @@ -1358,7 +1358,7 @@ SELECT '' AS to_timestamp_5, to_timestamp('1,582nd VIII 21', 'Y,YYYth FMRM DD'); (1 row) SELECT '' AS to_timestamp_6, to_timestamp('15 "text between quote marks" 98 54 45', - 'HH "\\text between quote marks\\"" YY MI SS'); + E'HH "\\text between quote marks\\"" YY MI SS'); to_timestamp_6 | to_timestamp ----------------+------------------------------ | Thu Jan 01 15:54:45 1998 PST diff --git a/src/test/regress/expected/timestamptz.out b/src/test/regress/expected/timestamptz.out index 20560b6bc8..a779e00d22 100644 --- a/src/test/regress/expected/timestamptz.out +++ b/src/test/regress/expected/timestamptz.out @@ -1041,7 +1041,7 @@ SELECT '' AS to_char_5, to_char(d1, 'HH HH12 HH24 MI SS SSSS') | 05 05 17 32 01 63121 (64 rows) -SELECT '' AS to_char_6, to_char(d1, '"HH:MI:SS is" HH:MI:SS "\\"text between quote marks\\""') +SELECT '' AS to_char_6, to_char(d1, E'"HH:MI:SS is" HH:MI:SS "\\"text between quote marks\\""') FROM TIMESTAMPTZ_TBL; to_char_6 | to_char -----------+------------------------------------------------- @@ -1427,7 +1427,7 @@ SELECT '' AS to_timestamp_5, to_timestamp('1,582nd VIII 21', 'Y,YYYth FMRM DD'); (1 row) SELECT '' AS to_timestamp_6, to_timestamp('15 "text between quote marks" 98 54 45', - 'HH "\\text between quote marks\\"" YY MI SS'); + E'HH "\\text between quote marks\\"" YY MI SS'); to_timestamp_6 | to_timestamp ----------------+------------------------------ | Thu Jan 01 15:54:45 1998 PST diff --git a/src/test/regress/expected/type_sanity.out b/src/test/regress/expected/type_sanity.out index 0ff4391258..0eb6bb8e96 100644 --- a/src/test/regress/expected/type_sanity.out +++ b/src/test/regress/expected/type_sanity.out @@ -59,7 +59,7 @@ WHERE (p1.typtype = 'c' AND p1.typrelid = 0) OR -- NOTE: as of 8.0, this check finds smgr and unknown. SELECT p1.oid, p1.typname FROM pg_type as p1 -WHERE p1.typtype in ('b') AND p1.typname NOT LIKE '\\_%' AND NOT EXISTS +WHERE p1.typtype in ('b') AND p1.typname NOT LIKE E'\\_%' AND NOT EXISTS (SELECT 1 FROM pg_type as p2 WHERE p2.typname = ('_' || p1.typname)::name AND p2.typelem = p1.oid); diff --git a/src/test/regress/input/copy.source b/src/test/regress/input/copy.source index 98dc272ce7..58fe2a0b45 100644 --- a/src/test/regress/input/copy.source +++ b/src/test/regress/input/copy.source @@ -62,10 +62,10 @@ create temp table copytest ( test text, filler int); -insert into copytest values('DOS','abc\r\ndef',1); -insert into copytest values('Unix','abc\ndef',2); -insert into copytest values('Mac','abc\rdef',3); -insert into copytest values('esc\\ape','a\\r\\\r\\\n\\nb',4); +insert into copytest values('DOS',E'abc\r\ndef',1); +insert into copytest values('Unix',E'abc\ndef',2); +insert into copytest values('Mac',E'abc\rdef',3); +insert into copytest values(E'esc\\ape',E'a\\r\\\r\\\n\\nb',4); copy copytest to '@abs_builddir@/results/copytest.csv' csv; @@ -79,9 +79,9 @@ truncate copytest2; --- same test but with an escape char different from quote char -copy copytest to '@abs_builddir@/results/copytest.csv' csv quote '\'' escape '\\'; +copy copytest to '@abs_builddir@/results/copytest.csv' csv quote '''' escape E'\\'; -copy copytest2 from '@abs_builddir@/results/copytest.csv' csv quote '\'' escape '\\'; +copy copytest2 from '@abs_builddir@/results/copytest.csv' csv quote '''' escape E'\\'; select * from copytest except select * from copytest2; diff --git a/src/test/regress/output/copy.source b/src/test/regress/output/copy.source index e6839d3f36..afdaa509d2 100644 --- a/src/test/regress/output/copy.source +++ b/src/test/regress/output/copy.source @@ -37,10 +37,10 @@ create temp table copytest ( style text, test text, filler int); -insert into copytest values('DOS','abc\r\ndef',1); -insert into copytest values('Unix','abc\ndef',2); -insert into copytest values('Mac','abc\rdef',3); -insert into copytest values('esc\\ape','a\\r\\\r\\\n\\nb',4); +insert into copytest values('DOS',E'abc\r\ndef',1); +insert into copytest values('Unix',E'abc\ndef',2); +insert into copytest values('Mac',E'abc\rdef',3); +insert into copytest values(E'esc\\ape',E'a\\r\\\r\\\n\\nb',4); copy copytest to '@abs_builddir@/results/copytest.csv' csv; create temp table copytest2 (like copytest); copy copytest2 from '@abs_builddir@/results/copytest.csv' csv; @@ -51,8 +51,8 @@ select * from copytest except select * from copytest2; truncate copytest2; --- same test but with an escape char different from quote char -copy copytest to '@abs_builddir@/results/copytest.csv' csv quote '\'' escape '\\'; -copy copytest2 from '@abs_builddir@/results/copytest.csv' csv quote '\'' escape '\\'; +copy copytest to '@abs_builddir@/results/copytest.csv' csv quote '''' escape E'\\'; +copy copytest2 from '@abs_builddir@/results/copytest.csv' csv quote '''' escape E'\\'; select * from copytest except select * from copytest2; style | test | filler -------+------+-------- diff --git a/src/test/regress/sql/arrays.sql b/src/test/regress/sql/arrays.sql index 37ef80bb5c..bc4d1345fb 100644 --- a/src/test/regress/sql/arrays.sql +++ b/src/test/regress/sql/arrays.sql @@ -204,7 +204,7 @@ select 'foo' ilike all (array['F%', '%O']); -- t -- none of the following should be accepted select '{{1,{2}},{2,3}}'::text[]; select '{{},{}}'::text[]; -select '{{1,2},\\{2,3}}'::text[]; +select E'{{1,2},\\{2,3}}'::text[]; select '{{"1 2" x},{3}}'::text[]; select '{}}'::text[]; select '{ }}'::text[]; diff --git a/src/test/regress/sql/copy2.sql b/src/test/regress/sql/copy2.sql index eb1a69c095..add8214d19 100644 --- a/src/test/regress/sql/copy2.sql +++ b/src/test/regress/sql/copy2.sql @@ -83,7 +83,7 @@ COPY x from stdin WITH DELIMITER AS ';' NULL AS ''; 3000;;c;; \. -COPY x from stdin WITH DELIMITER AS ':' NULL AS '\\X'; +COPY x from stdin WITH DELIMITER AS ':' NULL AS E'\\X'; 4000:\X:C:\X:\X 4001:1:empty:: 4002:2:null:\X:\X @@ -121,13 +121,13 @@ CREATE TABLE y ( col2 text ); -INSERT INTO y VALUES ('Jackson, Sam', '\\h'); -INSERT INTO y VALUES ('It is "perfect".','\t'); +INSERT INTO y VALUES ('Jackson, Sam', E'\\h'); +INSERT INTO y VALUES ('It is "perfect".',E'\t'); INSERT INTO y VALUES ('', NULL); COPY y TO stdout WITH CSV; COPY y TO stdout WITH CSV QUOTE '''' DELIMITER '|'; -COPY y TO stdout WITH CSV FORCE QUOTE col2 ESCAPE '\\'; +COPY y TO stdout WITH CSV FORCE QUOTE col2 ESCAPE E'\\'; --test that we read consecutive LFs properly diff --git a/src/test/regress/sql/int8.sql b/src/test/regress/sql/int8.sql index ec7766219d..4642c012cd 100644 --- a/src/test/regress/sql/int8.sql +++ b/src/test/regress/sql/int8.sql @@ -61,5 +61,5 @@ SELECT '' AS to_char_12, to_char(q2, 'FM9999999999999999.000') FROM INT8_TBL; SELECT '' AS to_char_13, to_char(q2, 'L9999999999999999.000') FROM INT8_TBL; SELECT '' AS to_char_14, to_char(q2, 'FM9999999999999999.999') FROM INT8_TBL; SELECT '' AS to_char_15, to_char(q2, 'S 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 . 9 9 9') FROM INT8_TBL; -SELECT '' AS to_char_16, to_char(q2, '99999 "text" 9999 "9999" 999 "\\"text between quote marks\\"" 9999') FROM INT8_TBL; +SELECT '' AS to_char_16, to_char(q2, E'99999 "text" 9999 "9999" 999 "\\"text between quote marks\\"" 9999') FROM INT8_TBL; SELECT '' AS to_char_17, to_char(q2, '999999SG9999999999') FROM INT8_TBL; diff --git a/src/test/regress/sql/numeric.sql b/src/test/regress/sql/numeric.sql index ffc1673339..b6f69b6f7d 100644 --- a/src/test/regress/sql/numeric.sql +++ b/src/test/regress/sql/numeric.sql @@ -742,7 +742,7 @@ SELECT '' AS to_char_16, to_char(val, 'L9999999999999999.099999999999999') FROM SELECT '' AS to_char_17, to_char(val, 'FM9999999999999999.99999999999999') FROM num_data; SELECT '' AS to_char_18, to_char(val, 'S 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 . 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9') FROM num_data; SELECT '' AS to_char_19, to_char(val, 'FMS 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 . 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9') FROM num_data; -SELECT '' AS to_char_20, to_char(val, '99999 "text" 9999 "9999" 999 "\\"text between quote marks\\"" 9999') FROM num_data; +SELECT '' AS to_char_20, to_char(val, E'99999 "text" 9999 "9999" 999 "\\"text between quote marks\\"" 9999') FROM num_data; SELECT '' AS to_char_21, to_char(val, '999999SG9999999999') FROM num_data; SELECT '' AS to_char_22, to_char(val, 'FM9999999999999999.999999999999999') FROM num_data; diff --git a/src/test/regress/sql/rowtypes.sql b/src/test/regress/sql/rowtypes.sql index e53197c05b..d09ff662ab 100644 --- a/src/test/regress/sql/rowtypes.sql +++ b/src/test/regress/sql/rowtypes.sql @@ -20,7 +20,7 @@ select row('Joe', 'Blow')::fullname, '(Joe,Blow)'::fullname; select '(Joe,von Blow)'::fullname, '(Joe,d''Blow)'::fullname; -select '(Joe,"von""Blow")'::fullname, '(Joe,d\\\\Blow)'::fullname; +select '(Joe,"von""Blow")'::fullname, E'(Joe,d\\\\Blow)'::fullname; select '(Joe,"Blow,Jr")'::fullname; diff --git a/src/test/regress/sql/timestamp.sql b/src/test/regress/sql/timestamp.sql index ceda76f546..3a788f9756 100644 --- a/src/test/regress/sql/timestamp.sql +++ b/src/test/regress/sql/timestamp.sql @@ -186,7 +186,7 @@ SELECT '' AS to_char_4, to_char(d1, 'FMY,YYY FMYYYY FMYYY FMYY FMY FMCC FMQ FMMM SELECT '' AS to_char_5, to_char(d1, 'HH HH12 HH24 MI SS SSSS') FROM TIMESTAMP_TBL; -SELECT '' AS to_char_6, to_char(d1, '"HH:MI:SS is" HH:MI:SS "\\"text between quote marks\\""') +SELECT '' AS to_char_6, to_char(d1, E'"HH:MI:SS is" HH:MI:SS "\\"text between quote marks\\""') FROM TIMESTAMP_TBL; SELECT '' AS to_char_7, to_char(d1, 'HH24--text--MI--text--SS') @@ -211,7 +211,7 @@ SELECT '' AS to_timestamp_4, to_timestamp('My birthday-> Year: 1976, Month: May, SELECT '' AS to_timestamp_5, to_timestamp('1,582nd VIII 21', 'Y,YYYth FMRM DD'); SELECT '' AS to_timestamp_6, to_timestamp('15 "text between quote marks" 98 54 45', - 'HH "\\text between quote marks\\"" YY MI SS'); + E'HH "\\text between quote marks\\"" YY MI SS'); SELECT '' AS to_timestamp_7, to_timestamp('05121445482000', 'MMDDHHMISSYYYY'); diff --git a/src/test/regress/sql/timestamptz.sql b/src/test/regress/sql/timestamptz.sql index 12572fa7ce..f76f2887e7 100644 --- a/src/test/regress/sql/timestamptz.sql +++ b/src/test/regress/sql/timestamptz.sql @@ -179,7 +179,7 @@ SELECT '' AS to_char_4, to_char(d1, 'FMY,YYY FMYYYY FMYYY FMYY FMY FMCC FMQ FMMM SELECT '' AS to_char_5, to_char(d1, 'HH HH12 HH24 MI SS SSSS') FROM TIMESTAMPTZ_TBL; -SELECT '' AS to_char_6, to_char(d1, '"HH:MI:SS is" HH:MI:SS "\\"text between quote marks\\""') +SELECT '' AS to_char_6, to_char(d1, E'"HH:MI:SS is" HH:MI:SS "\\"text between quote marks\\""') FROM TIMESTAMPTZ_TBL; SELECT '' AS to_char_7, to_char(d1, 'HH24--text--MI--text--SS') @@ -207,7 +207,7 @@ SELECT '' AS to_timestamp_4, to_timestamp('My birthday-> Year: 1976, Month: May, SELECT '' AS to_timestamp_5, to_timestamp('1,582nd VIII 21', 'Y,YYYth FMRM DD'); SELECT '' AS to_timestamp_6, to_timestamp('15 "text between quote marks" 98 54 45', - 'HH "\\text between quote marks\\"" YY MI SS'); + E'HH "\\text between quote marks\\"" YY MI SS'); SELECT '' AS to_timestamp_7, to_timestamp('05121445482000', 'MMDDHHMISSYYYY'); diff --git a/src/test/regress/sql/type_sanity.sql b/src/test/regress/sql/type_sanity.sql index 2dc2c6267c..20f6a75ffa 100644 --- a/src/test/regress/sql/type_sanity.sql +++ b/src/test/regress/sql/type_sanity.sql @@ -54,7 +54,7 @@ WHERE (p1.typtype = 'c' AND p1.typrelid = 0) OR SELECT p1.oid, p1.typname FROM pg_type as p1 -WHERE p1.typtype in ('b') AND p1.typname NOT LIKE '\\_%' AND NOT EXISTS +WHERE p1.typtype in ('b') AND p1.typname NOT LIKE E'\\_%' AND NOT EXISTS (SELECT 1 FROM pg_type as p2 WHERE p2.typname = ('_' || p1.typname)::name AND p2.typelem = p1.oid);