v16-0003-Move-EquivalenceMember-indexes-from-RelOptInfo-t.patch

application/octet-stream

Filename: v16-0003-Move-EquivalenceMember-indexes-from-RelOptInfo-t.patch
Type: application/octet-stream
Part: 2
Message: Re: [PoC] Reducing planning time when tables have many partitions

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: format-patch
Series: patch v16-0003
Subject: Move EquivalenceMember indexes from RelOptInfo to PlannerInfo
File+
src/backend/nodes/gen_node_support.pl 10 0
src/backend/optimizer/path/equivclass.c 25 40
src/backend/optimizer/path/indxpath.c 1 1
src/backend/optimizer/prep/prepunion.c 0 1
src/backend/optimizer/util/relnode.c 6 9
src/include/nodes/pathnodes.h 21 17
From 8d4db63bb7b2cd9f5c992f635e2f004815d9bc5b Mon Sep 17 00:00:00 2001
From: Yuya Watari <watari.yuya@gmail.com>
Date: Fri, 3 Feb 2023 13:27:07 +0900
Subject: [PATCH v16 3/5] Move EquivalenceMember indexes from RelOptInfo to
 PlannerInfo

---
 src/backend/nodes/gen_node_support.pl   | 10 ++++
 src/backend/optimizer/path/equivclass.c | 65 ++++++++++---------------
 src/backend/optimizer/path/indxpath.c   |  2 +-
 src/backend/optimizer/prep/prepunion.c  |  1 -
 src/backend/optimizer/util/relnode.c    | 15 +++---
 src/include/nodes/pathnodes.h           | 38 ++++++++-------
 6 files changed, 63 insertions(+), 68 deletions(-)

diff --git a/src/backend/nodes/gen_node_support.pl b/src/backend/nodes/gen_node_support.pl
index 19ed29657c..f40f4fec8f 100644
--- a/src/backend/nodes/gen_node_support.pl
+++ b/src/backend/nodes/gen_node_support.pl
@@ -862,6 +862,11 @@ _equal${n}(const $n *a, const $n *b)
 			print $cff "\tCOPY_SCALAR_FIELD($f);\n"    unless $copy_ignore;
 			print $eff "\tCOMPARE_SCALAR_FIELD($f);\n" unless $equal_ignore;
 		}
+		elsif ($t eq 'ECIndexes*')
+		{
+			# TODO:
+			# Do nothing
+		}
 		else
 		{
 			die
@@ -1211,6 +1216,11 @@ _read${n}(void)
 	}
 ! unless $no_read;
 		}
+		elsif ($t eq 'ECIndexes*')
+		{
+			# TODO:
+			# Do nothing
+		}
 		else
 		{
 			die
diff --git a/src/backend/optimizer/path/equivclass.c b/src/backend/optimizer/path/equivclass.c
index aad14c25ce..c2b27e3ae1 100644
--- a/src/backend/optimizer/path/equivclass.c
+++ b/src/backend/optimizer/path/equivclass.c
@@ -546,10 +546,9 @@ add_eq_source(PlannerInfo *root, EquivalenceClass *ec, RestrictInfo *rinfo)
 	i = -1;
 	while ((i = bms_next_member(rinfo->clause_relids, i)) >= 0)
 	{
-		RelOptInfo *rel = root->simple_rel_array[i];
-
-		rel->eclass_source_indexes = bms_add_member(rel->eclass_source_indexes,
-													source_idx);
+		root->eclass_indexes_array[i].source_indexes
+			= bms_add_member(root->eclass_indexes_array[i].source_indexes,
+							 source_idx);
 	}
 }
 
@@ -568,10 +567,9 @@ add_eq_derive(PlannerInfo *root, EquivalenceClass *ec, RestrictInfo *rinfo)
 	i = -1;
 	while ((i = bms_next_member(rinfo->clause_relids, i)) >= 0)
 	{
-		RelOptInfo *rel = root->simple_rel_array[i];
-
-		rel->eclass_derive_indexes = bms_add_member(rel->eclass_derive_indexes,
-													derive_idx);
+		root->eclass_indexes_array[i].derive_indexes
+			= bms_add_member(root->eclass_indexes_array[i].derive_indexes,
+							 derive_idx);
 	}
 }
 
