From 79d246c59b1b6bc077c44805c7e1d7d1c190828a Mon Sep 17 00:00:00 2001 From: Yuya Watari Date: Fri, 19 Jan 2024 11:43:29 +0900 Subject: [PATCH v24 3/3] Move EquivalenceClass indexes to PlannerInfo In the previous commit, the indexes, namely ec_[source|derive]_indexes, were in RestrictInfo. This was a workaround because RelOptInfo was the best place but some RelOptInfos can be NULL and we cannot store indexes for them. This commit introduces a new struct, EquivalenceClassIndexes. This struct exists in PlannerInfo and holds our indexes. This change prevents a serialization problem with RestirctInfo in the previous commit. --- src/backend/nodes/outfuncs.c | 2 - src/backend/nodes/readfuncs.c | 2 - src/backend/optimizer/path/equivclass.c | 83 +++++++++++------------ src/backend/optimizer/plan/analyzejoins.c | 16 ++--- src/backend/optimizer/util/inherit.c | 7 -- src/backend/optimizer/util/relnode.c | 6 ++ src/include/nodes/parsenodes.h | 6 -- src/include/nodes/pathnodes.h | 24 +++++++ src/tools/pgindent/typedefs.list | 1 + 9 files changed, 80 insertions(+), 67 deletions(-) diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index c61110c200..b08a4789c4 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -567,8 +567,6 @@ _outRangeTblEntry(StringInfo str, const RangeTblEntry *node) WRITE_BOOL_FIELD(inh); WRITE_BOOL_FIELD(inFromCl); WRITE_NODE_FIELD(securityQuals); - WRITE_BITMAPSET_FIELD(eclass_source_indexes); - WRITE_BITMAPSET_FIELD(eclass_derive_indexes); } static void diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index e3518c602b..b1e2f2b440 100644 --- a/src/backend/nodes/readfuncs.c +++ b/src/backend/nodes/readfuncs.c @@ -431,8 +431,6 @@ _readRangeTblEntry(void) READ_BOOL_FIELD(inh); READ_BOOL_FIELD(inFromCl); READ_NODE_FIELD(securityQuals); - READ_BITMAPSET_FIELD(eclass_source_indexes); - READ_BITMAPSET_FIELD(eclass_derive_indexes); READ_DONE(); } diff --git a/src/backend/optimizer/path/equivclass.c b/src/backend/optimizer/path/equivclass.c index 17fffc4087..4fb1ecff03 100644 --- a/src/backend/optimizer/path/equivclass.c +++ b/src/backend/optimizer/path/equivclass.c @@ -607,10 +607,10 @@ add_eq_source(PlannerInfo *root, EquivalenceClass *ec, RestrictInfo *rinfo) i = -1; while ((i = bms_next_member(rinfo->clause_relids, i)) >= 0) { - RangeTblEntry *rte = root->simple_rte_array[i]; + EquivalenceClassIndexes *index = &root->eclass_indexes_array[i]; - rte->eclass_source_indexes = bms_add_member(rte->eclass_source_indexes, - source_idx); + index->source_indexes = bms_add_member(index->source_indexes, + source_idx); } } @@ -631,10 +631,10 @@ add_eq_derive(PlannerInfo *root, EquivalenceClass *ec, RestrictInfo *rinfo) i = -1; while ((i = bms_next_member(rinfo->clause_relids, i)) >= 0) { - RangeTblEntry *rte = root->simple_rte_array[i]; + EquivalenceClassIndexes *index = &root->eclass_indexes_array[i]; - rte->eclass_derive_indexes = bms_add_member(rte->eclass_derive_indexes, - derive_idx); + index->derive_indexes = bms_add_member(index->derive_indexes, + derive_idx); } } @@ -673,22 +673,22 @@ update_clause_relids(PlannerInfo *root, RestrictInfo *rinfo, i = -1; while ((i = bms_next_member(removing_relids, i)) >= 0) { - RangeTblEntry *rte = root->simple_rte_array[i]; + EquivalenceClassIndexes *index = &root->eclass_indexes_array[i]; if (rinfo->eq_sources_index != -1) { Assert(bms_is_member(rinfo->eq_sources_index, - rte->eclass_source_indexes)); - rte->eclass_source_indexes = - bms_del_member(rte->eclass_source_indexes, + index->source_indexes)); + index->source_indexes = + bms_del_member(index->source_indexes, rinfo->eq_sources_index); } if (rinfo->eq_derives_index != -1) { Assert(bms_is_member(rinfo->eq_derives_index, - rte->eclass_derive_indexes)); - rte->eclass_derive_indexes = - bms_del_member(rte->eclass_derive_indexes, + index->derive_indexes)); + index->derive_indexes = + bms_del_member(index->derive_indexes, rinfo->eq_derives_index); } } @@ -702,22 +702,22 @@ update_clause_relids(PlannerInfo *root, RestrictInfo *rinfo, i = -1; while ((i = bms_next_member(adding_relids, i)) >= 0) { - RangeTblEntry *rte = root->simple_rte_array[i]; + EquivalenceClassIndexes *index = &root->eclass_indexes_array[i]; if (rinfo->eq_sources_index != -1) { Assert(!bms_is_member(rinfo->eq_sources_index, - rte->eclass_source_indexes)); - rte->eclass_source_indexes = - bms_add_member(rte->eclass_source_indexes, + index->source_indexes)); + index->source_indexes = + bms_add_member(index->source_indexes, rinfo->eq_sources_index); } if (rinfo->eq_derives_index != -1) { Assert(!bms_is_member(rinfo->eq_derives_index, - rte->eclass_derive_indexes)); - rte->eclass_derive_indexes = - bms_add_member(rte->eclass_derive_indexes, + index->derive_indexes)); + index->derive_indexes = + bms_add_member(index->derive_indexes, rinfo->eq_derives_index); } } @@ -731,17 +731,17 @@ update_clause_relids(PlannerInfo *root, RestrictInfo *rinfo, i = -1; while ((i = bms_next_member(common_relids, i)) >= 0) { - RangeTblEntry *rte = root->simple_rte_array[i]; + EquivalenceClassIndexes *index = &root->eclass_indexes_array[i]; if (rinfo->eq_sources_index != -1) { Assert(bms_is_member(rinfo->eq_sources_index, - rte->eclass_source_indexes)); + index->source_indexes)); } if (rinfo->eq_derives_index != -1) { Assert(bms_is_member(rinfo->eq_derives_index, - rte->eclass_derive_indexes)); + index->derive_indexes)); } } bms_free(common_relids); @@ -3777,9 +3777,9 @@ get_ec_source_indexes(PlannerInfo *root, EquivalenceClass *ec, Relids relids) while ((i = bms_next_member(relids, i)) >= 0) { - RangeTblEntry *rte = root->simple_rte_array[i]; + EquivalenceClassIndexes *index = &root->eclass_indexes_array[i]; - rel_esis = bms_add_members(rel_esis, rte->eclass_source_indexes); + rel_esis = bms_add_members(rel_esis, index->source_indexes); } #ifdef USE_ASSERT_CHECKING @@ -3815,7 +3815,7 @@ get_ec_source_indexes_strict(PlannerInfo *root, EquivalenceClass *ec, if (i >= 0) { - RangeTblEntry *rte = root->simple_rte_array[i]; + EquivalenceClassIndexes *index = &root->eclass_indexes_array[i]; /* * bms_intersect to the first relation to try to keep the resulting @@ -3824,12 +3824,12 @@ get_ec_source_indexes_strict(PlannerInfo *root, EquivalenceClass *ec, * more words than the other. */ esis = bms_intersect(ec->ec_source_indexes, - rte->eclass_source_indexes); + index->source_indexes); while ((i = bms_next_member(relids, i)) >= 0) { - rte = root->simple_rte_array[i]; - esis = bms_int_members(esis, rte->eclass_source_indexes); + index = &root->eclass_indexes_array[i]; + esis = bms_int_members(esis, index->source_indexes); } } @@ -3866,9 +3866,9 @@ get_ec_derive_indexes(PlannerInfo *root, EquivalenceClass *ec, Relids relids) while ((i = bms_next_member(relids, i)) >= 0) { - RangeTblEntry *rte = root->simple_rte_array[i]; + EquivalenceClassIndexes *index = &root->eclass_indexes_array[i]; - rel_edis = bms_add_members(rel_edis, rte->eclass_derive_indexes); + rel_edis = bms_add_members(rel_edis, index->derive_indexes); } #ifdef USE_ASSERT_CHECKING @@ -3904,7 +3904,7 @@ get_ec_derive_indexes_strict(PlannerInfo *root, EquivalenceClass *ec, if (i >= 0) { - RangeTblEntry *rte = root->simple_rte_array[i]; + EquivalenceClassIndexes *index = &root->eclass_indexes_array[i]; /* * bms_intersect to the first relation to try to keep the resulting @@ -3913,12 +3913,12 @@ get_ec_derive_indexes_strict(PlannerInfo *root, EquivalenceClass *ec, * more words than the other. */ edis = bms_intersect(ec->ec_derive_indexes, - rte->eclass_derive_indexes); + index->derive_indexes); while ((i = bms_next_member(relids, i)) >= 0) { - rte = root->simple_rte_array[i]; - edis = bms_int_members(edis, rte->eclass_derive_indexes); + index = &root->eclass_indexes_array[i]; + edis = bms_int_members(edis, index->derive_indexes); } } @@ -3941,9 +3941,8 @@ get_ec_derive_indexes_strict(PlannerInfo *root, EquivalenceClass *ec, /* * verify_eclass_indexes * Verify that there are no missing references between RestrictInfos and - * EquivalenceMember's indexes, namely eclass_source_indexes and - * eclass_derive_indexes. If you modify these indexes, you should check - * them with this function. + * EquivalenceMember's indexes, namely source_indexes and derive_indexes. + * If you modify these indexes, you should check them with this function. */ void verify_eclass_indexes(PlannerInfo *root, EquivalenceClass *ec) @@ -3952,7 +3951,7 @@ verify_eclass_indexes(PlannerInfo *root, EquivalenceClass *ec) /* * All RestrictInfos in root->eq_sources must have references to - * eclass_source_indexes. + * source_indexes. */ foreach(lc, root->eq_sources) { @@ -3969,13 +3968,13 @@ verify_eclass_indexes(PlannerInfo *root, EquivalenceClass *ec) while ((k = bms_next_member(rinfo->clause_relids, k)) >= 0) { /* must have a reference */ - Assert(bms_is_member(index, root->simple_rte_array[k]->eclass_source_indexes)); + Assert(bms_is_member(index, root->eclass_indexes_array[k].source_indexes)); } } /* * All RestrictInfos in root->eq_derives must have references to - * eclass_derive_indexes. + * derive_indexes. */ foreach(lc, root->eq_derives) { @@ -3992,7 +3991,7 @@ verify_eclass_indexes(PlannerInfo *root, EquivalenceClass *ec) while ((k = bms_next_member(rinfo->clause_relids, k)) >= 0) { /* must have a reference */ - Assert(bms_is_member(index, root->simple_rte_array[k]->eclass_derive_indexes)); + Assert(bms_is_member(index, root->eclass_indexes_array[k].derive_indexes)); } } } diff --git a/src/backend/optimizer/plan/analyzejoins.c b/src/backend/optimizer/plan/analyzejoins.c index 13e987493b..d2fdc2649a 100644 --- a/src/backend/optimizer/plan/analyzejoins.c +++ b/src/backend/optimizer/plan/analyzejoins.c @@ -1686,11 +1686,11 @@ update_eclasses(PlannerInfo *root, EquivalenceClass *ec, int from, int to) j = -1; while ((j = bms_next_member(rinfo->clause_relids, j)) >= 0) { - RangeTblEntry *rte = root->simple_rte_array[j]; + EquivalenceClassIndexes *index = &root->eclass_indexes_array[j]; - Assert(bms_is_member(i, rte->eclass_derive_indexes)); - rte->eclass_derive_indexes = - bms_del_member(rte->eclass_derive_indexes, i); + Assert(bms_is_member(i, index->derive_indexes)); + index->derive_indexes = + bms_del_member(index->derive_indexes, i); } /* @@ -1752,11 +1752,11 @@ update_eclasses(PlannerInfo *root, EquivalenceClass *ec, int from, int to) j = -1; while ((j = bms_next_member(rinfo->clause_relids, j)) >= 0) { - RangeTblEntry *rte = root->simple_rte_array[j]; + EquivalenceClassIndexes *index = &root->eclass_indexes_array[j]; - Assert(bms_is_member(i, rte->eclass_source_indexes)); - rte->eclass_source_indexes = - bms_del_member(rte->eclass_source_indexes, i); + Assert(bms_is_member(i, index->source_indexes)); + index->source_indexes = + bms_del_member(index->source_indexes, i); } /* diff --git a/src/backend/optimizer/util/inherit.c b/src/backend/optimizer/util/inherit.c index a65a76ace9..3501fbbeed 100644 --- a/src/backend/optimizer/util/inherit.c +++ b/src/backend/optimizer/util/inherit.c @@ -483,13 +483,6 @@ expand_single_inheritance_child(PlannerInfo *root, RangeTblEntry *parentrte, */ childrte = makeNode(RangeTblEntry); memcpy(childrte, parentrte, sizeof(RangeTblEntry)); - /* - * We do not want to inherit the EquivalenceMember indexes of the parent - * to its child - */ - childrte->eclass_source_indexes = NULL; - childrte->eclass_derive_indexes = NULL; - Assert(parentrte->rtekind == RTE_RELATION); /* else this is dubious */ childrte->relid = childOID; childrte->relkind = childrel->rd_rel->relkind; diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c index 9973326e90..bc9195c623 100644 --- a/src/backend/optimizer/util/relnode.c +++ b/src/backend/optimizer/util/relnode.c @@ -119,6 +119,9 @@ setup_simple_rel_arrays(PlannerInfo *root) root->simple_rte_array[rti++] = rte; } + root->eclass_indexes_array = (EquivalenceClassIndexes *) + palloc0(size * sizeof(EquivalenceClassIndexes)); + /* append_rel_array is not needed if there are no AppendRelInfos */ if (root->append_rel_list == NIL) { @@ -217,6 +220,9 @@ expand_planner_arrays(PlannerInfo *root, int add_size) root->top_parent_relid_array = NULL; } + root->eclass_indexes_array = + repalloc0_array(root->eclass_indexes_array, EquivalenceClassIndexes, root->simple_rel_array_size, new_size); + root->simple_rel_array_size = new_size; } diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index f624f41d99..baa6a97c7e 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -1194,12 +1194,6 @@ typedef struct RangeTblEntry bool inh; /* inheritance requested? */ bool inFromCl; /* present in FROM clause? */ List *securityQuals; /* security barrier quals to apply, if any */ - Bitmapset *eclass_source_indexes; /* Indexes in PlannerInfo's eq_sources - * list for RestrictInfos that mention - * this relation */ - Bitmapset *eclass_derive_indexes; /* Indexes in PlannerInfo's eq_derives - * list for RestrictInfos that mention - * this relation */ } RangeTblEntry; /* diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 81253d0351..49f53fd51e 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -189,6 +189,8 @@ typedef struct PlannerInfo PlannerInfo; #define HAVE_PLANNERINFO_TYPEDEF 1 #endif +struct EquivalenceClassIndexes; + struct PlannerInfo { pg_node_attr(no_copy_equal, no_read, no_query_jumble) @@ -245,6 +247,13 @@ struct PlannerInfo */ struct AppendRelInfo **append_rel_array pg_node_attr(read_write_ignore); + /* + * eclass_indexes_array is the same length as simple_rel_array and holds + * the indexes of the corresponding rels for faster lookups of + * RestrictInfo. See the EquivalenceClass comment for more details. + */ + struct EquivalenceClassIndexes *eclass_indexes_array pg_node_attr(read_write_ignore); + /* * append_rel_array is the same length as simple_rel_array and holds the * top-level parent indexes of the corresponding rels within @@ -1509,6 +1518,21 @@ typedef struct List *ec_members; /* parent and child members*/ } EquivalenceChildMemberIterator; +/* + * EquivalenceClassIndexes + * + * As mentioned in the EquivalenceClass comment, we introduce a + * bitmapset-based indexing mechanism for faster lookups of RestrictInfo. This + * struct exists for each relation and holds the corresponding indexes. + */ +typedef struct EquivalenceClassIndexes +{ + Bitmapset *source_indexes; /* Indexes in PlannerInfo's eq_sources list for + RestrictInfos that mention this relation */ + Bitmapset *derive_indexes; /* Indexes in PlannerInfo's eq_derives list for + RestrictInfos that mention this relation */ +} EquivalenceClassIndexes; + /* * PathKeys * diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list index 8f86dd864e..565dce4040 100644 --- a/src/tools/pgindent/typedefs.list +++ b/src/tools/pgindent/typedefs.list @@ -663,6 +663,7 @@ EphemeralNamedRelationMetadata EphemeralNamedRelationMetadataData EquivalenceChildMemberIterator EquivalenceClass +EquivalenceClassIndexes EquivalenceMember ErrorContextCallback ErrorData -- 2.42.0.windows.2