Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitca7a0d1

Browse files
committed
Fix two issues with HEADER MATCH in COPY
072132f used the attnum offset to access the raw_fields array whenchecking that the attribute names of the header and of the relationmatch, leading to incorrect results or even crashes if the attributenumbers of a relation are changed, like on a dropped attribute. Thisfixes the logic to use the correct attribute names for the headermatching requirements.Also, this commit disallows HEADER MATCH in COPY TO as there is novalidation that can be done in this case.The tests are expanded for HEADER MATCH with COPY FROM and droppedcolumns, with cases where a relation has a dropped and re-added column,as well as a reduced set of columns.Author: Julien RouhaudReviewed-by: Peter Eisentraut, Michael PaquierDiscussion:https://postgr.es/m/20220607154744.vvmitnqhyxrne5ms@jrouhaud
1 parenteba331a commitca7a0d1

File tree

5 files changed

+97
-8
lines changed

5 files changed

+97
-8
lines changed

‎doc/src/sgml/ref/copy.sgml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,8 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable
282282
of the columns in the header line must match the actual column names of
283283
the table, otherwise an error is raised.
284284
This option is not allowed when using <literal>binary</literal> format.
285+
The <literal>MATCH</literal> option is only valid for <command>COPY
286+
FROM</command> commands.
285287
</para>
286288
</listitem>
287289
</varlistentry>

