diff options
Diffstat (limited to 'src/backend/statistics/mcv.c')
-rw-r--r-- | src/backend/statistics/mcv.c | 51 |
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; |