postgres.git / summary / log / commit / refs

commit    910eb61b2bbdb729c242ed20d5f6e0a392eb62da
Author:   Andrew Dunstan <andrew@dunslane.net>
Date:     Sun Oct 01 14:18:41 2023 +0000
First released in: 17.0, 16.1

    Only evaluate default values as required when doing COPY FROM
    
    Commit 9f8377f7a2 was a little too eager in fetching default values.
    Normally this would not matter, but if the default value is not valid
    for the type (e.g. a varchar that's too long) it caused an unnecessary
    error.
    
    Complaint and fix from Laurenz Albe
    
    Backpatch to release 16.
    
    Discussion: https://postgr.es/m/75a7b7483aeb331aa017328d606d568fc715b90d.camel@cybertec.at


src/backend/commands/copyfrom.c | 9 ++++++++- src/test/regress/expected/copy.out | 17 +++++++++++++++++ src/test/regress/sql/copy.sql | 15 +++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/backend/commands/copyfrom.c b/src/backend/commands/copyfrom.c index b47cb5c66da..65b3e56cd49 100644 --- a/src/backend/commands/copyfrom.c +++ b/src/backend/commands/copyfrom.c @@ -1569,7 +1569,14 @@ BeginCopyFrom(ParseState *pstate, /* Get default info if available */ defexprs[attnum - 1] = NULL; - if (!att->attgenerated) + /* + * We only need the default values for columns that do not appear in + * the column list, unless the DEFAULT option was given. We never need + * default values for generated columns. + */ + if ((cstate->opts.default_print != NULL || + !list_member_int(cstate->attnumlist, attnum)) && + !att->attgenerated) { Expr *defexpr = (Expr *) build_column_default(cstate->rel, attnum); diff --git a/src/test/regress/expected/copy.out b/src/test/regress/expected/copy.out index 8a8bf43fdea..a5912c13a8c 100644 --- a/src/test/regress/expected/copy.out +++ b/src/test/regress/expected/copy.out @@ -240,3 +240,20 @@ SELECT * FROM header_copytest ORDER BY a; (5 rows) drop table header_copytest; +-- test COPY with overlong column defaults +create temp table oversized_column_default ( + col1 varchar(5) DEFAULT 'more than 5 chars', + col2 varchar(5)); +-- normal COPY should work +copy oversized_column_default from stdin; +-- error if the column is excluded +copy oversized_column_default (col2) from stdin; +ERROR: value too long for type character varying(5) +\. +invalid command \. +-- error if the DEFAULT option is given +copy oversized_column_default from stdin (default ''); +ERROR: value too long for type character varying(5) +\. +invalid command \. +drop table oversized_column_default; diff --git a/src/test/regress/sql/copy.sql b/src/test/regress/sql/copy.sql index f9da7b1508f..7fdb26d14f3 100644 --- a/src/test/regress/sql/copy.sql +++ b/src/test/regress/sql/copy.sql @@ -268,3 +268,18 @@ a c b SELECT * FROM header_copytest ORDER BY a; drop table header_copytest; + +-- test COPY with overlong column defaults +create temp table oversized_column_default ( + col1 varchar(5) DEFAULT 'more than 5 chars', + col2 varchar(5)); +-- normal COPY should work +copy oversized_column_default from stdin; +\. +-- error if the column is excluded +copy oversized_column_default (col2) from stdin; +\. +-- error if the DEFAULT option is given +copy oversized_column_default from stdin (default ''); +\. +drop table oversized_column_default; [parent: d5c5312dc8b6]