v13-0005-Fix-incorrect-filtering-condition-in-iteration.patch

application/octet-stream

Filename: v13-0005-Fix-incorrect-filtering-condition-in-iteration.patch
Type: application/octet-stream
Part: 4
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 v13-0005
Subject: Fix incorrect filtering condition in iteration
File+
src/backend/optimizer/path/equivclass.c 30 38
From 401c2ddf9ce72cccbe39e908737d68a6704c7926 Mon Sep 17 00:00:00 2001
From: Yuya Watari <watari.yuya@gmail.com>
Date: Mon, 30 Jan 2023 09:46:56 +0900
Subject: [PATCH v13 5/7] Fix incorrect filtering condition in iteration

The original code incorrectly missed EquivalenceMembers with empty
em_relids when 'with_norel_members' is true in
eclass_member_iterator_strict_next(). Such an EM passes the second if
condition, but fails the last condition because it cannot be superset of
non-empty relids.
---
 src/backend/optimizer/path/equivclass.c | 68 +++++++++++--------------
 1 file changed, 30 insertions(+), 38 deletions(-)

diff --git a/src/backend/optimizer/path/equivclass.c b/src/backend/optimizer/path/equivclass.c
index 561f50cafa..83ea0313e1 100644
--- a/src/backend/optimizer/path/equivclass.c
+++ b/src/backend/optimizer/path/equivclass.c
@@ -3733,26 +3733,22 @@ eclass_member_iterator_next(EquivalenceMemberIterator *iter)
 		{
 			EquivalenceMember *em = lfirst_node(EquivalenceMember, lc);
 
-			if (!iter->with_children && em->em_is_child)
-				continue;
-
-			if (!iter->with_norel_members && bms_is_empty(em->em_relids))
-				continue;
-
-			if (!bms_overlap(em->em_relids, iter->with_relids))
-				continue;
-
-			iter->current_index = foreach_current_index(lc);
+			if ((iter->with_norel_members && bms_is_empty(em->em_relids))
+				|| (bms_overlap(em->em_relids, iter->with_relids)
+					&& (iter->with_children || !em->em_is_child)))
+			{
+				iter->current_index = foreach_current_index(lc);
 
-			/*
-			 * Some users of this iterator will be adding new
-			 * EquivalenceMember during the loop.  We must ensure we don't
-			 * return those, so here we return NULL when the loop index goes
-			 * beyond the original length of the ec_members list.
-			 */
-			if (iter->current_index >= iter->orig_length)
-				return NULL;
-			return em;
+				/*
+				 * Some users of this iterator will be adding new
+				 * EquivalenceMember during the loop.  We must ensure we don't
+				 * return those, so here we return NULL when the loop index goes
+				 * beyond the original length of the ec_members list.
+				 */
+				if (iter->current_index >= iter->orig_length)
+					return NULL;
+				return em;
+			}
 		}
 		return NULL;
 	}
@@ -3784,26 +3780,22 @@ eclass_member_iterator_strict_next(EquivalenceMemberIterator *iter)
 		{
 			EquivalenceMember *em = lfirst_node(EquivalenceMember, lc);
 
-			if (!iter->with_children && em->em_is_child)
-				continue;
-
-			if (!iter->with_norel_members && bms_is_empty(em->em_relids))
-				continue;
-
-			if (!bms_is_subset(iter->with_relids, em->em_relids))
-				continue;
-
-			iter->current_index = foreach_current_index(lc);
+			if ((iter->with_norel_members && bms_is_empty(em->em_relids))
+				|| (bms_is_subset(iter->with_relids, em->em_relids)
+					&& (iter->with_children || !em->em_is_child)))
+			{
+				iter->current_index = foreach_current_index(lc);
 
-			/*
-			 * Some users of this iterator will be adding new
-			 * EquivalenceMember during the loop.  We must ensure we don't
-			 * return those, so here we return NULL when the loop index goes
-			 * beyond the original length of the ec_members list.
-			 */
-			if (iter->current_index >= iter->orig_length)
-				return NULL;
-			return em;
+				/*
+				 * Some users of this iterator will be adding new
+				 * EquivalenceMember during the loop.  We must ensure we don't
+				 * return those, so here we return NULL when the loop index goes
+				 * beyond the original length of the ec_members list.
+				 */
+				if (iter->current_index >= iter->orig_length)
+					return NULL;
+				return em;
+			}
 		}
 		return NULL;
 	}
-- 
2.35.3.windows.1