summaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorMichael Paquier2022-06-23 01:49:20 +0000
committerMichael Paquier2022-06-23 01:49:20 +0000
commitca7a0d1d368216e89359c63531a4df0b99a437e4 (patch)
treef662791ab4a78f5dff1969e7b532f48442c7faf7 /src/backend
parenteba331ae2aad781d498f8a424a12185146c7f1f7 (diff)
Fix two issues with HEADER MATCH in COPY
072132f0 used the attnum offset to access the raw_fields array when checking that the attribute names of the header and of the relation match, leading to incorrect results or even crashes if the attribute numbers of a relation are changed, like on a dropped attribute. This fixes the logic to use the correct attribute names for the header matching requirements. Also, this commit disallows HEADER MATCH in COPY TO as there is no validation that can be done in this case. The tests are expanded for HEADER MATCH with COPY FROM and dropped columns, with cases where a relation has a dropped and re-added column, as well as a reduced set of columns. Author: Julien Rouhaud Reviewed-by: Peter Eisentraut, Michael Paquier Discussion: https://postgr.es/m/20220607154744.vvmitnqhyxrne5ms@jrouhaud
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/commands/copy.c11
-rw-r--r--src/backend/commands/copyfromparse.c5
2 files changed, 12 insertions, 4 deletions
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index f448d39c7ed..e2870e3c11c 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -318,7 +318,7 @@ DoCopy(ParseState *pstate, const CopyStmt *stmt,
* defGetBoolean() but also accepts the special value "match".
*/
static CopyHeaderChoice
-defGetCopyHeaderChoice(DefElem *def)
+defGetCopyHeaderChoice(DefElem *def, bool is_from)
{
/*
* If no parameter given, assume "true" is meant.
@@ -360,7 +360,14 @@ defGetCopyHeaderChoice(DefElem *def)
if (pg_strcasecmp(sval, "off") == 0)
return COPY_HEADER_FALSE;
if (pg_strcasecmp(sval, "match") == 0)
+ {
+ if (!is_from)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot use \"%s\" with HEADER in COPY TO",
+ sval)));
return COPY_HEADER_MATCH;
+ }
}
break;
}
@@ -452,7 +459,7 @@ ProcessCopyOptions(ParseState *pstate,
if (header_specified)
errorConflictingDefElem(defel, pstate);
header_specified = true;
- opts_out->header_line = defGetCopyHeaderChoice(defel);
+ opts_out->header_line = defGetCopyHeaderChoice(defel, is_from);
}
else if (strcmp(defel->defname, "quote") == 0)
{
diff --git a/src/backend/commands/copyfromparse.c b/src/backend/commands/copyfromparse.c
index e06534943f7..57813b3458b 100644
--- a/src/backend/commands/copyfromparse.c
+++ b/src/backend/commands/copyfromparse.c
@@ -789,11 +789,12 @@ NextCopyFromRawFields(CopyFromState cstate, char ***fields, int *nfields)
foreach(cur, cstate->attnumlist)
{
int attnum = lfirst_int(cur);
- char *colName = cstate->raw_fields[attnum - 1];
+ char *colName;
Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
- fldnum++;
+ Assert(fldnum < cstate->max_fields);
+ colName = cstate->raw_fields[fldnum++];
if (colName == NULL)
ereport(ERROR,
(errcode(ERRCODE_BAD_COPY_FILE_FORMAT),