Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 4f5760d

Browse filesBrowse files
committed
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. Dean Rasheed, reviewed by Tomas Vondra. Discussion: https://postgr.es/m/CAEZATCW=J65GUFm50RcPv-iASnS2mTXQbr=CfBvWRVhFLJ_fWA@mail.gmail.com
1 parent 88b0898 commit 4f5760d
Copy full SHA for 4f5760d

File tree

Expand file treeCollapse file tree

3 files changed

+48
-2
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+48
-2
lines changed

‎src/backend/optimizer/path/clausesel.c

Copy file name to clipboardExpand all lines: src/backend/optimizer/path/clausesel.c
+21Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,28 @@ find_single_rel_for_clauses(PlannerInfo *root, List *clauses)
538538
* However, currently the extended-stats machinery won't do anything
539539
* with non-RestrictInfo clauses anyway, so there's no point in
540540
* spending extra cycles; just fail if that's what we have.
541+
*
542+
* An exception to that rule is if we have a bare BoolExpr AND clause.
543+
* We treat this as a special case because the restrictinfo machinery
544+
* doesn't build RestrictInfos on top of AND clauses.
541545
*/
546+
if (is_andclause(rinfo))
547+
{
548+
RelOptInfo *rel;
549+
550+
rel = find_single_rel_for_clauses(root,
551+
((BoolExpr *) rinfo)->args);
552+
553+
if (rel == NULL)
554+
return NULL;
555+
if (lastrelid == 0)
556+
lastrelid = rel->relid;
557+
else if (rel->relid != lastrelid)
558+
return NULL;
559+
560+
continue;
561+
}
562+
542563
if (!IsA(rinfo, RestrictInfo))
543564
return NULL;
544565

‎src/backend/statistics/extended_stats.c

Copy file name to clipboardExpand all lines: src/backend/statistics/extended_stats.c
+25Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,6 +1174,31 @@ statext_is_compatible_clause(PlannerInfo *root, Node *clause, Index relid,
11741174
RestrictInfo *rinfo = (RestrictInfo *) clause;
11751175
Oid userid;
11761176

1177+
/*
1178+
* Special-case handling for bare BoolExpr AND clauses, because the
1179+
* restrictinfo machinery doesn't build RestrictInfos on top of AND
1180+
* clauses.
1181+
*/
1182+
if (is_andclause(clause))
1183+
{
1184+
BoolExpr *expr = (BoolExpr *) clause;
1185+
ListCell *lc;
1186+
1187+
/*
1188+
* Check that each sub-clause is compatible. We expect these to be
1189+
* RestrictInfos.
1190+
*/
1191+
foreach(lc, expr->args)
1192+
{
1193+
if (!statext_is_compatible_clause(root, (Node *) lfirst(lc),
1194+
relid, attnums))
1195+
return false;
1196+
}
1197+
1198+
return true;
1199+
}
1200+
1201+
/* Otherwise it must be a RestrictInfo. */
11771202
if (!IsA(rinfo, RestrictInfo))
11781203
return false;
11791204

‎src/test/regress/expected/stats_ext.out

Copy file name to clipboardExpand all lines: src/test/regress/expected/stats_ext.out
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,13 +1594,13 @@ SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0
15941594
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)');
15951595
estimated | actual
15961596
-----------+--------
1597-
300 | 306
1597+
306 | 306
15981598
(1 row)
15991599

16001600
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)');
16011601
estimated | actual
16021602
-----------+--------
1603-
306 | 102
1603+
108 | 102
16041604
(1 row)
16051605

16061606
DROP TABLE mcv_lists_partial;

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.