]> granicus.if.org Git - postgresql/commitdiff
Add E'' syntax so eventually normal strings can treat backslashes
authorBruce Momjian <bruce@momjian.us>
Sun, 26 Jun 2005 03:04:37 +0000 (03:04 +0000)
committerBruce Momjian <bruce@momjian.us>
Sun, 26 Jun 2005 03:04:37 +0000 (03:04 +0000)
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.

30 files changed:
contrib/tsearch2/expected/tsearch2.out
contrib/tsearch2/sql/tsearch2.sql
doc/src/sgml/runtime.sgml
doc/src/sgml/syntax.sgml
src/backend/parser/scan.l
src/backend/utils/misc/guc.c
src/backend/utils/misc/postgresql.conf.sample
src/bin/initdb/initdb.c
src/bin/pg_dump/pg_dumpall.c
src/bin/psql/describe.c
src/include/catalog/pg_proc.h
src/include/utils/guc.h
src/test/regress/expected/arrays.out
src/test/regress/expected/copy2.out
src/test/regress/expected/int8.out
src/test/regress/expected/numeric.out
src/test/regress/expected/rowtypes.out
src/test/regress/expected/timestamp.out
src/test/regress/expected/timestamptz.out
src/test/regress/expected/type_sanity.out
src/test/regress/input/copy.source
src/test/regress/output/copy.source
src/test/regress/sql/arrays.sql
src/test/regress/sql/copy2.sql
src/test/regress/sql/int8.sql
src/test/regress/sql/numeric.sql
src/test/regress/sql/rowtypes.sql
src/test/regress/sql/timestamp.sql
src/test/regress/sql/timestamptz.sql
src/test/regress/sql/type_sanity.sql

index 9e050ae27934da0ee49b4530be832eefcda12adc..6c266a29ac6c4191f3b573df1a1a345611869127 100644 (file)
@@ -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 <fr>qwer jf sdjk<we hjwer <werrwe> ewr1> ewri2 <a href="qwe<qwe>">
+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 <fr>qwer jf sdjk<we hjwer <werrwe> ewr1> ewri2 <a href="qwe<qwe>">
 /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 
 <i <b> 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 <fr>qwer jf sdjk<we hjwer <werrwe> ewr1> ewri2 <a href="qwe<qwe>">
+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 <fr>qwer jf sdjk<we hjwer <werrwe> ewr1> ewri2 <a href="qwe<qwe>">
 /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 
 <i <b> 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 <fr>qwer jf sdjk<we hjwer <werrwe> ewr1> ewri2 <a href="qwe<qwe>">
+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 <fr>qwer jf sdjk<we hjwer <werrwe> ewr1> ewri2 <a href="qwe<qwe>">
 /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 
 <i <b> 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');
index 0a980608f7c2631e6d7109bb258d29fdc29d2bdf..52e709d74b7a36fa5f7b02bb2e947b92b60819ec 100644 (file)
@@ -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 <fr>qwer jf sdjk<we hjwer <werrwe> ewr1> ewri2 <a href="qwe<qwe>">
+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 <fr>qwer jf sdjk<we hjwer <werrwe> ewr1> ewri2 <a href="qwe<qwe>">
 /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 
 <i <b> 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 <fr>qwer jf sdjk<we hjwer <werrwe> ewr1> ewri2 <a href="qwe<qwe>">
+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 <fr>qwer jf sdjk<we hjwer <werrwe> ewr1> ewri2 <a href="qwe<qwe>">
 /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 
 <i <b> 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 <fr>qwer jf sdjk<we hjwer <werrwe> ewr1> ewri2 <a href="qwe<qwe>">
+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 <fr>qwer jf sdjk<we hjwer <werrwe> ewr1> ewri2 <a href="qwe<qwe>">
 /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 
 <i <b> 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');
index 43334453921b6602208d7019a164782a9d2bc1c0..3841b0dee2d6ab3da034fdcfc87c139c0e5a3a54 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.330 2005/06/21 04:02:30 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.331 2005/06/26 03:03:17 momjian Exp $
 -->
 
 <chapter Id="runtime">
@@ -3757,6 +3757,30 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir'
       </listitem>
      </varlistentry>
 
