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
This commit is contained in:
Andrew Dunstan 2023-10-01 10:18:41 -04:00
parent b1a8dc846d
commit 276393f53e
3 changed files with 40 additions and 1 deletions

View File

@ -1571,7 +1571,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);

View File

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

View File

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