Skip to content

Commit 4132dbe

Browse files
committed
Fix partitioning crashes during error reporting.
In various places where we reverse-map a tuple before calling ExecBuildSlotValueDescription, we neglected to ensure that the slot descriptor matched the tuple stored in it. Amit Langote and Amit Khandekar, reviewed by Etsuro Fujita Discussion: http://postgr.es/m/CAJ3gD9cqpP=WvJj=dv1ONkPWjy8ZuUaOM4_x86i3uQPas=0_jg@mail.gmail.com
1 parent e2c8100 commit 4132dbe

File tree

5 files changed

+41
-9
lines changed

5 files changed

+41
-9
lines changed

src/backend/executor/execMain.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1879,6 +1879,7 @@ ExecPartitionCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot,
18791879
if (map != NULL)
18801880
{
18811881
tuple = do_convert_tuple(tuple, map);
1882+
ExecSetSlotDescriptor(slot, tupdesc);
18821883
ExecStoreTuple(tuple, slot, InvalidBuffer, false);
18831884
}
18841885
}
@@ -1956,6 +1957,7 @@ ExecConstraints(ResultRelInfo *resultRelInfo,
19561957
if (map != NULL)
19571958
{
19581959
tuple = do_convert_tuple(tuple, map);
1960+
ExecSetSlotDescriptor(slot, tupdesc);
19591961
ExecStoreTuple(tuple, slot, InvalidBuffer, false);
19601962
}
19611963
}
@@ -2003,6 +2005,7 @@ ExecConstraints(ResultRelInfo *resultRelInfo,
20032005
if (map != NULL)
20042006
{
20052007
tuple = do_convert_tuple(tuple, map);
2008+
ExecSetSlotDescriptor(slot, tupdesc);
20062009
ExecStoreTuple(tuple, slot, InvalidBuffer, false);
20072010
}
20082011
}
@@ -2112,6 +2115,7 @@ ExecWithCheckOptions(WCOKind kind, ResultRelInfo *resultRelInfo,
21122115
if (map != NULL)
21132116
{
21142117
tuple = do_convert_tuple(tuple, map);
2118+
ExecSetSlotDescriptor(slot, tupdesc);
21152119
ExecStoreTuple(tuple, slot, InvalidBuffer, false);
21162120
}
21172121
}

src/test/regress/expected/insert.out

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,21 @@ with ins (a, b, c) as
410410
mlparted4 | 1 | 30 | 39
411411
(5 rows)
412412

413+
alter table mlparted add c text;
414+
create table mlparted5 (c text, a int not null, b int not null) partition by list (c);
415+
create table mlparted5a (a int not null, c text, b int not null);
416+
alter table mlparted5 attach partition mlparted5a for values in ('a');
417+
alter table mlparted attach partition mlparted5 for values from (1, 40) to (1, 50);
418+
alter table mlparted add constraint check_b check (a = 1 and b < 45);
419+
insert into mlparted values (1, 45, 'a');
420+
ERROR: new row for relation "mlparted5a" violates check constraint "check_b"
421+
DETAIL: Failing row contains (1, 45, a).
422+
create function mlparted5abrtrig_func() returns trigger as $$ begin new.c = 'b'; return new; end; $$ language plpgsql;
423+
create trigger mlparted5abrtrig before insert on mlparted5a for each row execute procedure mlparted5abrtrig_func();
424+
insert into mlparted5 (a, b, c) values (1, 40, 'a');
425+
ERROR: new row for relation "mlparted5a" violates partition constraint
426+
DETAIL: Failing row contains (b, 1, 40).
427+
drop table mlparted5;
413428
-- check that message shown after failure to find a partition shows the
414429
-- appropriate key description (or none) in various situations
415430
create table key_desc (a int, b int) partition by list ((a+0));

src/test/regress/expected/updatable_views.out

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2368,8 +2368,8 @@ DETAIL: Failing row contains (-1, invalid).
23682368
DROP VIEW v1;
23692369
DROP TABLE t1;
23702370
-- check that an auto-updatable view on a partitioned table works correctly
2371-
create table pt (a int, b int) partition by range (a, b);
2372-
create table pt1 (b int not null, a int not null) partition by range (b);
2371+
create table pt (a int, b int, v varchar) partition by range (a, b);
2372+
create table pt1 (b int not null, v varchar, a int not null) partition by range (b);
23732373
create table pt11 (like pt1);
23742374
alter table pt11 drop a;
23752375
alter table pt11 add a int;
@@ -2412,18 +2412,19 @@ select table_name, column_name, is_updatable
24122412
------------+-------------+--------------
24132413
ptv | a | YES
24142414
ptv | b | YES
2415-
(2 rows)
2415+
ptv | v | YES
2416+
(3 rows)
24162417

24172418
insert into ptv values (1, 2);
24182419
select tableoid::regclass, * from pt;
2419-
tableoid | a | b
2420-
----------+---+---
2421-
pt11 | 1 | 2
2420+
tableoid | a | b | v
2421+
----------+---+---+---
2422+
pt11 | 1 | 2 |
24222423
(1 row)
24232424

24242425
create view ptv_wco as select * from pt where a = 0 with check option;
24252426
insert into ptv_wco values (1, 2);
24262427
ERROR: new row violates check option for view "ptv_wco"
2427-
DETAIL: Failing row contains (1, 2).
2428+
DETAIL: Failing row contains (1, 2, null).
24282429
drop view ptv, ptv_wco;
24292430
drop table pt, pt1, pt11;

src/test/regress/sql/insert.sql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,18 @@ with ins (a, b, c) as
263263
(insert into mlparted (b, a) select s.a, 1 from generate_series(2, 39) s(a) returning tableoid::regclass, *)
264264
select a, b, min(c), max(c) from ins group by a, b order by 1;
265265

266+
alter table mlparted add c text;
267+
create table mlparted5 (c text, a int not null, b int not null) partition by list (c);
268+
create table mlparted5a (a int not null, c text, b int not null);
269+
alter table mlparted5 attach partition mlparted5a for values in ('a');
270+
alter table mlparted attach partition mlparted5 for values from (1, 40) to (1, 50);
271+
alter table mlparted add constraint check_b check (a = 1 and b < 45);
272+
insert into mlparted values (1, 45, 'a');
273+
create function mlparted5abrtrig_func() returns trigger as $$ begin new.c = 'b'; return new; end; $$ language plpgsql;
274+
create trigger mlparted5abrtrig before insert on mlparted5a for each row execute procedure mlparted5abrtrig_func();
275+
insert into mlparted5 (a, b, c) values (1, 40, 'a');
276+
drop table mlparted5;
277+
266278
-- check that message shown after failure to find a partition shows the
267279
-- appropriate key description (or none) in various situations
268280
create table key_desc (a int, b int) partition by list ((a+0));

src/test/regress/sql/updatable_views.sql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,8 +1114,8 @@ DROP VIEW v1;
11141114
DROP TABLE t1;
11151115

11161116
-- check that an auto-updatable view on a partitioned table works correctly
1117-
create table pt (a int, b int) partition by range (a, b);
1118-
create table pt1 (b int not null, a int not null) partition by range (b);
1117+
create table pt (a int, b int, v varchar) partition by range (a, b);
1118+
create table pt1 (b int not null, v varchar, a int not null) partition by range (b);
11191119
create table pt11 (like pt1);
11201120
alter table pt11 drop a;
11211121
alter table pt11 add a int;

0 commit comments

Comments
 (0)