Reads sql the way dialect splits it into tokens. Returns the string literals, quoted
identifiers and comments it contains, and the code that remains.
Both dialects: '…' and N'…' strings, in which '' is an escaped quote and a backslash is an
ordinary character; "…" identifiers with "" escapes; -- comments to the end of the line; and
nested block comments. SQL Server adds […] identifiers with ]] escapes. PostgreSQL adds E'…'
strings, in which a backslash escapes the next character, dollar-quoted strings ($$…$$,
$tag$…$tag$), and U&"…" identifiers, read as one identifier whose \XXXX and \+XXXXXX
escapes (or those of the character a following UESCAPE '<c>' names) are decoded, so the name is
the one PostgreSQL resolves; a [ is code there.
🚨 Do not add backslash escapes to plain '…' strings. Neither server honors them (PostgreSQL is
assumed to run with standard_conforming_strings = on, its default since 9.1), and a scanner that
does reads x = 'a\') ; DROP TABLE t; --' as one literal while the database runs the DROP.
The scan stops and reports an error, instead of guessing, when:
a string, quoted identifier, dollar-quoted string or block comment is not closed;
the text contains a NUL character;
a -- comment contains a line break other than \n or \r\n;
a PostgreSQL E'…' string is followed by another quoted segment, which PostgreSQL can join to
it and read with backslash escapes;
a PostgreSQL U&"…" identifier has an escape or a UESCAPE clause PostgreSQL would reject;
on SQL Server, a number is followed by e and a word character (1EXEC splits two ways).
Reads
sqlthe waydialectsplits it into tokens. Returns the string literals, quoted identifiers and comments it contains, and the code that remains.Both dialects:
'…'andN'…'strings, in which''is an escaped quote and a backslash is an ordinary character;"…"identifiers with""escapes;--comments to the end of the line; and nested block comments. SQL Server adds[…]identifiers with]]escapes. PostgreSQL addsE'…'strings, in which a backslash escapes the next character, dollar-quoted strings ($$…$$,$tag$…$tag$), andU&"…"identifiers, read as one identifier whose\XXXXand\+XXXXXXescapes (or those of the character a followingUESCAPE '<c>'names) are decoded, so the name is the one PostgreSQL resolves; a[is code there.🚨 Do not add backslash escapes to plain
'…'strings. Neither server honors them (PostgreSQL is assumed to run withstandard_conforming_strings = on, its default since 9.1), and a scanner that does readsx = 'a\') ; DROP TABLE t; --'as one literal while the database runs the DROP.The scan stops and reports an error, instead of guessing, when:
--comment contains a line break other than\nor\r\n;E'…'string is followed by another quoted segment, which PostgreSQL can join to it and read with backslash escapes;U&"…"identifier has an escape or aUESCAPEclause PostgreSQL would reject;eand a word character (1EXECsplits two ways).