+     <varlistentry id="guc-escape-string-warning" xreflabel="escape_string_warning">
+      <term><varname>escape_string_warning</varname> (<type>boolean</type>)</term>
+      <indexterm><primary>strings</><secondary>escape</></>
+      <indexterm>
+       <primary><varname>escape_string_warning</> configuration parameter</primary>
+      </indexterm>
+      <listitem>
+       <para>
+        When <literal>on</>, a warning is issued if a backslash
+        (<literal>\</>) appears in a ordinary, non-escape syntax
+        (<literal>''</>) string. To log the statement that generated the
+        warning, set <varname>log_min_error_statement</> to
+        <literal>error</>.  The default is off.
+       </para>
+       <para>
+        Escape string syntax (<literal>E''</>) should be used for
+        escapes, because in future versions of
+        <productname>PostgreSQL</productname> ordinary strings will have
+        the standard-compliant behavior of treating backslashes
+        literally.
+       </para>
+      </listitem>
+     </varlistentry>
+
      </variablelist>
     </sect3>
     <sect3 id="runtime-config-compatible-clients">
@@ -3964,6 +3988,37 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir'
       </listitem>
      </varlistentry>
 
+     <varlistentry id="guc-escape-string-syntax" xreflabel="escape_string_syntax">
+      <term><varname>escape_string_syntax</varname> (<type>boolean</type>)</term>
+      <indexterm><primary>strings</><secondary>escape</></>
+      <indexterm>
+       <primary><varname>escape_string_syntax</> configuration parameter</primary>
+      </indexterm>
+      <listitem>
+       <para>
+        Reports whether escape string syntax (<literal>E''</>) is
+        supported. This variable is used by applications that need to
+        determine if escape string syntax can be used in their code.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry id="guc-sql-standard-strings" xreflabel="standard_compliant_strings">
+      <term><varname>standard_compliant_strings</varname> (<type>boolean</type>)</term>
+      <indexterm><primary>strings</><secondary>escape</></>
+      <indexterm>
+       <primary><varname>standard_compliant_strings</> configuration parameter</primary>
+      </indexterm>
+      <listitem>
+       <para>
+        Reports whether ordinary, non-escape syntax strings
+        (<literal>''</>) treat backslashes literally, as specified in
+        the SQL standard. This variable is used by applications that
+        need to know how ordinary strings are processed`.
+       </para>
+      </listitem>
+     </varlistentry>
+
     </variablelist>
    </sect2>
 
index 45b6a80564b51724d9de5658c2c2c142a7e5dd20..3d8d457c561f5d1d99f683d98c184fb83d814e6c 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/syntax.sgml,v 1.100 2005/06/02 01:23:08 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/syntax.sgml,v 1.101 2005/06/26 03:03:21 momjian Exp $
 -->
 
 <chapter id="sql-syntax">
@@ -247,9 +247,10 @@ UPDATE "my_table" SET "a" = 5;
      write two adjacent single quotes, e.g.
      <literal>'Dianne''s horse'</literal>.
      <productname>PostgreSQL</productname> also allows single quotes
-     to be escaped with a backslash (<literal>\</literal>), so for
-     example the same string could be written
-     <literal>'Dianne\'s horse'</literal>.
+     to be escaped with a backslash (<literal>\'</literal>).  However,
+     future versions of <productname>PostgreSQL</productname> will not
+     support this so applications using this should convert to the 
+     standard-compliant method outlined above.
     </para>
 
     <para>
@@ -268,6 +269,20 @@ UPDATE "my_table" SET "a" = 5;
      include a backslash in a string constant, write two backslashes.
     </para>
 
+    <note>
+    <para>
+     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 <literal>E</literal> (upper or lower case) before
+     the string, e.g. <literal>E'\041'</>. This method will work in all
+     future versions of <productname>PostgreSQL</productname>.
+    </para>
+    </note>
+
     <para>
      The character with the code zero cannot be in a string constant.
     </para>
index 0a250e8dbe89aa9db6f74fff08ee9d3cee5c9db7..4c556a5fba29e0f992cde889bd3d6a43f6f70ba1 100644 (file)
@@ -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);
                                }
 <xq>{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]));
                                }
 <xq>{xqoctesc}  {
                                        unsigned char c = strtoul(yytext+1, NULL, 8);
+
+                                       check_escape_warning();
                                        addlitchar(c);
                                }
 <xq>{xqhexesc}  {
                                        unsigned char c = strtoul(yytext+2, NULL, 16);
+
+                                       check_escape_warning();
                                        addlitchar(c);
                                }
 <xq>{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 */
+}
index 05ce93cf58ff2b5d0bd3f07856d557087db428dc..1738604942615a179627518ee1c926bfa5753b85 100644 (file)
@@ -10,7 +10,7 @@
  * Written by Peter Eisentraut <peter_e@gmx.net>.
  *
  * 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
index 4c5a1ed59e31d6eeccdc7a872e8734affea306d1..72f447c76b4ad9fac59ccd4840e4325ec3ed402f 100644 (file)
 #regex_flavor = advanced       # advanced, extended, or basic
 #sql_inheritance = true
 #default_with_oids = false
+#escape_string_warning = false
 
 # - Other Platforms & Clients -
 
index dd830f7c037a060c81918c8f89e7a3b77b89e922..2442f43ddcf583e1a34b048b8014b56f462913c0 100644 (file)
@@ -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';
index 75158a58bfaa556f50159476c5a153986a87ed89..c6a0d3e2085835c797a9820e40d952b33f1bebbf 100644 (file)
@@ -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");
index 392421dc6f60d96de5c4dca8226c762d6e150615..b7397515b73ba6ced40169bd53d7e427e5e31b13 100644 (file)
@@ -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,
index 892835075aa1d25d888ace8eb6d4f1cd728dd27f..049024ae40c0ccc9d20bc0d919dec4b3d9f1f0c3 100644 (file)
@@ -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");
index ed2748e8b23320ab5a55b449e1a229624b4ab10a..c08ecd4db4245d2a15b4ff3e8c0a850f917c2cee 100644 (file)
@@ -7,7 +7,7 @@
  * Copyright (c) 2000-2005, PostgreSQL Global Development Group
  * Written by Peter Eisentraut <peter_e@gmx.net>.
  *
- * $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;
index 80eab4a13da9662ae08c412b154b29863cce3ef6..dcc9e9c1abb7efe7b6b51e9de1402e5dbefdc989 100644 (file)
@@ -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}}"
index 40dd7f24af20b26db01e9e2a3f06d02f35a0a747..78f20605702881203849c0fa49e65b7ec557b6c2 100644 (file)
@@ -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\"."," "
 "",
index 164285dd65a36ef1ede03bddadf92ca5609ac74d..c62d133074197ddc3e5572e1890beb05aa8ab62b 100644 (file)
@@ -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
index 7d075a2a8eecfcbc4d81db54f2efffdb8de1feda..6f88c541e442128b82d4a34daf696b1f85eae2ed 100644 (file)
@@ -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
index 384e5ad6d53baf50ac5f2549a2e5a637db3ca2d8..ce3bd80db7536595a91509466fecd8c7f2551144 100644 (file)
@@ -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")
index d6f14ff6ef3f4a362b8a6b5a23f9a25c51f0259e..06da4578a95c9704440d15c6771237f8ae30e2aa 100644 (file)
@@ -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
index 20560b6bc874a1a6bd4c6eaeb0802bd8c8378a9c..a779e00d223315db22ed184b67fca254eb20aa2b 100644 (file)
@@ -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
index 0ff439125840f126851eb24b6651d12c6f76330d..0eb6bb8e9613c53af17562842b5f0609c86ba866 100644 (file)
@@ -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);
index 98dc272ce783e5c407ba1afaf1a2a4dd7a384ac5..58fe2a0b45d9d39dde0d2d0f05852bac5d76f33e 100644 (file)
@@ -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;
 
index e6839d3f3640935170e692b58a7deb9586805b99..afdaa509d2f3f7d38b6293a569a700d67d7d0bc9 100644 (file)
@@ -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 
 -------+------+--------
index 37ef80bb5c49b094f2268b701abc55b7f8787cf2..bc4d1345fb1c11b131a2959c0a503b4f6ed19114 100644 (file)
@@ -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[];
index eb1a69c095555b06ce9af2a990c353cdbe1ba153..add8214d19dfb43157c7648455d4200232bfdea2 100644 (file)
@@ -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
 
index ec7766219d63e578740970cb1e3f902432ab0a82..4642c012cdc87fb1e9540027f25047122c708a12 100644 (file)
@@ -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;
index ffc16733390c690d35f5ac0827f8d08a446281ad..b6f69b6f7d2428e7d9a49968c0559eef274bf7db 100644 (file)
@@ -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;
 
index e53197c05b5e3fa30530393ea6273c4e205bb4a6..d09ff662abcac7ea073a6374c39c6af2ccc8c3fe 100644 (file)
@@ -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;
 
index ceda76f546a9617fcd0cef8deeabd27260aa53d1..3a788f975655f953e5d88b63f86ecb6c96f15d94 100644 (file)
@@ -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');    
 
index 12572fa7ce44e3eb87cd4662db077296e194b71b..f76f2887e73cfe2a10096b052369a64d5cf727a5 100644 (file)
@@ -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');    
 
index 2dc2c6267ce8e25153b51f9df195d79dec407cab..20f6a75ffae9f5ad6af61a775cce828f0f0f104b 100644 (file)
@@ -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);