0002-Improve-estimation-of-ANDs-under-ORs-using-extended-.patch
application/octet-stream
Filename: 0002-Improve-estimation-of-ANDs-under-ORs-using-extended-.patch
Type: application/octet-stream
Part: 1
Patch
Format: format-patch
Series: patch 0002
Subject: Improve estimation of ANDs under ORs using extended statistics.
| File | + | − |
|---|---|---|
| src/backend/optimizer/path/clausesel.c | 21 | 0 |
| src/backend/statistics/extended_stats.c | 25 | 0 |
| src/test/regress/expected/stats_ext.out | 2 | 2 |
From 21634e391305a6e5f029068af62ebf6baf450037 Mon Sep 17 00:00:00 2001
From: Dean Rasheed <dean.a.rasheed@gmail.com>
Date: Mon, 7 Dec 2020 14:59:34 +0000
Subject: [PATCH 2/2] Improve estimation of ANDs under ORs using extended
statistics.
Formerly, extended statistics only handled clauses that were
RestrictInfos. However, the restrictinfo machinery doesn't create
sub-AND RestrictInfos for AND clauses underneath OR clauses.
Therefore teach extended statistics to handle bare AND clauses,
looking for compatible RestrictInfo clauses underneath them.
---
src/backend/optimizer/path/clausesel.c | 21 +++++++++++++++++++++
src/backend/statistics/extended_stats.c | 25 +++++++++++++++++++++++++
src/test/regress/expected/stats_ext.out | 4 ++--
3 files changed, 48 insertions(+), 2 deletions(-)
diff --git a/src/backend/optimizer/path/clausesel.c b/src/backend/optimizer/path/clausesel.c
index b88b29ec23..a7e535c27f 100644
--- a/src/backend/optimizer/path/clausesel.c
+++ b/src/backend/optimizer/path/clausesel.c
@@ -538,7 +538,28 @@ find_single_rel_for_clauses(PlannerInfo *root, List *clauses)
* However, currently the extended-stats machinery won't do anything
* with non-RestrictInfo clauses anyway, so there's no point in
* spending extra cycles; just fail if that's what we have.
+ *
+ * An exception to that rule is if we have a bare BoolExpr AND clause.
+ * We treat this as a special case because the restrictinfo machinery
+ * doesn't build RestrictInfos on top of AND clauses.
*/
+ if (is_andclause(rinfo))
+ {
+ RelOptInfo *rel;
+
+ rel = find_single_rel_for_clauses(root,
+ ((BoolExpr *) rinfo)->args);
+
+ if (rel == NULL)
+ return NULL;
+ if (lastrelid == 0)
+ lastrelid = rel->relid;
+ else if (rel->relid != lastrelid)
+ return NULL;
+
+ continue;
+ }
+
if (!IsA(rinfo, RestrictInfo))
return NULL;
diff --git a/src/backend/statistics/extended_stats.c b/src/backend/statistics/extended_stats.c
index b6bd12c229..9745a2f248 100644
--- a/src/backend/statistics/extended_stats.c
+++ b/src/backend/statistics/extended_stats.c
@@ -1174,6 +1174,31 @@ statext_is_compatible_clause(PlannerInfo *root, Node *clause, Index relid,
RestrictInfo *rinfo = (RestrictInfo *) clause;
Oid userid;
+ /*
+ * Special-case handling for bare BoolExpr AND clauses, because the
+ * restrictinfo machinery doesn't build RestrictInfos on top of AND
+ * clauses.
+ */
+ if (is_andclause(clause))
+ {
+ BoolExpr *expr = (BoolExpr *) clause;
+ ListCell *lc;
+
+ /*
+ * Check that each sub-clause is compatible. We expect these to be
+ * RestrictInfos.
+ */
+ foreach(lc, expr->args)
+ {
+ if (!statext_is_compatible_clause(root, (Node *) lfirst(lc),
+ relid, attnums))
+ return false;
+ }
+
+ return true;
+ }
+
+ /* Otherwise it must be a RestrictInfo. */
if (!IsA(rinfo, RestrictInfo))
return false;
diff --git a/src/test/regress/expected/stats_ext.out b/src/test/regress/expected/stats_ext.out
index 6e1c4f3edd..7bfeaf85f0 100644
--- a/src/test/regress/expected/stats_ext.out
+++ b/src/test/regress/expected/stats_ext.out
@@ -1594,13 +1594,13 @@ SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE (a = 0 AND b = 0 AND c = 0) OR (a = 1 AND b = 1 AND c = 1) OR (a = 2 AND b = 2 AND c = 2)');
estimated | actual
-----------+--------
- 300 | 306
+ 306 | 306
(1 row)
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE (a = 0 AND b = 0) OR (a = 0 AND c = 0) OR (b = 0 AND c = 0)');
estimated | actual
-----------+--------
- 306 | 102
+ 108 | 102
(1 row)
DROP TABLE mcv_lists_partial;
--
2.26.2