This will have its consequences for libpqxx support. I found the topic confusing, documentation didn't give me certainty, so I took some time to get clarity. I tried both psql and libpqxx calls.
Here's what I found:
Identifiers
Table names and such can be written in double quotes. I tested this by
creating a table with a quoted column name, and using PQfname().
- Doubling a double-quote escapes it:
"""" reads as a string containing
one double-quote.
- Backslash is just a character. It does not escape anything.
- When
standard_conforming_strings is disabled, neither seems to change.
Hstore strings
Keys and values in hstore entries should be in double quotes if they contain
certain unusual characters. (In practice, backslash-escaping works fine in
unquoted strings as well but there may be characters it does not support.)
This is a bit harder to reason about, since I'm writing these double-quoted
strings inside single-quoted strings inside C++ string literals. But AFAIK a
double-quote character is just not special at all inside a single-quoted
string.
I ran SELECT ($1::hstore)[1] with various values for parameter $1:
1=>ab, 1=>"a\"b", etc.
- Doubling a double-quote seems to be meaningless. The first one closes the
string and you get a syntax error.
- Backslash escapes a double-quote.
- When
standard_conforming_strings is disabled, neither seems to change.
Array entries
The situation with array entries is similar: entries can be in double quotes.
- Doubling a double-quote seems to be meaningless. The first one closes the
string and you get a syntax error.
- Backslash escapes a double-quote.
- When
standard_conforming_strings is disabled, neither seems to change.
Composite entries
Values within a composite are different.
- Doubling a double-quote seems to escape it.
- Backslash also escapes a double quote.
- When
standard_conforming_strings is disabled, backslash no longer works as an escape character — but confusingly you get an error message saying you should use backslash as an escape character:
BEGIN;
SET standard_conforming_strings = on; -- (This is the default)
CREATE TYPE foo AS (x text);
SELECT '("a""b")'::foo; -- OK: ("a""b")
SELECT '("a\"b")'::foo; -- OK: ("a""b")
SET standard_conforming_strings = off; -- (Going back to pre-9.1 nonstandard behaviour)
SELECT '("a""b")'::foo; -- OK: ("a""b")
-- Now we need to double the escaping backslash to get around the nonstandard string handling.
SELECT '("a\\"b")'::foo; -- OK: ("a ""b") (with a warning).
SELECT '("a\"b")'::foo; -- ERROR: malformed record literal
ROLLBACK;
That last check fails with:
WARNING: nonstandard use of escape in a string literal
LINE 1: SELECT '("a\"b")'::foo;
^
HINT: Use the escape string syntax for escapes, e.g., E'\r\n'.
ERROR: malformed record literal: "("a"b")"
LINE 1: SELECT '("a\"b")'::foo;
^
DETAIL: Unexpected end of input.
Conclusion
There seem to be 3 kinds of double-quoted strings: identifier strings, value strings, and composite field strings.
- Identifier strings use SQL-style escaping: to embed a double-quote character, you write two double-quote characters. Backslash has no special meaning.
- Value strings (as in array entries and hstore keys/values) use the backslash as an escape character. Writing two double-quote characters has no special meaning (and in fact if you wanted two double-quotes you'd need to escape them both with backslashes).
- Composite value strings support both SQL-style escaping (by repeating the quote character) and backslash-escaping, but the latter only if
standard_conforming_strings is enabled (as is the default).
I don't think libpqxx needs a parser for identifier strings anywhere, but it does for the other kinds. Do we need specialised parsers for some of these different cases?
This will have its consequences for libpqxx support. I found the topic confusing, documentation didn't give me certainty, so I took some time to get clarity. I tried both psql and libpqxx calls.
Here's what I found:
Identifiers
Table names and such can be written in double quotes. I tested this by
creating a table with a quoted column name, and using
PQfname().""""reads as a string containingone double-quote.
standard_conforming_stringsis disabled, neither seems to change.Hstore strings
Keys and values in hstore entries should be in double quotes if they contain
certain unusual characters. (In practice, backslash-escaping works fine in
unquoted strings as well but there may be characters it does not support.)
This is a bit harder to reason about, since I'm writing these double-quoted
strings inside single-quoted strings inside C++ string literals. But AFAIK a
double-quote character is just not special at all inside a single-quoted
string.
I ran
SELECT ($1::hstore)[1]with various values for parameter$1:1=>ab,1=>"a\"b", etc.string and you get a syntax error.
standard_conforming_stringsis disabled, neither seems to change.Array entries
The situation with array entries is similar: entries can be in double quotes.
string and you get a syntax error.
standard_conforming_stringsis disabled, neither seems to change.Composite entries
Values within a composite are different.
standard_conforming_stringsis disabled, backslash no longer works as an escape character — but confusingly you get an error message saying you should use backslash as an escape character:That last check fails with:
Conclusion
There seem to be 3 kinds of double-quoted strings: identifier strings, value strings, and composite field strings.
standard_conforming_stringsis enabled (as is the default).I don't think libpqxx needs a parser for identifier strings anywhere, but it does for the other kinds. Do we need specialised parsers for some of these different cases?