From 2d2d06b7e27e3177d5bef0061801c75946871db3 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Fri, 8 Dec 2017 09:18:18 -0500 Subject: [PATCH] Apply identity sequence values on COPY A COPY into a table should apply identity sequence values just like it does for ordinary defaults. This was previously forgotten, leading to null values being inserted, which in turn would fail because identity columns have not-null constraints. Author: Michael Paquier Reported-by: Steven Winfield Bug: #14952 --- src/backend/commands/copy.c | 16 ++++++++++++++-- src/test/regress/expected/identity.out | 13 +++++++++++++ src/test/regress/sql/identity.sql | 17 +++++++++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index bace390470..254be28ae4 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -23,6 +23,7 @@ #include "access/sysattr.h" #include "access/xact.h" #include "access/xlog.h" +#include "catalog/dependency.h" #include "catalog/pg_type.h" #include "commands/copy.h" #include "commands/defrem.h" @@ -3067,8 +3068,19 @@ BeginCopyFrom(ParseState *pstate, { /* attribute is NOT to be copied from input */ /* use default value if one exists */ - Expr *defexpr = (Expr *) build_column_default(cstate->rel, - attnum); + Expr *defexpr; + + if (att->attidentity) + { + NextValueExpr *nve = makeNode(NextValueExpr); + + nve->seqid = getOwnedSequence(RelationGetRelid(cstate->rel), + attnum); + nve->typeId = att->atttypid; + defexpr = (Expr *) nve; + } + else + defexpr = (Expr *) build_column_default(cstate->rel, attnum); if (defexpr != NULL) { diff --git a/src/test/regress/expected/identity.out b/src/test/regress/expected/identity.out index 5fa585d6cc..174b420a04 100644 --- a/src/test/regress/expected/identity.out +++ b/src/test/regress/expected/identity.out @@ -153,6 +153,19 @@ SELECT * FROM itest2; 3 | (3 rows) +-- COPY tests +CREATE TABLE itest9 (a int GENERATED ALWAYS AS IDENTITY, b text, c bigint); +COPY itest9 FROM stdin; +COPY itest9 (b, c) FROM stdin; +SELECT * FROM itest9 ORDER BY c; + a | b | c +-----+------+----- + 100 | foo | 200 + 101 | bar | 201 + 1 | foo2 | 202 + 2 | bar2 | 203 +(4 rows) + -- DROP IDENTITY tests ALTER TABLE itest4 ALTER COLUMN a DROP IDENTITY; ALTER TABLE itest4 ALTER COLUMN a DROP IDENTITY; -- error diff --git a/src/test/regress/sql/identity.sql b/src/test/regress/sql/identity.sql index e1b5a074c9..6e76dd08c8 100644 --- a/src/test/regress/sql/identity.sql +++ b/src/test/regress/sql/identity.sql @@ -78,6 +78,23 @@ UPDATE itest2 SET a = DEFAULT WHERE a = 2; SELECT * FROM itest2; +-- COPY tests + +CREATE TABLE itest9 (a int GENERATED ALWAYS AS IDENTITY, b text, c bigint); + +COPY itest9 FROM stdin; +100 foo 200 +101 bar 201 +\. + +COPY itest9 (b, c) FROM stdin; +foo2 202 +bar2 203 +\. + +SELECT * FROM itest9 ORDER BY c; + + -- DROP IDENTITY tests ALTER TABLE itest4 ALTER COLUMN a DROP IDENTITY;