Catch syntax error in generated column definition

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>
pull/40/head
Peter Eisentraut 7 years ago
parent 4ae7f02b03
commit 7241911782
  1. 13
      src/backend/parser/gram.y
  2. 5
      src/test/regress/expected/generated.out
  3. 3
      src/test/regress/sql/generated.sql

@ -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

@ -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

@ -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

Loading…
Cancel
Save