diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2021-03-12 11:08:42 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2021-03-12 11:08:42 -0500 |
commit | 6c34f186c4c62ac93b8f5f7229b03301b02741c9 (patch) | |
tree | 852e1855d0a486f53fc11b9af133b9612ece500d | |
parent | ddd4cc09a6e5d775822e0244e73ca9bb894dce42 (diff) | |
download | postgresql-6c34f186c4c62ac93b8f5f7229b03301b02741c9.tar.gz postgresql-6c34f186c4c62ac93b8f5f7229b03301b02741c9.zip |
Forbid marking an identity column as nullable.
GENERATED ALWAYS AS IDENTITY implies NOT NULL, but the code failed
to complain if you overrode that with "GENERATED ALWAYS AS IDENTITY
NULL". One might think the old behavior was a feature, but it was
inconsistent because the outcome varied depending on the order of
the clauses, so it seems to have been just an oversight.
Per bug #16913 from Pavel Boev. Back-patch to v10 where identity
columns were introduced.
Vik Fearing (minor tweaks by me)
Discussion: https://postgr.es/m/16913-3b5198410f67d8c6@postgresql.org
-rw-r--r-- | doc/src/sgml/ref/create_table.sgml | 1 | ||||
-rw-r--r-- | src/backend/parser/parse_utilcmd.c | 10 | ||||
-rw-r--r-- | src/test/regress/expected/identity.out | 13 | ||||
-rw-r--r-- | src/test/regress/sql/identity.sql | 9 |
4 files changed, 33 insertions, 0 deletions
diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index b77cc320512..082d0f259f6 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -750,6 +750,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM column</firstterm>. It will have an implicit sequence attached to it and the column in new rows will automatically have values from the sequence assigned to it. + Such a column is implicitly <literal>NOT NULL</literal>. </para> <para> diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index 9b4874dc11d..76fe9e71846 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -726,7 +726,17 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column) column->identity = constraint->generated_when; saw_identity = true; + + /* An identity column is implicitly NOT NULL */ + if (saw_nullable && !column->is_not_null) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"", + column->colname, cxt->relation->relname), + parser_errposition(cxt->pstate, + constraint->location))); column->is_not_null = true; + saw_nullable = true; break; } diff --git a/src/test/regress/expected/identity.out b/src/test/regress/expected/identity.out index 98699348ebf..7a882f0b196 100644 --- a/src/test/regress/expected/identity.out +++ b/src/test/regress/expected/identity.out @@ -386,3 +386,16 @@ CREATE TABLE itest_child PARTITION OF itest_parent ( ) FOR VALUES FROM ('2016-07-01') TO ('2016-08-01'); -- error ERROR: identity columns are not supported on partitions DROP TABLE itest_parent; +-- Identity columns must be NOT NULL (cf bug #16913) +CREATE TABLE itest15 (id integer GENERATED ALWAYS AS IDENTITY NULL); -- fail +ERROR: conflicting NULL/NOT NULL declarations for column "id" of table "itest15" +LINE 1: ...ABLE itest15 (id integer GENERATED ALWAYS AS IDENTITY NULL); + ^ +CREATE TABLE itest15 (id integer NULL GENERATED ALWAYS AS IDENTITY); -- fail +ERROR: conflicting NULL/NOT NULL declarations for column "id" of table "itest15" +LINE 1: CREATE TABLE itest15 (id integer NULL GENERATED ALWAYS AS ID... + ^ +CREATE TABLE itest15 (id integer GENERATED ALWAYS AS IDENTITY NOT NULL); +DROP TABLE itest15; +CREATE TABLE itest15 (id integer NOT NULL GENERATED ALWAYS AS IDENTITY); +DROP TABLE itest15; diff --git a/src/test/regress/sql/identity.sql b/src/test/regress/sql/identity.sql index 3f6fb629a4a..1c81bb908c0 100644 --- a/src/test/regress/sql/identity.sql +++ b/src/test/regress/sql/identity.sql @@ -246,3 +246,12 @@ CREATE TABLE itest_child PARTITION OF itest_parent ( f3 WITH OPTIONS GENERATED ALWAYS AS IDENTITY ) FOR VALUES FROM ('2016-07-01') TO ('2016-08-01'); -- error DROP TABLE itest_parent; + +-- Identity columns must be NOT NULL (cf bug #16913) + +CREATE TABLE itest15 (id integer GENERATED ALWAYS AS IDENTITY NULL); -- fail +CREATE TABLE itest15 (id integer NULL GENERATED ALWAYS AS IDENTITY); -- fail +CREATE TABLE itest15 (id integer GENERATED ALWAYS AS IDENTITY NOT NULL); +DROP TABLE itest15; +CREATE TABLE itest15 (id integer NOT NULL GENERATED ALWAYS AS IDENTITY); +DROP TABLE itest15; |