]> granicus.if.org Git - postgresql/commitdiff
Catch syntax error in generated column definition
authorPeter Eisentraut <peter@eisentraut.org>
Mon, 1 Apr 2019 08:46:37 +0000 (10:46 +0200)
committerPeter Eisentraut <peter@eisentraut.org>
Mon, 1 Apr 2019 08:46:37 +0000 (10:46 +0200)
The syntax

    GENERATED BY DEFAULT AS (expr)

is not allowed but we have to accept it in the grammar to avoid
shift/reduce conflicts because of the similar syntax for identity
columns.  The existing code just ignored this, incorrectly.  Add an
explicit error check and a bespoke error message.

Reported-by: Justin Pryzby <pryzby@telsasoft.com>
src/backend/parser/gram.y
src/test/regress/expected/generated.out
src/test/regress/sql/generated.sql

index 01521789e82e5fd8668693c5c904ec179d9bb004..b51f12dc2322f5ef146ee7e5c06829732d1754d4 100644 (file)
@@ -3505,6 +3505,19 @@ ColConstraintElem:
                                        n->raw_expr = $5;
                                        n->cooked_expr = NULL;
                                        n->location = @1;
+
+                                       /*
+                                        * Can't do this in the grammar because of shift/reduce
+                                        * conflicts.  (IDENTITY allows both ALWAYS and BY
+                                        * DEFAULT, but generated columns only allow ALWAYS.)  We
+                                        * can also give a more useful error message and location.
+                                        */
+                                       if ($2 != ATTRIBUTE_IDENTITY_ALWAYS)
+                                               ereport(ERROR,
+                                                               (errcode(ERRCODE_SYNTAX_ERROR),
+                                                                errmsg("for a generated column, GENERATED ALWAYS must be specified"),
+                                                                parser_errposition(@2)));
+
                                        $$ = (Node *)n;
                                }
                        | REFERENCES qualified_name opt_column_list key_match key_actions
index e0d1d88f17ea1ff67f960cf33f38f80274556140..d4ed3f7ae1bed26aa746fe2f13d2d58ad20cdb5b 100644 (file)
@@ -85,6 +85,11 @@ CREATE TABLE gtest_err_7d (a int PRIMARY KEY, b int GENERATED ALWAYS AS (generat
 ERROR:  set-returning functions are not allowed in column generation expressions
 LINE 1: ...7d (a int PRIMARY KEY, b int GENERATED ALWAYS AS (generate_s...
                                                              ^
+-- GENERATED BY DEFAULT not allowed
+CREATE TABLE gtest_err_8 (a int PRIMARY KEY, b int GENERATED BY DEFAULT AS (a * 2) STORED);
+ERROR:  for a generated column, GENERATED ALWAYS must be specified
+LINE 1: ...E gtest_err_8 (a int PRIMARY KEY, b int GENERATED BY DEFAULT...
+                                                             ^
 INSERT INTO gtest1 VALUES (1);
 INSERT INTO gtest1 VALUES (2, DEFAULT);
 INSERT INTO gtest1 VALUES (3, 33);  -- error
index 6d71594dc43d8b5c312bbeb63e23fb3d18246aca..da11b8c9b89a80bf2abb70aceb046b0ff2dcd324 100644 (file)
@@ -37,6 +37,9 @@ CREATE TABLE gtest_err_7b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (row_num
 CREATE TABLE gtest_err_7c (a int PRIMARY KEY, b int GENERATED ALWAYS AS ((SELECT a)) STORED);
 CREATE TABLE gtest_err_7d (a int PRIMARY KEY, b int GENERATED ALWAYS AS (generate_series(1, a)) STORED);
 
+-- GENERATED BY DEFAULT not allowed
+CREATE TABLE gtest_err_8 (a int PRIMARY KEY, b int GENERATED BY DEFAULT AS (a * 2) STORED);
+
 INSERT INTO gtest1 VALUES (1);
 INSERT INTO gtest1 VALUES (2, DEFAULT);
 INSERT INTO gtest1 VALUES (3, 33);  -- error