aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/parser/gram.y34
-rw-r--r--src/test/regress/expected/namespace.out4
2 files changed, 31 insertions, 7 deletions
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 7feadeac169..e4ff76e66e0 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -67,16 +67,34 @@
#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
* memory leaks if we error out during parsing. Note this only works with
@@ -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 5fcd46daf42..9187c8126a3 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