From a296c9876e510ed27056a1acee24afb1ed90e146 Mon Sep 17 00:00:00 2001 From: Tomas Vondra Date: Mon, 17 Jun 2024 15:13:21 +0200 Subject: [PATCH v20240617 11/56] use the pre-calculated RestrictInfo->left|right_relids It should has better performance than pull_varnos and easier to understand. --- src/backend/statistics/extended_stats.c | 41 ++++++------------------- 1 file changed, 9 insertions(+), 32 deletions(-) diff --git a/src/backend/statistics/extended_stats.c b/src/backend/statistics/extended_stats.c index f6f416ac213..98d579578c0 100644 --- a/src/backend/statistics/extended_stats.c +++ b/src/backend/statistics/extended_stats.c @@ -2831,10 +2831,10 @@ statext_determine_join_restrictions(PlannerInfo *root, RelOptInfo *rel, static bool statext_is_supported_join_clause(PlannerInfo *root, Node *clause) { - Oid oprsel; - RestrictInfo *rinfo; - OpExpr *opclause; - ListCell *lc; + Oid oprsel; + RestrictInfo *rinfo; + OpExpr *opclause; + int left_relid, right_relid; /* * XXX isn't this comment stale after removal of varRelid? @@ -2852,10 +2852,6 @@ statext_is_supported_join_clause(PlannerInfo *root, Node *clause) rinfo = (RestrictInfo *) clause; clause = (Node *) rinfo->clause; - /* is it referencing multiple relations? */ - if (bms_membership(rinfo->clause_relids) != BMS_MULTIPLE) - return false; - /* we only support simple operator clauses for now */ if (!is_opclause(clause)) return false; @@ -2878,8 +2874,6 @@ statext_is_supported_join_clause(PlannerInfo *root, Node *clause) * which is still technically an opclause, but we can't match it to * extended statistics in a simple way. * - * XXX This also means we require rinfo->clause_relids to have 2 rels. - * * XXX Also check it's not expression on system attributes, which we don't * allow in extended statistics. * @@ -2888,30 +2882,13 @@ statext_is_supported_join_clause(PlannerInfo *root, Node *clause) * something like that. We could do "cartesian product" of the MCV stats * and restrict it using this condition. */ - foreach(lc, opclause->args) - { - Bitmapset *varnos = NULL; - Node *expr = (Node *) lfirst(lc); - varnos = pull_varnos(root, expr); - - /* - * No argument should reference more than just one relation. - * - * This effectively means each side references just two relations. If - * there's no relation on one side, it's a Const, and the other side - * has to be either Const or Expr with a single rel. In which case it - * can't be a join clause. - */ - if (bms_num_members(varnos) > 1) - return false; + if (!bms_get_singleton_member(rinfo->left_relids, &left_relid) || + !bms_get_singleton_member(rinfo->right_relids, &right_relid)) + return false; - /* - * XXX Maybe check that both relations have extended statistics (no - * point in considering the clause as useful without it). But we'll do - * that check later anyway, so keep this cheap. - */ - } + if (left_relid == right_relid) + return false; return true; } -- 2.45.2