@@ -650,9 +648,9 @@ add_eq_member(PlannerInfo *root, EquivalenceClass *ec, Expr *expr, Relids relids
 	i = -1;
 	while ((i = bms_next_member(expr_relids, i)) >= 0)
 	{
-		RelOptInfo *rel = root->simple_rel_array[i];
-
-		rel->eclass_member_indexes = bms_add_member(rel->eclass_member_indexes, em_index);
+		root->eclass_indexes_array[i].member_indexes
+			= bms_add_member(root->eclass_indexes_array[i].member_indexes,
+							 em_index);
 	}
 
 	return em;
@@ -2528,10 +2526,9 @@ reconsider_full_join_clause(PlannerInfo *root, OuterJoinClauseInfo *ojcinfo)
 			i = -1;
 			while ((i = bms_next_member(coal_em->em_relids, i)) >= 0)
 			{
-				RelOptInfo *rel = root->simple_rel_array[i];
-
-				rel->eclass_member_indexes = bms_del_member(rel->eclass_member_indexes,
-															coal_idx);
+				root->eclass_indexes_array[i].member_indexes
+					= bms_del_member(root->eclass_indexes_array[i].member_indexes,
+									 coal_idx);
 			}
 
 			return true;
@@ -3467,9 +3464,8 @@ get_ecmember_indexes(PlannerInfo *root, EquivalenceClass *ec, Relids relids,
 
 	while ((i = bms_next_member(relids, i)) >= 0)
 	{
-		RelOptInfo *rel = root->simple_rel_array[i];
-
-		rel_ems = bms_add_members(rel_ems, rel->eclass_member_indexes);
+		rel_ems = bms_add_members(rel_ems,
+								  root->eclass_indexes_array[i].member_indexes);
 	}
 
 #ifdef USE_ASSERT_CHECKING
@@ -3515,8 +3511,6 @@ get_ecmember_indexes_strict(PlannerInfo *root, EquivalenceClass *ec,
 
 	if (i >= 0)
 	{
-		RelOptInfo *rel = root->simple_rel_array[i];
-
 		/*
 		 * bms_intersect to the first relation to try to keep the resulting
 		 * Bitmapset as small as possible.  This saves having to make a
@@ -3524,17 +3518,16 @@ get_ecmember_indexes_strict(PlannerInfo *root, EquivalenceClass *ec,
 		 * more words than the other.
 		 */
 		if (!with_children)
-			matching_ems = bms_intersect(rel->eclass_member_indexes,
+			matching_ems = bms_intersect(root->eclass_indexes_array[i].member_indexes,
 										 ec->ec_nonchild_indexes);
 		else
-			matching_ems = bms_intersect(rel->eclass_member_indexes,
+			matching_ems = bms_intersect(root->eclass_indexes_array[i].member_indexes,
 										 ec->ec_member_indexes);
 
 		while ((i = bms_next_member(relids, i)) >= 0)
 		{
-			rel = root->simple_rel_array[i];
 			matching_ems = bms_int_members(matching_ems,
-										   rel->eclass_member_indexes);
+										   root->eclass_indexes_array[i].member_indexes);
 		}
 	}
 
@@ -3879,9 +3872,8 @@ get_ec_source_indexes(PlannerInfo *root, EquivalenceClass *ec, Relids relids)
 
 	while ((i = bms_next_member(relids, i)) >= 0)
 	{
-		RelOptInfo *rel = root->simple_rel_array[i];
-
-		rel_esis = bms_add_members(rel_esis, rel->eclass_source_indexes);
+		rel_esis = bms_add_members(rel_esis,
+								   root->eclass_indexes_array[i].source_indexes);
 	}
 
 #ifdef USE_ASSERT_CHECKING
@@ -3917,8 +3909,6 @@ get_ec_source_indexes_strict(PlannerInfo *root, EquivalenceClass *ec,
 
 	if (i >= 0)
 	{
-		RelOptInfo *rel = root->simple_rel_array[i];
-
 		/*
 		 * bms_intersect to the first relation to try to keep the resulting
 		 * Bitmapset as small as possible.  This saves having to make a
@@ -3926,12 +3916,11 @@ get_ec_source_indexes_strict(PlannerInfo *root, EquivalenceClass *ec,
 		 * more words than the other.
 		 */
 		esis = bms_intersect(ec->ec_source_indexes,
-							 rel->eclass_source_indexes);
+							 root->eclass_indexes_array[i].source_indexes);
 
 		while ((i = bms_next_member(relids, i)) >= 0)
 		{
-			rel = root->simple_rel_array[i];
-			esis = bms_int_members(esis, rel->eclass_source_indexes);
+			esis = bms_int_members(esis, root->eclass_indexes_array[i].source_indexes);
 		}
 	}
 
@@ -3968,9 +3957,8 @@ get_ec_derive_indexes(PlannerInfo *root, EquivalenceClass *ec, Relids relids)
 
 	while ((i = bms_next_member(relids, i)) >= 0)
 	{
-		RelOptInfo *rel = root->simple_rel_array[i];
-
-		rel_edis = bms_add_members(rel_edis, rel->eclass_derive_indexes);
+		rel_edis = bms_add_members(rel_edis,
+								   root->eclass_indexes_array[i].derive_indexes);
 	}
 
 #ifdef USE_ASSERT_CHECKING
@@ -4006,8 +3994,6 @@ get_ec_derive_indexes_strict(PlannerInfo *root, EquivalenceClass *ec,
 
 	if (i >= 0)
 	{
-		RelOptInfo *rel = root->simple_rel_array[i];
-
 		/*
 		 * bms_intersect to the first relation to try to keep the resulting
 		 * Bitmapset as small as possible.  This saves having to make a
@@ -4015,12 +4001,11 @@ get_ec_derive_indexes_strict(PlannerInfo *root, EquivalenceClass *ec,
 		 * more words than the other.
 		 */
 		edis = bms_intersect(ec->ec_derive_indexes,
-							 rel->eclass_derive_indexes);
+							 root->eclass_indexes_array[i].derive_indexes);
 
 		while ((i = bms_next_member(relids, i)) >= 0)
 		{
-			rel = root->simple_rel_array[i];
-			edis = bms_int_members(edis, rel->eclass_derive_indexes);
+			edis = bms_int_members(edis, root->eclass_indexes_array[i].derive_indexes);
 		}
 	}
 
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 5ebf944cb1..384932727b 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -3111,7 +3111,7 @@ match_pathkeys_to_index(PlannerInfo *root, IndexOptInfo *index,
 		 * here.  See also get_eclass_for_sort_expr.)
 		 */
 		matching_ems = bms_intersect(pathkey->pk_eclass->ec_member_indexes,
-									 index->rel->eclass_member_indexes);
+									 root->eclass_indexes_array[index->rel->relid].member_indexes);
 
 		i = -1;
 		while ((i = bms_next_member(matching_ems, i)) >= 0)
diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c
index 4c7d66311f..938a1f581c 100644
--- a/src/backend/optimizer/prep/prepunion.c
+++ b/src/backend/optimizer/prep/prepunion.c
@@ -196,7 +196,6 @@ setup_append_rel_entry(PlannerInfo *root)
 	RelOptInfo *rel = makeNode(RelOptInfo);
 
 	memset(rel, 0, sizeof(RelOptInfo));
-	rel->eclass_member_indexes = NULL;
 
 	/* make sure nothing else has made use of this element */
 	Assert(root->simple_rel_array[0] == NULL);
diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c
index dfa374a8cf..2131333297 100644
--- a/src/backend/optimizer/util/relnode.c
+++ b/src/backend/optimizer/util/relnode.c
@@ -105,6 +105,9 @@ setup_simple_rel_arrays(PlannerInfo *root)
 	root->simple_rel_array = (RelOptInfo **)
 		palloc0(size * sizeof(RelOptInfo *));
 
+	root->eclass_indexes_array = (ECIndexes *)
+		palloc0(size * sizeof(ECIndexes));
+
 	/* simple_rte_array is an array equivalent of the rtable list */
 	root->simple_rte_array = (RangeTblEntry **)
 		palloc0(size * sizeof(RangeTblEntry *));
@@ -168,6 +171,9 @@ expand_planner_arrays(PlannerInfo *root, int add_size)
 	root->simple_rel_array =
 		repalloc0_array(root->simple_rel_array, RelOptInfo *, root->simple_rel_array_size, new_size);
 
+	root->eclass_indexes_array =
+		repalloc0_array(root->eclass_indexes_array, ECIndexes, root->simple_rel_array_size, new_size);
+
 	root->simple_rte_array =
 		repalloc0_array(root->simple_rte_array, RangeTblEntry *, root->simple_rel_array_size, new_size);
 
@@ -226,9 +232,6 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent)
 	rel->tuples = 0;
 	rel->allvisfrac = 0;
 	rel->eclass_indexes = NULL;
-	rel->eclass_member_indexes = NULL;
-	rel->eclass_source_indexes = NULL;
-	rel->eclass_derive_indexes = NULL;
 	rel->subroot = NULL;
 	rel->subplan_params = NIL;
 	rel->rel_parallel_workers = -1; /* set up in get_relation_info */
@@ -704,9 +707,6 @@ build_join_rel(PlannerInfo *root,
 	joinrel->tuples = 0;
 	joinrel->allvisfrac = 0;
 	joinrel->eclass_indexes = NULL;
-	joinrel->eclass_member_indexes = NULL;
-	joinrel->eclass_source_indexes = NULL;
-	joinrel->eclass_derive_indexes = NULL;
 	joinrel->subroot = NULL;
 	joinrel->subplan_params = NIL;
 	joinrel->rel_parallel_workers = -1;
@@ -896,9 +896,6 @@ build_child_join_rel(PlannerInfo *root, RelOptInfo *outer_rel,
 	joinrel->tuples = 0;
 	joinrel->allvisfrac = 0;
 	joinrel->eclass_indexes = NULL;
-	joinrel->eclass_member_indexes = NULL;
-	joinrel->eclass_source_indexes = NULL;
-	joinrel->eclass_derive_indexes = NULL;
 	joinrel->subroot = NULL;
 	joinrel->subplan_params = NIL;
 	joinrel->amflags = 0;
diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h
index cf43dd1385..0b57a89f94 100644
--- a/src/include/nodes/pathnodes.h
+++ b/src/include/nodes/pathnodes.h
@@ -169,6 +169,25 @@ typedef struct PlannerGlobal
 #define planner_subplan_get_plan(root, subplan) \
 	((Plan *) list_nth((root)->glob->subplans, (subplan)->plan_id - 1))
 
+typedef struct ECIndexes
+{
+	/*
+	 * Indexes in PlannerInfo's eq_members list of EMs that mention this rel
+	 */
+	Bitmapset  *member_indexes;
+
+	/*
+	 * Indexes in PlannerInfo's eq_sources list for RestrictInfos that mention
+	 * this relation.
+	 */
+	Bitmapset  *source_indexes;
+
+	/*
+	 * Indexes in PlannerInfo's eq_derives list for RestrictInfos that mention
+	 * this relation.
+	 */
+	Bitmapset  *derive_indexes;
+} ECIndexes;
 
 /*----------
  * PlannerInfo
@@ -231,6 +250,8 @@ struct PlannerInfo
 	/* allocated size of array */
 	int			simple_rel_array_size;
 
+	ECIndexes  *eclass_indexes_array pg_node_attr(array_size(simple_rel_array_size));
+
 	/*
 	 * simple_rte_array is the same length as simple_rel_array and holds
 	 * pointers to the associated rangetable entries.  Using this is a shade
@@ -949,23 +970,6 @@ typedef struct RelOptInfo
 	/* indexes in PlannerInfo's eq_classes list of ECs that mention this rel */
 	Bitmapset  *eclass_indexes;
 
-	/*
-	 * Indexes in PlannerInfo's eq_members list of EMs that mention this rel
-	 */
-	Bitmapset  *eclass_member_indexes;
-
-	/*
-	 * Indexes in PlannerInfo's eq_sources list for RestrictInfos that mention
-	 * this relation.
-	 */
-	Bitmapset  *eclass_source_indexes;
-
-	/*
-	 * Indexes in PlannerInfo's eq_derives list for RestrictInfos that mention
-	 * this relation.
-	 */
-	Bitmapset  *eclass_derive_indexes;
-
 	PlannerInfo *subroot;		/* if subquery */
 	List	   *subplan_params; /* if subquery */
 	/* wanted number of parallel workers */
-- 
2.35.3.windows.1