‎src/backend/commands/copy.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ DoCopy(ParseState *pstate, const CopyStmt *stmt,
318318
* defGetBoolean() but also accepts the special value "match".
319319
*/
320320
staticCopyHeaderChoice
321-
defGetCopyHeaderChoice(DefElem*def)
321+
defGetCopyHeaderChoice(DefElem*def,boolis_from)
322322
{
323323
/*
324324
* If no parameter given, assume "true" is meant.
@@ -360,7 +360,14 @@ defGetCopyHeaderChoice(DefElem *def)
360360
if (pg_strcasecmp(sval,"off")==0)
361361
returnCOPY_HEADER_FALSE;
362362
if (pg_strcasecmp(sval,"match")==0)
363+
{
364+
if (!is_from)
365+
ereport(ERROR,
366+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
367+
errmsg("cannot use \"%s\" with HEADER in COPY TO",
368+
sval)));
363369
returnCOPY_HEADER_MATCH;
370+
}
364371
}
365372
break;
366373
}
@@ -452,7 +459,7 @@ ProcessCopyOptions(ParseState *pstate,
452459
if (header_specified)
453460
errorConflictingDefElem(defel,pstate);
454461
header_specified= true;
455-
opts_out->header_line=defGetCopyHeaderChoice(defel);
462+
opts_out->header_line=defGetCopyHeaderChoice(defel,is_from);
456463
}
457464
elseif (strcmp(defel->defname,"quote")==0)
458465
{

‎src/backend/commands/copyfromparse.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -789,11 +789,12 @@ NextCopyFromRawFields(CopyFromState cstate, char ***fields, int *nfields)
789789
foreach(cur,cstate->attnumlist)
790790
{
791791
intattnum=lfirst_int(cur);
792-
char*colName=cstate->raw_fields[attnum-1];
792+
char*colName;
793793
Form_pg_attributeattr=TupleDescAttr(tupDesc,attnum-1);
794794

795-
fldnum++;
795+
Assert(fldnum<cstate->max_fields);
796796

797+
colName=cstate->raw_fields[fldnum++];
797798
if (colName==NULL)
798799
ereport(ERROR,
799800
(errcode(ERRCODE_BAD_COPY_FILE_FORMAT),

‎src/test/regress/expected/copy.out

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,21 @@ create table header_copytest (
182182
b int,
183183
c text
184184
);
185+
-- Make sure it works with with dropped columns
186+
alter table header_copytest drop column c;
187+
alter table header_copytest add column c text;
188+
copy header_copytest to stdout with (header match);
189+
ERROR: cannot use "match" with HEADER in COPY TO
185190
copy header_copytest from stdin with (header wrong_choice);
186191
ERROR: header requires a Boolean value or "match"
192+
-- works
187193
copy header_copytest from stdin with (header match);
194+
copy header_copytest (c, a, b) from stdin with (header match);
195+
copy header_copytest from stdin with (header match, format csv);
196+
-- errors
197+
copy header_copytest (c, b, a) from stdin with (header match);
198+
ERROR: column name mismatch in header line field 1: got "a", expected "c"
199+
CONTEXT: COPY header_copytest, line 1: "abc"
188200
copy header_copytest from stdin with (header match);
189201
ERROR: column name mismatch in header line field 3: got null value ("\N"), expected "c"
190202
CONTEXT: COPY header_copytest, line 1: "ab\N"
@@ -197,5 +209,34 @@ CONTEXT: COPY header_copytest, line 1: "abcd"
197209
copy header_copytest from stdin with (header match);
198210
ERROR: column name mismatch in header line field 3: got "d", expected "c"
199211
CONTEXT: COPY header_copytest, line 1: "abd"
200-
copy header_copytest from stdin with (header match, format csv);
212+
SELECT * FROM header_copytest ORDER BY a;
213+
a | b | c
214+
---+---+-----
215+
1 | 2 | foo
216+
3 | 4 | bar
217+
5 | 6 | baz
218+
(3 rows)
219+
220+
-- Drop an extra column, in the middle of the existing set.
221+
alter table header_copytest drop column b;
222+
-- works
223+
copy header_copytest (c, a) from stdin with (header match);
224+
copy header_copytest (a, c) from stdin with (header match);
225+
-- errors
226+
copy header_copytest from stdin with (header match);
227+
ERROR: wrong number of fields in header line: field count is 3, expected 2
228+
CONTEXT: COPY header_copytest, line 1: "a........pg.dropped.2........c"
229+
copy header_copytest (a, c) from stdin with (header match);
230+
ERROR: wrong number of fields in header line: field count is 3, expected 2
231+
CONTEXT: COPY header_copytest, line 1: "acb"
232+
SELECT * FROM header_copytest ORDER BY a;
233+
a | c
234+
---+-----
235+
1 | foo
236+
3 | bar
237+
5 | baz
238+
7 | foo
239+
8 | foo
240+
(5 rows)
241+
201242
drop table header_copytest;

‎src/test/regress/sql/copy.sql

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -204,11 +204,29 @@ create table header_copytest (
204204
bint,
205205
ctext
206206
);
207+
-- Make sure it works with with dropped columns
208+
altertable header_copytest drop column c;
209+
altertable header_copytest add column ctext;
210+
copy header_copytest to stdout with (header match);
207211
copy header_copytestfrom stdin with (header wrong_choice);
212+
-- works
208213
copy header_copytestfrom stdin with (header match);
209214
abc
210215
12foo
211216
\.
217+
copy header_copytest (c, a, b)from stdin with (header match);
218+
cab
219+
bar34
220+
\.
221+
copy header_copytestfrom stdin with (header match, format csv);
222+
a,b,c
223+
5,6,baz
224+
\.
225+
-- errors
226+
copy header_copytest (c, b, a)from stdin with (header match);
227+
abc
228+
12foo
229+
\.
212230
copy header_copytestfrom stdin with (header match);
213231
ab\N
214232
12foo
@@ -225,8 +243,28 @@ copy header_copytest from stdin with (header match);
225243
abd
226244
12foo
227245
\.
228-
copy header_copytestfrom stdin with (header match, format csv);
229-
a,b,c
230-
1,2,foo
246+
SELECT*FROM header_copytestORDER BY a;
247+
248+
-- Drop an extra column, in the middle of the existing set.
249+
altertable header_copytest drop column b;
250+
-- works
251+
copy header_copytest (c, a)from stdin with (header match);
252+
ca
253+
foo7
254+
\.
255+
copy header_copytest (a, c)from stdin with (header match);
256+
ac
257+
8foo
231258
\.
259+
-- errors
260+
copy header_copytestfrom stdin with (header match);
261+
a........pg.dropped.2........c
262+
12foo
263+
\.
264+
copy header_copytest (a, c)from stdin with (header match);
265+
acb
266+
1foo2
267+
\.
268+
269+
SELECT*FROM header_copytestORDER BY a;
232270
droptable header_copytest;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp