1
0
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:
Robert Haas
2026-10-08 12:11:08 -04:00
parent 16b94c4012
commit 0f7dfd7936
3 changed files with 121 additions and 0 deletions

View File

@@ -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)

View File

@@ -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;

View File

@@ -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.