diff options
| author | Tom Lane <tgl@sss.pgh.pa.us> | 2009-04-19 18:52:58 +0000 |
|---|---|---|
| committer | Tom Lane <tgl@sss.pgh.pa.us> | 2009-04-19 18:52:58 +0000 |
| commit | 3a624e9200bbd8b88d7724e1448fe530f32e2c3c (patch) | |
| tree | 1b540115b0ae55108784c32d7bd1473f10312657 /src/test | |
| parent | 7f2f798b30b53dc24bee78ec4e1f3c2d0d987de0 (diff) | |
| download | postgresql-3a624e9200bbd8b88d7724e1448fe530f32e2c3c.tar.gz | |
Revise plpgsql's scanner to process comments and string literals in a way
more nearly matching the core SQL scanner. The user-visible effects are:
* Block comments (slash-star comments) now nest, as per SQL spec.
* In standard_conforming_strings mode, backslash as the last character of a
non-E string literal is now correctly taken as an ordinary character;
formerly it was misinterpreted as escaping the ending quote. (Since the
string also had to pass through the core scanner, this invariably led
to syntax errors.)
* Formerly, backslashes in the format string of RAISE were always treated as
quoting the next character, regardless of mode. Now, they are ordinary
characters with standard_conforming_strings on, while with it off, they
introduce the same set of escapes as in the core SQL scanner. Also,
escape_string_warning is now effective for RAISE format strings. These
changes make RAISE format strings work just like any other string literal.
This is implemented by copying and pasting a lot of logic from the core
scanner. It would be a good idea to look into getting rid of plpgsql's
scanner entirely in favor of using the core scanner. However, that involves
more change than I can justify making during beta --- in particular, the core
scanner would have to become re-entrant.
In passing, remove the kluge that made the plpgsql scanner emit T_FUNCTION or
T_TRIGGER as a made-up first token. That presumably had some value once upon
a time, but now it's just useless complication for both the scanner and the
grammar.
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/regress/expected/plpgsql.out | 71 | ||||
| -rw-r--r-- | src/test/regress/sql/plpgsql.sql | 44 |
2 files changed, 115 insertions, 0 deletions
diff --git a/src/test/regress/expected/plpgsql.out b/src/test/regress/expected/plpgsql.out index 25be3857ab..0446f5193c 100644 --- a/src/test/regress/expected/plpgsql.out +++ b/src/test/regress/expected/plpgsql.out @@ -3737,3 +3737,74 @@ SELECT * FROM leaker_1(true); DROP FUNCTION leaker_1(bool); DROP FUNCTION leaker_2(bool); +-- Test handling of string literals. +set standard_conforming_strings = off; +create or replace function strtest() returns text as $$ +begin + raise notice 'foo\\bar\041baz'; + return 'foo\\bar\041baz'; +end +$$ language plpgsql; +WARNING: nonstandard use of \\ in a string literal +HINT: Use the escape string syntax for backslashes, e.g., E'\\'. +CONTEXT: string literal in PL/PgSQL function "strtest" near line 2 +WARNING: nonstandard use of \\ in a string literal +LINE 1: SELECT 'foo\\bar\041baz' + ^ +HINT: Use the escape string syntax for backslashes, e.g., E'\\'. +QUERY: SELECT 'foo\\bar\041baz' +CONTEXT: SQL statement in PL/PgSQL function "strtest" near line 3 +select strtest(); +NOTICE: foo\bar!baz +WARNING: nonstandard use of \\ in a string literal +LINE 1: SELECT 'foo\\bar\041baz' + ^ +HINT: Use the escape string syntax for backslashes, e.g., E'\\'. +QUERY: SELECT 'foo\\bar\041baz' +CONTEXT: PL/pgSQL function "strtest" line 3 at RETURN + strtest +------------- + foo\bar!baz +(1 row) + +create or replace function strtest() returns text as $$ +begin + raise notice E'foo\\bar\041baz'; + return E'foo\\bar\041baz'; +end +$$ language plpgsql; +select strtest(); +NOTICE: foo\bar!baz + strtest +------------- + foo\bar!baz +(1 row) + +set standard_conforming_strings = on; +create or replace function strtest() returns text as $$ +begin + raise notice 'foo\\bar\041baz\'; + return 'foo\\bar\041baz\'; +end +$$ language plpgsql; +select strtest(); +NOTICE: foo\\bar\041baz\ + strtest +------------------ + foo\\bar\041baz\ +(1 row) + +create or replace function strtest() returns text as $$ +begin + raise notice E'foo\\bar\041baz'; + return E'foo\\bar\041baz'; +end +$$ language plpgsql; +select strtest(); +NOTICE: foo\bar!baz + strtest +------------- + foo\bar!baz +(1 row) + +drop function strtest(); diff --git a/src/test/regress/sql/plpgsql.sql b/src/test/regress/sql/plpgsql.sql index d9026bd117..3dcfc9e781 100644 --- a/src/test/regress/sql/plpgsql.sql +++ b/src/test/regress/sql/plpgsql.sql @@ -3005,3 +3005,47 @@ SELECT * FROM leaker_1(true); DROP FUNCTION leaker_1(bool); DROP FUNCTION leaker_2(bool); + +-- Test handling of string literals. + +set standard_conforming_strings = off; + +create or replace function strtest() returns text as $$ +begin + raise notice 'foo\\bar\041baz'; + return 'foo\\bar\041baz'; +end +$$ language plpgsql; + +select strtest(); + +create or replace function strtest() returns text as $$ +begin + raise notice E'foo\\bar\041baz'; + return E'foo\\bar\041baz'; +end +$$ language plpgsql; + +select strtest(); + +set standard_conforming_strings = on; + +create or replace function strtest() returns text as $$ +begin + raise notice 'foo\\bar\041baz\'; + return 'foo\\bar\041baz\'; +end +$$ language plpgsql; + +select strtest(); + +create or replace function strtest() returns text as $$ +begin + raise notice E'foo\\bar\041baz'; + return E'foo\\bar\041baz'; +end +$$ language plpgsql; + +select strtest(); + +drop function strtest(); |
