@@ -1579,15 +1579,15 @@ mcv_get_match_bitmap(PlannerInfo *root, List *clauses,
1579
1579
OpExpr * expr = (OpExpr * ) clause ;
1580
1580
FmgrInfo opproc ;
1581
1581
1582
- /* valid only after examine_opclause_expression returns true */
1582
+ /* valid only after examine_clause_args returns true */
1583
1583
Var * var ;
1584
1584
Const * cst ;
1585
1585
bool varonleft ;
1586
1586
1587
1587
fmgr_info (get_opcode (expr -> opno ), & opproc );
1588
1588
1589
1589
/* extract the var and const from the expression */
1590
- if (examine_opclause_expression (expr , & var , & cst , & varonleft ))
1590
+ if (examine_clause_args (expr -> args , & var , & cst , & varonleft ))
1591
1591
{
1592
1592
int idx ;
1593
1593
@@ -1652,6 +1652,113 @@ mcv_get_match_bitmap(PlannerInfo *root, List *clauses,
1652
1652
}
1653
1653
}
1654
1654
}
1655
+ else if (IsA (clause , ScalarArrayOpExpr ))
1656
+ {
1657
+ ScalarArrayOpExpr * expr = (ScalarArrayOpExpr * ) clause ;
1658
+ FmgrInfo opproc ;
1659
+
1660
+ /* valid only after examine_clause_args returns true */
1661
+ Var * var ;
1662
+ Const * cst ;
1663
+ bool varonleft ;
1664
+
1665
+ fmgr_info (get_opcode (expr -> opno ), & opproc );
1666
+
1667
+ /* extract the var and const from the expression */
1668
+ if (examine_clause_args (expr -> args , & var , & cst , & varonleft ))
1669
+ {
1670
+ int idx ;
1671
+
1672
+ ArrayType * arrayval ;
1673
+ int16 elmlen ;
1674
+ bool elmbyval ;
1675
+ char elmalign ;
1676
+ int num_elems ;
1677
+ Datum * elem_values ;
1678
+ bool * elem_nulls ;
1679
+
1680
+ /* ScalarArrayOpExpr has the Var always on the left */
1681
+ Assert (varonleft );
1682
+
1683
+ if (!cst -> constisnull )
1684
+ {
1685
+ arrayval = DatumGetArrayTypeP (cst -> constvalue );
1686
+ get_typlenbyvalalign (ARR_ELEMTYPE (arrayval ),
1687
+ & elmlen , & elmbyval , & elmalign );
1688
+ deconstruct_array (arrayval ,
1689
+ ARR_ELEMTYPE (arrayval ),
1690
+ elmlen , elmbyval , elmalign ,
1691
+ & elem_values , & elem_nulls , & num_elems );
1692
+ }
1693
+
1694
+ /* match the attribute to a dimension of the statistic */
1695
+ idx = bms_member_index (keys , var -> varattno );
1696
+
1697
+ /*
1698
+ * Walk through the MCV items and evaluate the current clause.
1699
+ * We can skip items that were already ruled out, and
1700
+ * terminate if there are no remaining MCV items that might
1701
+ * possibly match.
1702
+ */
1703
+ for (i = 0 ; i < mcvlist -> nitems ; i ++ )
1704
+ {
1705
+ int j ;
1706
+ bool match = (expr -> useOr ? false : true);
1707
+ MCVItem * item = & mcvlist -> items [i ];
1708
+
1709
+ /*
1710
+ * When the MCV item or the Const value is NULL we can treat
1711
+ * this as a mismatch. We must not call the operator because
1712
+ * of strictness.
1713
+ */
1714
+ if (item -> isnull [idx ] || cst -> constisnull )
1715
+ {
1716
+ matches [i ] = RESULT_MERGE (matches [i ], is_or , false);
1717
+ continue ;
1718
+ }
1719
+
1720
+ /*
1721
+ * Skip MCV items that can't change result in the bitmap.
1722
+ * Once the value gets false for AND-lists, or true for
1723
+ * OR-lists, we don't need to look at more clauses.
1724
+ */
1725
+ if (RESULT_IS_FINAL (matches [i ], is_or ))
1726
+ continue ;
1727
+
1728
+ for (j = 0 ; j < num_elems ; j ++ )
1729
+ {
1730
+ Datum elem_value = elem_values [j ];
1731
+ bool elem_isnull = elem_nulls [j ];
1732
+ bool elem_match ;
1733
+
1734
+ /* NULL values always evaluate as not matching. */
1735
+ if (elem_isnull )
1736
+ {
1737
+ match = RESULT_MERGE (match , expr -> useOr , false);
1738
+ continue ;
1739
+ }
1740
+
1741
+ /*
1742
+ * Stop evaluating the array elements once we reach
1743
+ * match value that can't change - ALL() is the same
1744
+ * as AND-list, ANY() is the same as OR-list.
1745
+ */
1746
+ if (RESULT_IS_FINAL (match , expr -> useOr ))
1747
+ break ;
1748
+
1749
+ elem_match = DatumGetBool (FunctionCall2Coll (& opproc ,
1750
+ var -> varcollid ,
1751
+ item -> values [idx ],
1752
+ elem_value ));
1753
+
1754
+ match = RESULT_MERGE (match , expr -> useOr , elem_match );
1755
+ }
1756
+
1757
+ /* update the match bitmap with the result */
1758
+ matches [i ] = RESULT_MERGE (matches [i ], is_or , match );
1759
+ }
1760
+ }
1761
+ }
1655
1762
else if (IsA (clause , NullTest ))
1656
1763
{
1657
1764
NullTest * expr = (NullTest * ) clause ;
0 commit comments