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

Commit08361ce

Browse files
committed
Fix null-pointer-deref crash while doing COPY IN with check constraints.
In commitbf7ca15 I introduced anassumption that an RTE referenced by a whole-row Var must have a valid ereffield. This is false for RTEs constructed by DoCopy, and there are otherplaces taking similar shortcuts. Perhaps we should make all those placesgo through addRangeTableEntryForRelation or its siblings instead of havingad-hoc logic, but the most reliable fix seems to be to make the new code inExecEvalWholeRowVar cope if there's no eref. We can reasonably assume thatthere's no need to insert column aliases if no aliases were provided.Add a regression test case covering this, and also verifying that a sanecolumn name is in fact available in this situation.Although the known case only crashes in 9.4 and HEAD, it seems prudent toback-patch the code change to 9.2, since all the ingredients for a similarfailure exist in the variant patch applied to 9.3 and 9.2.Per report from Jean-Pierre Pelletier.
1 parentc5b31e2 commit08361ce

File tree

3 files changed

+58
-2
lines changed

3 files changed

+58
-2
lines changed

‎src/backend/executor/execQual.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -900,15 +900,18 @@ ExecEvalWholeRowVar(WholeRowVarExprState *wrvstate, ExprContext *econtext,
900900
* If we can't locate the RTE, assume the column names we've got are OK.
901901
* (As of this writing, the only cases where we can't locate the RTE are
902902
* in execution of trigger WHEN clauses, and then the Var will have the
903-
* trigger's relation's rowtype, so its names are fine.)
903+
* trigger's relation's rowtype, so its names are fine.) Also, if the
904+
* creator of the RTE didn't bother to fill in an eref field, assume our
905+
* column names are OK. (This happens in COPY, and perhaps other places.)
904906
*/
905907
if (econtext->ecxt_estate&&
906908
variable->varno <=list_length(econtext->ecxt_estate->es_range_table))
907909
{
908910
RangeTblEntry*rte=rt_fetch(variable->varno,
909911
econtext->ecxt_estate->es_range_table);
910912

911-
ExecTypeSetColNames(output_tupdesc,rte->eref->colnames);
913+
if (rte->eref)
914+
ExecTypeSetColNames(output_tupdesc,rte->eref->colnames);
912915
}
913916

914917
/* Bless the tupdesc if needed, and save it in the execution state */

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,40 @@ COPY forcetest (d, e) FROM STDIN WITH (FORMAT csv, FORCE_NULL(b));
429429
ERROR: FORCE NULL column "b" not referenced by COPY
430430
ROLLBACK;
431431
\pset null ''
432+
-- test case with whole-row Var in a check constraint
433+
create table check_con_tbl (f1 int);
434+
create function check_con_function(check_con_tbl) returns bool as $$
435+
begin
436+
raise notice 'input = %', row_to_json($1);
437+
return $1.f1 > 0;
438+
end $$ language plpgsql immutable;
439+
alter table check_con_tbl add check (check_con_function(check_con_tbl.*));
440+
\d+ check_con_tbl
441+
Table "public.check_con_tbl"
442+
Column | Type | Modifiers | Storage | Stats target | Description
443+
--------+---------+-----------+---------+--------------+-------------
444+
f1 | integer | | plain | |
445+
Check constraints:
446+
"check_con_tbl_check" CHECK (check_con_function(check_con_tbl.*))
447+
448+
copy check_con_tbl from stdin;
449+
NOTICE: input = {"f1":1}
450+
CONTEXT: COPY check_con_tbl, line 1: "1"
451+
NOTICE: input = {"f1":null}
452+
CONTEXT: COPY check_con_tbl, line 2: "\N"
453+
copy check_con_tbl from stdin;
454+
NOTICE: input = {"f1":0}
455+
CONTEXT: COPY check_con_tbl, line 1: "0"
456+
ERROR: new row for relation "check_con_tbl" violates check constraint "check_con_tbl_check"
457+
DETAIL: Failing row contains (0).
458+
CONTEXT: COPY check_con_tbl, line 1: "0"
459+
select * from check_con_tbl;
460+
f1
461+
----
462+
1
463+
464+
(2 rows)
465+
432466
DROP TABLE forcetest;
433467
DROP TABLE vistest;
434468
DROP FUNCTION truncate_in_subxact();

‎src/test/regress/sql/copy2.sql

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,25 @@ BEGIN;
308308
COPY forcetest (d, e)FROM STDIN WITH (FORMAT csv, FORCE_NULL(b));
309309
ROLLBACK;
310310
\psetnull''
311+
312+
-- test case with whole-row Var in a check constraint
313+
createtablecheck_con_tbl (f1int);
314+
createfunctioncheck_con_function(check_con_tbl) returns boolas $$
315+
begin
316+
raise notice'input = %', row_to_json($1);
317+
return $1.f1>0;
318+
end $$ language plpgsql immutable;
319+
altertable check_con_tbl addcheck (check_con_function(check_con_tbl.*));
320+
\d+ check_con_tbl
321+
copy check_con_tblfrom stdin;
322+
1
323+
\N
324+
\.
325+
copy check_con_tblfrom stdin;
326+
0
327+
\.
328+
select*from check_con_tbl;
329+
311330
DROPTABLE forcetest;
312331
DROPTABLE vistest;
313332
DROPFUNCTION truncate_in_subxact();

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp