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
This commit is contained in:
parent
e2c8100e60
commit
4132dbec69
|
@ -1879,6 +1879,7 @@ ExecPartitionCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot,
|
|||
if (map != NULL)
|
||||
{
|
||||
tuple = do_convert_tuple(tuple, map);
|
||||
ExecSetSlotDescriptor(slot, tupdesc);
|
||||
ExecStoreTuple(tuple, slot, InvalidBuffer, false);
|
||||
}
|
||||
}
|
||||
|
@ -1956,6 +1957,7 @@ ExecConstraints(ResultRelInfo *resultRelInfo,
|
|||
if (map != NULL)
|
||||
{
|
||||
tuple = do_convert_tuple(tuple, map);
|
||||
ExecSetSlotDescriptor(slot, tupdesc);
|
||||
ExecStoreTuple(tuple, slot, InvalidBuffer, false);
|
||||
}
|
||||
}
|
||||
|
@ -2003,6 +2005,7 @@ ExecConstraints(ResultRelInfo *resultRelInfo,
|
|||
if (map != NULL)
|
||||
{
|
||||
tuple = do_convert_tuple(tuple, map);
|
||||
ExecSetSlotDescriptor(slot, tupdesc);
|
||||
ExecStoreTuple(tuple, slot, InvalidBuffer, false);
|
||||
}
|
||||
}
|
||||
|
@ -2112,6 +2115,7 @@ ExecWithCheckOptions(WCOKind kind, ResultRelInfo *resultRelInfo,
|
|||
if (map != NULL)
|
||||
{
|
||||
tuple = do_convert_tuple(tuple, map);
|
||||
ExecSetSlotDescriptor(slot, tupdesc);
|
||||
ExecStoreTuple(tuple, slot, InvalidBuffer, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -410,6 +410,21 @@ with ins (a, b, c) as
|
|||
mlparted4 | 1 | 30 | 39
|
||||
(5 rows)
|
||||
|
||||
alter table mlparted add c text;
|
||||
create table mlparted5 (c text, a int not null, b int not null) partition by list (c);
|
||||
create table mlparted5a (a int not null, c text, b int not null);
|
||||
alter table mlparted5 attach partition mlparted5a for values in ('a');
|
||||
alter table mlparted attach partition mlparted5 for values from (1, 40) to (1, 50);
|
||||
alter table mlparted add constraint check_b check (a = 1 and b < 45);
|
||||
insert into mlparted values (1, 45, 'a');
|
||||
ERROR: new row for relation "mlparted5a" violates check constraint "check_b"
|
||||
DETAIL: Failing row contains (1, 45, a).
|
||||
create function mlparted5abrtrig_func() returns trigger as $$ begin new.c = 'b'; return new; end; $$ language plpgsql;
|
||||
create trigger mlparted5abrtrig before insert on mlparted5a for each row execute procedure mlparted5abrtrig_func();
|
||||
insert into mlparted5 (a, b, c) values (1, 40, 'a');
|
||||
ERROR: new row for relation "mlparted5a" violates partition constraint
|
||||
DETAIL: Failing row contains (b, 1, 40).
|
||||
drop table mlparted5;
|
||||
-- check that message shown after failure to find a partition shows the
|
||||
-- appropriate key description (or none) in various situations
|
||||
create table key_desc (a int, b int) partition by list ((a+0));
|
||||
|
|
|
@ -2368,8 +2368,8 @@ DETAIL: Failing row contains (-1, invalid).
|
|||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
-- check that an auto-updatable view on a partitioned table works correctly
|
||||
create table pt (a int, b int) partition by range (a, b);
|
||||
create table pt1 (b int not null, a int not null) partition by range (b);
|
||||
create table pt (a int, b int, v varchar) partition by range (a, b);
|
||||
create table pt1 (b int not null, v varchar, a int not null) partition by range (b);
|
||||
create table pt11 (like pt1);
|
||||
alter table pt11 drop a;
|
||||
alter table pt11 add a int;
|
||||
|
@ -2412,18 +2412,19 @@ select table_name, column_name, is_updatable
|
|||
------------+-------------+--------------
|
||||
ptv | a | YES
|
||||
ptv | b | YES
|
||||
(2 rows)
|
||||
ptv | v | YES
|
||||
(3 rows)
|
||||
|
||||
insert into ptv values (1, 2);
|
||||
select tableoid::regclass, * from pt;
|
||||
tableoid | a | b
|
||||
----------+---+---
|
||||
pt11 | 1 | 2
|
||||
tableoid | a | b | v
|
||||
----------+---+---+---
|
||||
pt11 | 1 | 2 |
|
||||
(1 row)
|
||||
|
||||
create view ptv_wco as select * from pt where a = 0 with check option;
|
||||
insert into ptv_wco values (1, 2);
|
||||
ERROR: new row violates check option for view "ptv_wco"
|
||||
DETAIL: Failing row contains (1, 2).
|
||||
DETAIL: Failing row contains (1, 2, null).
|
||||
drop view ptv, ptv_wco;
|
||||
drop table pt, pt1, pt11;
|
||||
|
|
|
@ -263,6 +263,18 @@ with ins (a, b, c) as
|
|||
(insert into mlparted (b, a) select s.a, 1 from generate_series(2, 39) s(a) returning tableoid::regclass, *)
|
||||
select a, b, min(c), max(c) from ins group by a, b order by 1;
|
||||
|
||||
alter table mlparted add c text;
|
||||
create table mlparted5 (c text, a int not null, b int not null) partition by list (c);
|
||||
create table mlparted5a (a int not null, c text, b int not null);
|
||||
alter table mlparted5 attach partition mlparted5a for values in ('a');
|
||||
alter table mlparted attach partition mlparted5 for values from (1, 40) to (1, 50);
|
||||
alter table mlparted add constraint check_b check (a = 1 and b < 45);
|
||||
insert into mlparted values (1, 45, 'a');
|
||||
create function mlparted5abrtrig_func() returns trigger as $$ begin new.c = 'b'; return new; end; $$ language plpgsql;
|
||||
create trigger mlparted5abrtrig before insert on mlparted5a for each row execute procedure mlparted5abrtrig_func();
|
||||
insert into mlparted5 (a, b, c) values (1, 40, 'a');
|
||||
drop table mlparted5;
|
||||
|
||||
-- check that message shown after failure to find a partition shows the
|
||||
-- appropriate key description (or none) in various situations
|
||||
create table key_desc (a int, b int) partition by list ((a+0));
|
||||
|
|
|
@ -1114,8 +1114,8 @@ DROP VIEW v1;
|
|||
DROP TABLE t1;
|
||||
|
||||
-- check that an auto-updatable view on a partitioned table works correctly
|
||||
create table pt (a int, b int) partition by range (a, b);
|
||||
create table pt1 (b int not null, a int not null) partition by range (b);
|
||||
create table pt (a int, b int, v varchar) partition by range (a, b);
|
||||
create table pt1 (b int not null, v varchar, a int not null) partition by range (b);
|
||||
create table pt11 (like pt1);
|
||||
alter table pt11 drop a;
|
||||
alter table pt11 add a int;
|
||||
|
|
Loading…
Reference in New Issue