diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 7feadeac1693e7ff46f44ef3ad9ea2fa86bf46a8..e4ff76e66e0990d91790ccc54615c26dd64a143e 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -67,15 +67,33 @@ #include "utils/xml.h" -/* Location tracking support --- simpler than bison's default */ +/* + * Location tracking support --- simpler than bison's default, since we only + * want to track the start position not the end position of each nonterminal. + */ #define YYLLOC_DEFAULT(Current, Rhs, N) \ do { \ - if (N) \ + if ((N) > 0) \ (Current) = (Rhs)[1]; \ else \ - (Current) = (Rhs)[0]; \ + (Current) = (-1); \ } while (0) +/* + * The above macro assigns -1 (unknown) as the parse location of any + * nonterminal that was reduced from an empty rule. This is problematic + * for nonterminals defined like + * OptFooList: / * EMPTY * / { ... } | OptFooList Foo { ... } ; + * because we'll set -1 as the location during the first reduction and then + * copy it during each subsequent reduction, leaving us with -1 for the + * location even when the list is not empty. To fix that, do this in the + * action for the nonempty rule(s): + * if (@$ < 0) @$ = @2; + * (Although we have many nonterminals that follow this pattern, we only + * bother with fixing @$ like this when the nonterminal's parse location + * is actually referenced in some rule.) + */ + /* * Bison doesn't allocate anything that needs to live across parser calls, * so we can easily have it use palloc instead of malloc. This prevents @@ -1223,8 +1241,14 @@ OptSchemaName: ; OptSchemaEltList: - OptSchemaEltList schema_stmt { $$ = lappend($1, $2); } - | /* EMPTY */ { $$ = NIL; } + OptSchemaEltList schema_stmt + { + if (@$ < 0) /* see comments for YYLLOC_DEFAULT */ + @$ = @2; + $$ = lappend($1, $2); + } + | /* EMPTY */ + { $$ = NIL; } ; /* diff --git a/src/test/regress/expected/namespace.out b/src/test/regress/expected/namespace.out index 5fcd46daf42705147f53599d657e52d8fe7b5b1f..9187c8126a3ffa32e365400816b262daf3b6f2d5 100644 --- a/src/test/regress/expected/namespace.out +++ b/src/test/regress/expected/namespace.out @@ -47,8 +47,8 @@ CREATE SCHEMA IF NOT EXISTS test_schema_1 -- fail, disallowed b int UNIQUE ); ERROR: CREATE SCHEMA IF NOT EXISTS cannot include schema elements -LINE 1: CREATE SCHEMA IF NOT EXISTS test_schema_1 - ^ +LINE 2: CREATE TABLE abc ( + ^ DROP SCHEMA test_schema_1 CASCADE; NOTICE: drop cascades to 2 other objects DETAIL: drop cascades to table test_schema_1.abc