mirror of
https://github.com/postgres/postgres.git
synced 2026-10-23 13:29:09 +03:00
Fix failure of setrefs.c to process child_append_relid_sets
Commit 7358abcc60 taught the planner to
store information about Append node consolidation in the final plan,
but it forgot that child_append_relid_sets needs to be adjusted
at setrefs.c time just like every other place where we store RTIs
in a plan tree. Fix that.
Although this can cause incorrect plan advice to be emitted in cases
involving multi-level partitioning, it seems more appropriate to put
the test case for it in pg_overexplain, so this commit does that.
Backpatch-through: 19
Discussion: http://postgr.es/m/CA+TgmoYYHC4i-Gpzc9-JYHqih6pOK+6LTYFiNR-PioXG1nKkOQ@mail.gmail.com
This commit is contained in:
@@ -60,6 +60,24 @@ INSERT INTO vegetables (name, genus)
|
||||
('cabbage', 'brassica'), ('kohlrabi', 'brassica'),
|
||||
('rutabaga', 'brassica'), ('turnip', 'brassica');
|
||||
VACUUM ANALYZE vegetables;
|
||||
-- Create a multi-level partitioned table.
|
||||
CREATE TABLE creatures (id serial, name text, class text, clade text)
|
||||
PARTITION BY LIST (class);
|
||||
CREATE TABLE mammalia PARTITION OF creatures FOR VALUES IN ('mammalia')
|
||||
PARTITION BY LIST (clade);
|
||||
CREATE TABLE carnivora PARTITION OF mammalia FOR VALUES IN ('carnivora');
|
||||
CREATE TABLE rodentia PARTITION OF mammalia FOR VALUES IN ('rodentia');
|
||||
CREATE TABLE aves PARTITION OF creatures FOR VALUES IN ('aves');
|
||||
INSERT INTO creatures (name, class, clade)
|
||||
VALUES ('fossa', 'mammalia', 'carnivora'),
|
||||
('meerkat', 'mammalia', 'carnivora'),
|
||||
('binturong', 'mammalia', 'carnivora'),
|
||||
('capybara', 'mammalia', 'rodentia'),
|
||||
('chinchilla', 'mammalia', 'rodentia'),
|
||||
('agouti', 'mammalia', 'rodentia'),
|
||||
('kakapo', 'aves', NULL),
|
||||
('hoatzin', 'aves', NULL);
|
||||
VACUUM ANALYZE creatures;
|
||||
-- We filter relation OIDs out of the test output in order to avoid
|
||||
-- test instability. This is currently only needed for EXPLAIN (DEBUG), not
|
||||
-- EXPLAIN (RANGE_TABLE). Also suppress actual row counts, which are not
|
||||
@@ -766,3 +784,60 @@ SELECT * FROM vegetables v,
|
||||
Unprunable RTIs: 1 3 4 5 6
|
||||
(51 rows)
|
||||
|
||||
-- test display of child append RTIs
|
||||
EXPLAIN (RANGE_TABLE, COSTS OFF)
|
||||
SELECT * FROM (SELECT * FROM creatures OFFSET 0) ss;
|
||||
QUERY PLAN
|
||||
----------------------------------------------
|
||||
Append
|
||||
Append RTIs: 2
|
||||
Child Append RTIs: 4
|
||||
Elided Node Type: SubqueryScan
|
||||
Elided Node RTIs: 1
|
||||
-> Seq Scan on aves creatures_1
|
||||
Scan RTI: 3
|
||||
-> Seq Scan on carnivora creatures_2
|
||||
Scan RTI: 5
|
||||
-> Seq Scan on rodentia creatures_3
|
||||
Scan RTI: 6
|
||||
RTI 1 (subquery, in-from-clause):
|
||||
Alias: ss ()
|
||||
Eref: ss (id, name, class, clade)
|
||||
RTI 2 (relation, inherited, in-from-clause):
|
||||
Subplan: ss
|
||||
Eref: creatures (id, name, class, clade)
|
||||
Relation: creatures
|
||||
Relation Kind: partitioned_table
|
||||
Relation Lock Mode: AccessShareLock
|
||||
Permission Info Index: 1
|
||||
RTI 3 (relation, in-from-clause):
|
||||
Subplan: ss
|
||||
Alias: creatures (id, name, class, clade)
|
||||
Eref: creatures (id, name, class, clade)
|
||||
Relation: aves
|
||||
Relation Kind: relation
|
||||
Relation Lock Mode: AccessShareLock
|
||||
RTI 4 (relation, inherited, in-from-clause):
|
||||
Subplan: ss
|
||||
Alias: creatures (id, name, class, clade)
|
||||
Eref: creatures (id, name, class, clade)
|
||||
Relation: mammalia
|
||||
Relation Kind: partitioned_table
|
||||
Relation Lock Mode: AccessShareLock
|
||||
RTI 5 (relation, in-from-clause):
|
||||
Subplan: ss
|
||||
Alias: creatures (id, name, class, clade)
|
||||
Eref: creatures (id, name, class, clade)
|
||||
Relation: carnivora
|
||||
Relation Kind: relation
|
||||
Relation Lock Mode: AccessShareLock
|
||||
RTI 6 (relation, in-from-clause):
|
||||
Subplan: ss
|
||||
Alias: creatures (id, name, class, clade)
|
||||
Eref: creatures (id, name, class, clade)
|
||||
Relation: rodentia
|
||||
Relation Kind: relation
|
||||
Relation Lock Mode: AccessShareLock
|
||||
Unprunable RTIs: 2 3 4 5 6
|
||||
(50 rows)
|
||||
|
||||
|
||||
@@ -31,6 +31,25 @@ INSERT INTO vegetables (name, genus)
|
||||
('rutabaga', 'brassica'), ('turnip', 'brassica');
|
||||
VACUUM ANALYZE vegetables;
|
||||
|
||||
-- Create a multi-level partitioned table.
|
||||
CREATE TABLE creatures (id serial, name text, class text, clade text)
|
||||
PARTITION BY LIST (class);
|
||||
CREATE TABLE mammalia PARTITION OF creatures FOR VALUES IN ('mammalia')
|
||||
PARTITION BY LIST (clade);
|
||||
CREATE TABLE carnivora PARTITION OF mammalia FOR VALUES IN ('carnivora');
|
||||
CREATE TABLE rodentia PARTITION OF mammalia FOR VALUES IN ('rodentia');
|
||||
CREATE TABLE aves PARTITION OF creatures FOR VALUES IN ('aves');
|
||||
INSERT INTO creatures (name, class, clade)
|
||||
VALUES ('fossa', 'mammalia', 'carnivora'),
|
||||
('meerkat', 'mammalia', 'carnivora'),
|
||||
('binturong', 'mammalia', 'carnivora'),
|
||||
('capybara', 'mammalia', 'rodentia'),
|
||||
('chinchilla', 'mammalia', 'rodentia'),
|
||||
('agouti', 'mammalia', 'rodentia'),
|
||||
('kakapo', 'aves', NULL),
|
||||
('hoatzin', 'aves', NULL);
|
||||
VACUUM ANALYZE creatures;
|
||||
|
||||
-- We filter relation OIDs out of the test output in order to avoid
|
||||
-- test instability. This is currently only needed for EXPLAIN (DEBUG), not
|
||||
-- EXPLAIN (RANGE_TABLE). Also suppress actual row counts, which are not
|
||||
@@ -136,3 +155,7 @@ SELECT * FROM vegetables v,
|
||||
EXPLAIN (RANGE_TABLE, COSTS OFF)
|
||||
SELECT * FROM vegetables v,
|
||||
(SELECT * FROM vegetables WHERE genus = 'daucus' OFFSET 0);
|
||||
|
||||
-- test display of child append RTIs
|
||||
EXPLAIN (RANGE_TABLE, COSTS OFF)
|
||||
SELECT * FROM (SELECT * FROM creatures OFFSET 0) ss;
|
||||
|
||||
@@ -155,6 +155,7 @@ static Plan *set_mergeappend_references(PlannerInfo *root,
|
||||
int rtoffset);
|
||||
static void set_hash_references(PlannerInfo *root, Plan *plan, int rtoffset);
|
||||
static Relids offset_relid_set(Relids relids, int rtoffset);
|
||||
static List *offset_relid_set_list(List *relid_sets, int rtoffset);
|
||||
static Node *fix_dummy_setop_vars_mutator(Node *node, int *first_child_relid);
|
||||
static Node *fix_scan_expr(PlannerInfo *root, Node *node,
|
||||
int rtoffset, double num_exec);
|
||||
@@ -1913,6 +1914,8 @@ set_append_references(PlannerInfo *root,
|
||||
set_dummy_tlist_references((Plan *) aplan, rtoffset);
|
||||
|
||||
aplan->apprelids = offset_relid_set(aplan->apprelids, rtoffset);
|
||||
aplan->child_append_relid_sets =
|
||||
offset_relid_set_list(aplan->child_append_relid_sets, rtoffset);
|
||||
|
||||
/*
|
||||
* Add PartitionPruneInfo, if any, to PlannerGlobal and update the index.
|
||||
@@ -1991,6 +1994,8 @@ set_mergeappend_references(PlannerInfo *root,
|
||||
set_dummy_tlist_references((Plan *) mplan, rtoffset);
|
||||
|
||||
mplan->apprelids = offset_relid_set(mplan->apprelids, rtoffset);
|
||||
mplan->child_append_relid_sets =
|
||||
offset_relid_set_list(mplan->child_append_relid_sets, rtoffset);
|
||||
|
||||
/*
|
||||
* Add PartitionPruneInfo, if any, to PlannerGlobal and update the index.
|
||||
@@ -2052,6 +2057,24 @@ offset_relid_set(Relids relids, int rtoffset)
|
||||
return bms_offset_members(relids, rtoffset);
|
||||
}
|
||||
|
||||
/*
|
||||
* offset_relid_set_list
|
||||
* Apply rtoffset to the members of each Relid set in a List.
|
||||
*/
|
||||
static List *
|
||||
offset_relid_set_list(List *relid_sets, int rtoffset)
|
||||
{
|
||||
List *result = NIL;
|
||||
|
||||
if (rtoffset == 0)
|
||||
return relid_sets;
|
||||
|
||||
foreach_ptr(Bitmapset, relids, relid_sets)
|
||||
result = lappend(result, offset_relid_set(relids, rtoffset));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* copyVar
|
||||
* Copy a Var node.
|
||||
|
||||
Reference in New Issue
Block a user