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);