Partially undo commit 94da73281.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 5 Aug 2022 19:57:46 +0000 (15:57 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 5 Aug 2022 19:57:46 +0000 (15:57 -0400)
On closer inspection, mcv.c isn't as broken for ScalarArrayOpExpr
as I thought.  The Var-on-right issue is real enough, but actually
it does cope fine with a NULL array constant --- I was misled by
an XXX comment suggesting it didn't.  Undo that part of the code
change, and replace the XXX comment with something less misleading.

src/backend/statistics/extended_stats.c
src/backend/statistics/mcv.c

index 5e8bdc4cf1bfbe14dc83c4d254edfac8333f93e7..ee05e230e060ea8c2904b8f1f960814fda886aad 100644 (file)
@@ -1452,7 +1452,6 @@ statext_is_compatible_clause_internal(PlannerInfo *root, Node *clause,
        RangeTblEntry *rte = root->simple_rte_array[relid];
        ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) clause;
        Node       *clause_expr;
-       Const      *cst;
        bool        expronleft;
 
        /* Only expressions with two arguments are considered compatible. */
@@ -1460,11 +1459,11 @@ statext_is_compatible_clause_internal(PlannerInfo *root, Node *clause,
            return false;
 
        /* Check if the expression has the right shape (one Var, one Const) */
-       if (!examine_opclause_args(expr->args, &clause_expr, &cst, &expronleft))
+       if (!examine_opclause_args(expr->args, &clause_expr, NULL, &expronleft))
            return false;
 
-       /* We only support Var on left and non-null array constants */
-       if (!expronleft || cst->constisnull)
+       /* We only support Var on left, Const on right */
+       if (!expronleft)
            return false;
 
        /*
index 0be53a89f9cef32bb2c0e7b6cf9fece109d213b3..6d9a098479d3ff55db1ac3a4632bb4e980c29f94 100644 (file)
@@ -1740,17 +1740,24 @@ mcv_get_match_bitmap(PlannerInfo *root, List *clauses,
            if (!examine_opclause_args(expr->args, &clause_expr, &cst, &expronleft))
                elog(ERROR, "incompatible clause");
 
-           /* We expect Var on left and non-null constant on right */
-           if (!expronleft || cst->constisnull)
+           /* We expect Var on left */
+           if (!expronleft)
                elog(ERROR, "incompatible clause");
 
-           arrayval = DatumGetArrayTypeP(cst->constvalue);
-           get_typlenbyvalalign(ARR_ELEMTYPE(arrayval),
-                                &elmlen, &elmbyval, &elmalign);
-           deconstruct_array(arrayval,
-                             ARR_ELEMTYPE(arrayval),
-                             elmlen, elmbyval, elmalign,
-                             &elem_values, &elem_nulls, &num_elems);
+           /*
+            * Deconstruct the array constant, unless it's NULL (we'll cover
+            * that case below)
+            */
+           if (!cst->constisnull)
+           {
+               arrayval = DatumGetArrayTypeP(cst->constvalue);
+               get_typlenbyvalalign(ARR_ELEMTYPE(arrayval),
+                                    &elmlen, &elmbyval, &elmalign);
+               deconstruct_array(arrayval,
+                                 ARR_ELEMTYPE(arrayval),
+                                 elmlen, elmbyval, elmalign,
+                                 &elem_values, &elem_nulls, &num_elems);
+           }
 
            /* match the attribute/expression to a dimension of the statistic */
            idx = mcv_match_expression(clause_expr, keys, exprs, &collid);