eq_member_find_duplicates.patch.txt

text/plain

Filename: eq_member_find_duplicates.patch.txt
Type: text/plain
Part: 0
Message: Re: [PoC] Reducing planning time when tables have many partitions
diff --git b/src/backend/optimizer/path/equivclass.c a/src/backend/optimizer/path/equivclass.c
index b8c64d80987..30f1ca37e2e 100644
--- b/src/backend/optimizer/path/equivclass.c
+++ a/src/backend/optimizer/path/equivclass.c
@@ -617,6 +617,7 @@ make_eq_member(EquivalenceClass *ec, Expr *expr, Relids relids,
 		ec->ec_has_const = true;
 		/* it can't affect ec_relids */
 	}
+	em->iterator_generation = 0;
 
 	return em;
 }
@@ -930,6 +931,7 @@ find_ec_member_matching_expr(EquivalenceClass *ec,
 		expr = ((RelabelType *) expr)->arg;
 
 	setup_eclass_member_iterator(&it, ec, relids);
+	it.warn_if_returned_before = false;
 	while ((em = eclass_member_iterator_next(&it)) != NULL)
 	{
 		Expr	   *emexpr;
@@ -3149,10 +3151,14 @@ add_setop_child_rel_equivalences(PlannerInfo *root, RelOptInfo *child_rel,
  *	ec - The EquivalenceClass from which to iterate members.
  *	child_relids - The relids to return child members for.
  */
+uint64 iterator_generation = 0;
+
 void
 setup_eclass_member_iterator(EquivalenceMemberIterator *it,
 							 EquivalenceClass *ec, Relids child_relids)
 {
+	it->iterator_generation = ++iterator_generation;
+	it->warn_if_returned_before = true;
 	it->ec = ec;
 	/* no need to set this if the class has no child members */
 	it->child_relids = ec->ec_childmembers != NULL ? child_relids : NULL;
@@ -3179,6 +3185,9 @@ nextcell:
 			EquivalenceMember *em;
 
 			em = lfirst_node(EquivalenceMember, it->current_cell);
+			if (it->warn_if_returned_before && em->iterator_generation == it->iterator_generation)
+				elog(NOTICE, "returned before %llu", it->iterator_generation);
+			em->iterator_generation = it->iterator_generation;
 			it->current_cell = lnext(it->current_list, it->current_cell);
 			return em;
 		}
diff --git b/src/include/nodes/pathnodes.h a/src/include/nodes/pathnodes.h
index a44f5bb1f60..60f156da136 100644
--- b/src/include/nodes/pathnodes.h
+++ a/src/include/nodes/pathnodes.h
@@ -1514,6 +1514,7 @@ typedef struct EquivalenceMember
 	JoinDomain *em_jdomain;		/* join domain containing the source clause */
 	/* if em_is_child is true, this links to corresponding EM for top parent */
 	struct EquivalenceMember *em_parent pg_node_attr(read_write_ignore);
+	uint64 iterator_generation;
 } EquivalenceMember;
 
 /*
@@ -1570,6 +1571,8 @@ typedef struct EquivalenceMember
  */
 typedef struct
 {
+	uint64 iterator_generation;
+	bool warn_if_returned_before;
 	EquivalenceClass *ec;		/* The EquivalenceClass to iterate over */
 	int			current_relid;	/* Current relid position within 'relids'. -1
 								 * when still looping over ec_members and -2