]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Forbid marking an identity column as nullable.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 12 Mar 2021 16:08:42 +0000 (11:08 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 12 Mar 2021 16:08:42 +0000 (11:08 -0500)
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

doc/src/sgml/ref/create_table.sgml
src/backend/parser/parse_utilcmd.c
src/test/regress/expected/identity.out
src/test/regress/sql/identity.sql

index b77cc32051256607fd1dc226ed4353b5d84f2898..082d0f259f62b1a6ad2506aaa2a0b10c17fd98b8 100644 (file)
@@ -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>
index 9b4874dc11d86f11fe7c2cf0dc15208e7d24b721..76fe9e71846b4e8b39f23215c23a99dbe99da3d3 100644 (file)
@@ -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;
                                }
 
index 98699348ebf423eca545f3315b735b4be6571672..7a882f0b1966e500fcc5d64d9bd3c56ea1e26b46 100644 (file)
@@ -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;
index 3f6fb629a4a16a4c7daef1fa43190080587c54f3..1c81bb908c07d26ef576fca913ff800c8c2924aa 100644 (file)
@@ -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;