v12-0004-Add-a-validation-to-check-that-two-iteration-res.patch
application/octet-stream
Filename: v12-0004-Add-a-validation-to-check-that-two-iteration-res.patch
Type: application/octet-stream
Part: 3
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 v12-0004
Subject: Add a validation to check that two iteration results are the same
| File | + | − |
|---|---|---|
| src/backend/optimizer/path/equivclass.c | 92 | 0 |
From 2de0de6020be4d757db2ed10ff4f57f77fbd5520 Mon Sep 17 00:00:00 2001
From: Yuya Watari <watari.yuya@gmail.com>
Date: Fri, 27 Jan 2023 11:26:13 +0900
Subject: [PATCH v12 4/4] Add a validation to check that two iteration results
are the same
---
src/backend/optimizer/path/equivclass.c | 92 +++++++++++++++++++++++++
1 file changed, 92 insertions(+)
diff --git a/src/backend/optimizer/path/equivclass.c b/src/backend/optimizer/path/equivclass.c
index bd9493f659..561f50cafa 100644
--- a/src/backend/optimizer/path/equivclass.c
+++ b/src/backend/optimizer/path/equivclass.c
@@ -3550,6 +3550,68 @@ get_ecmember_indexes_strict(PlannerInfo *root, EquivalenceClass *ec,
*/
#define ECMEMBER_INDEX_THRESHOLD 16
+#ifdef USE_ASSERT_CHECKING
+static int
+list_ptr_cmp(const ListCell *p1, const ListCell *p2)
+{
+ void *v1 = lfirst(p1);
+ void *v2 = lfirst(p2);
+
+ if (v1 < v2)
+ return -1;
+ if (v1 > v2)
+ return 1;
+ return 0;
+}
+
+/*
+ * validate_eclass_member_iterator
+ * Assert that the results of the iterations are the same with and without
+ * indexes. The function iterates in two methods and asserts that the
+ * results are equal.
+ */
+static void
+validate_eclass_member_iterator(const EquivalenceMemberIterator *iter,
+ EquivalenceMember *(*next)(EquivalenceMemberIterator *iter))
+{
+ /* First, we create two copies of the given iterator */
+ EquivalenceMemberIterator with_index = *iter;
+ EquivalenceMemberIterator without_index = *iter;
+
+ /* The results of the two iterations */
+ List *result_with_index = NIL;
+ List *result_without_index = NIL;
+
+ EquivalenceMember *em;
+ ListCell *lc1;
+ ListCell *lc2;
+
+ /* Set flags */
+ with_index.use_index = true;
+ without_index.use_index = false;
+
+ /* Get the result with index */
+ while ((em = next(&with_index)) != NULL)
+ result_with_index = lappend(result_with_index, em);
+
+ /* Get the result without index */
+ while ((em = next(&without_index)) != NULL)
+ result_without_index = lappend(result_without_index, em);
+
+ /* Sort the two lists to ignore the iteration order */
+ list_sort(result_with_index, list_ptr_cmp);
+ list_sort(result_without_index, list_ptr_cmp);
+
+ /* Validate */
+ Assert(list_length(result_with_index) == list_length(result_without_index));
+
+ forboth(lc1, result_with_index, lc2, result_without_index)
+ {
+ Assert(lfirst(lc1) == lfirst(lc2));
+ }
+}
+#endif
+
/*
* setup_eclass_member_iterator
* Setup 'iter' so it's ready for eclass_member_iterator_next to start
@@ -3572,14 +3634,29 @@ setup_eclass_member_iterator(EquivalenceMemberIterator *iter,
iter->root = root;
iter->eclass = ec;
+#ifdef USE_ASSERT_CHECKING
+ /*
+ * When assert checking is enabled, we always create indexes to check the
+ * result of the iteration in validate_eclass_member_iterator().
+ */
+ iter->matching_ems = get_ecmember_indexes(root, ec, relids,
+ with_children,
+ with_norel_members);
+#else
if (iter->use_index)
iter->matching_ems = get_ecmember_indexes(root, ec, relids,
with_children,
with_norel_members);
else
iter->matching_ems = NULL;
+#endif
iter->current_index = -1;
+
+#ifdef USE_ASSERT_CHECKING
+ /* Assert that the results are the same with and without indexes */
+ validate_eclass_member_iterator(iter, eclass_member_iterator_next);
+#endif
}
/*
@@ -3605,14 +3682,29 @@ setup_eclass_member_strict_iterator(EquivalenceMemberIterator *iter,
iter->root = root;
iter->eclass = ec;
+#ifdef USE_ASSERT_CHECKING
+ /*
+ * When assert checking is enabled, we always create indexes to check the
+ * result of the iteration in validate_eclass_member_iterator().
+ */
+ iter->matching_ems = get_ecmember_indexes_strict(root, ec, relids,
+ with_children,
+ with_norel_members);
+#else
if (iter->use_index)
iter->matching_ems = get_ecmember_indexes_strict(root, ec, relids,
with_children,
with_norel_members);
else
iter->matching_ems = NULL;
+#endif
iter->current_index = -1;
+
+#ifdef USE_ASSERT_CHECKING
+ /* Assert that the results are the same with and without indexes */
+ validate_eclass_member_iterator(iter, eclass_member_iterator_strict_next);
+#endif
}
/*
--
2.35.3.windows.1