aboutsummaryrefslogtreecommitdiff
path: root/src/backend/statistics/mcv.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/statistics/mcv.c')
-rw-r--r--src/backend/statistics/mcv.c51
1 files changed, 34 insertions, 17 deletions
diff --git a/src/backend/statistics/mcv.c b/src/backend/statistics/mcv.c
index 35bb21c43ea..0be53a89f9c 100644
--- a/src/backend/statistics/mcv.c
+++ b/src/backend/statistics/mcv.c
@@ -1532,13 +1532,13 @@ pg_mcv_list_send(PG_FUNCTION_ARGS)
/*
* match the attribute/expression to a dimension of the statistic
*
- * Match the attribute/expression to statistics dimension. Optionally
- * determine the collation.
+ * Returns the zero-based index of the matching statistics dimension.
+ * Optionally determines the collation.
*/
static int
mcv_match_expression(Node *expr, Bitmapset *keys, List *exprs, Oid *collid)
{
- int idx = -1;
+ int idx;
if (IsA(expr, Var))
{
@@ -1550,20 +1550,19 @@ mcv_match_expression(Node *expr, Bitmapset *keys, List *exprs, Oid *collid)
idx = bms_member_index(keys, var->varattno);
- /* make sure the index is valid */
- Assert((idx >= 0) && (idx <= bms_num_members(keys)));
+ if (idx < 0)
+ elog(ERROR, "variable not found in statistics object");
}
else
{
+ /* expression - lookup in stats expressions */
ListCell *lc;
- /* expressions are stored after the simple columns */
- idx = bms_num_members(keys);
-
if (collid)
*collid = exprCollation(expr);
- /* expression - lookup in stats expressions */
+ /* expressions are stored after the simple columns */
+ idx = bms_num_members(keys);
foreach(lc, exprs)
{
Node *stat_expr = (Node *) lfirst(lc);
@@ -1574,13 +1573,10 @@ mcv_match_expression(Node *expr, Bitmapset *keys, List *exprs, Oid *collid)
idx++;
}
- /* make sure the index is valid */
- Assert((idx >= bms_num_members(keys)) &&
- (idx <= bms_num_members(keys) + list_length(exprs)));
+ if (lc == NULL)
+ elog(ERROR, "expression not found in statistics object");
}
- Assert((idx >= 0) && (idx < bms_num_members(keys) + list_length(exprs)));
-
return idx;
}
@@ -1659,8 +1655,6 @@ mcv_get_match_bitmap(PlannerInfo *root, List *clauses,
/* match the attribute/expression to a dimension of the statistic */
idx = mcv_match_expression(clause_expr, keys, exprs, &collid);
- Assert((idx >= 0) && (idx < bms_num_members(keys) + list_length(exprs)));
-
/*
* Walk through the MCV items and evaluate the current clause. We
* can skip items that were already ruled out, and terminate if
@@ -1944,7 +1938,30 @@ mcv_get_match_bitmap(PlannerInfo *root, List *clauses,
}
}
else
- elog(ERROR, "unknown clause type: %d", clause->type);
+ {
+ /* Otherwise, it must be a bare boolean-returning expression */
+ int idx;
+
+ /* match the expression to a dimension of the statistic */
+ idx = mcv_match_expression(clause, keys, exprs, NULL);
+
+ /*
+ * Walk through the MCV items and evaluate the current clause. We
+ * can skip items that were already ruled out, and terminate if
+ * there are no remaining MCV items that might possibly match.
+ */
+ for (i = 0; i < mcvlist->nitems; i++)
+ {
+ bool match;
+ MCVItem *item = &mcvlist->items[i];
+
+ /* "match" just means it's bool TRUE */
+ match = !item->isnull[idx] && DatumGetBool(item->values[idx]);
+
+ /* now, update the match bitmap, depending on OR/AND type */
+ matches[i] = RESULT_MERGE(matches[i], is_or, match);
+ }
+ }
}
return matches;