aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/array_selfuncs.c15
-rw-r--r--src/backend/utils/adt/selfuncs.c22
2 files changed, 26 insertions, 11 deletions
diff --git a/src/backend/utils/adt/array_selfuncs.c b/src/backend/utils/adt/array_selfuncs.c
index e35edf8ec84..20eb358a620 100644
--- a/src/backend/utils/adt/array_selfuncs.c
+++ b/src/backend/utils/adt/array_selfuncs.c
@@ -68,11 +68,13 @@ static int float_compare_desc(const void *key1, const void *key2);
* scalararraysel_containment
* Estimate selectivity of ScalarArrayOpExpr via array containment.
*
- * scalararraysel() has already verified that the operator of a
- * ScalarArrayOpExpr is the array element type's default equality or
- * inequality operator. If we have const =/<> ANY/ALL (array_var)
- * then we can estimate the selectivity as though this were an array
- * containment operator, array_var op ARRAY[const].
+ * If we have const =/<> ANY/ALL (array_var) then we can estimate the
+ * selectivity as though this were an array containment operator,
+ * array_var op ARRAY[const].
+ *
+ * scalararraysel() has already verified that the ScalarArrayOpExpr's operator
+ * is the array element type's default equality or inequality operator, and
+ * has aggressively simplified both inputs to constants.
*
* Returns selectivity (0..1), or -1 if we fail to estimate selectivity.
*/
@@ -99,9 +101,8 @@ scalararraysel_containment(PlannerInfo *root,
}
/*
- * Aggressively reduce leftop to a constant, if possible.
+ * leftop must be a constant, else punt.
*/
- leftop = estimate_expression_value(root, leftop);
if (!IsA(leftop, Const))
{
ReleaseVariableStats(vardata);
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index d525ca4546b..f70bdaa328f 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -1735,6 +1735,10 @@ scalararraysel(PlannerInfo *root,
leftop = (Node *) linitial(clause->args);
rightop = (Node *) lsecond(clause->args);
+ /* aggressively reduce both sides to constants */
+ leftop = estimate_expression_value(root, leftop);
+ rightop = estimate_expression_value(root, rightop);
+
/* get nominal (after relabeling) element type of rightop */
nominal_element_type = get_base_element_type(exprType(rightop));
if (!OidIsValid(nominal_element_type))
@@ -6856,7 +6860,8 @@ gincost_pattern(IndexOptInfo *index, int indexcol,
* appropriately. If the query is unsatisfiable, return false.
*/
static bool
-gincost_opexpr(IndexOptInfo *index, OpExpr *clause, GinQualCounts *counts)
+gincost_opexpr(PlannerInfo *root, IndexOptInfo *index, OpExpr *clause,
+ GinQualCounts *counts)
{
Node *leftop = get_leftop((Expr *) clause);
Node *rightop = get_rightop((Expr *) clause);
@@ -6880,6 +6885,9 @@ gincost_opexpr(IndexOptInfo *index, OpExpr *clause, GinQualCounts *counts)
operand = NULL; /* keep compiler quiet */
}
+ /* aggressively reduce to a constant, and look through relabeling */
+ operand = estimate_expression_value(root, operand);
+
if (IsA(operand, RelabelType))
operand = (Node *) ((RelabelType *) operand)->arg;
@@ -6918,7 +6926,8 @@ gincost_opexpr(IndexOptInfo *index, OpExpr *clause, GinQualCounts *counts)
* by N, causing gincostestimate to scale up its estimates accordingly.
*/
static bool
-gincost_scalararrayopexpr(IndexOptInfo *index, ScalarArrayOpExpr *clause,
+gincost_scalararrayopexpr(PlannerInfo *root,
+ IndexOptInfo *index, ScalarArrayOpExpr *clause,
double numIndexEntries,
GinQualCounts *counts)
{
@@ -6943,6 +6952,9 @@ gincost_scalararrayopexpr(IndexOptInfo *index, ScalarArrayOpExpr *clause,
if ((indexcol = find_index_column(leftop, index)) < 0)
elog(ERROR, "could not match index to operand");
+ /* aggressively reduce to a constant, and look through relabeling */
+ rightop = estimate_expression_value(root, rightop);
+
if (IsA(rightop, RelabelType))
rightop = (Node *) ((RelabelType *) rightop)->arg;
@@ -7160,7 +7172,8 @@ gincostestimate(PG_FUNCTION_ARGS)
clause = rinfo->clause;
if (IsA(clause, OpExpr))
{
- matchPossible = gincost_opexpr(index,
+ matchPossible = gincost_opexpr(root,
+ index,
(OpExpr *) clause,
&counts);
if (!matchPossible)
@@ -7168,7 +7181,8 @@ gincostestimate(PG_FUNCTION_ARGS)
}
else if (IsA(clause, ScalarArrayOpExpr))
{
- matchPossible = gincost_scalararrayopexpr(index,
+ matchPossible = gincost_scalararrayopexpr(root,
+ index,
(ScalarArrayOpExpr *) clause,
numEntries,
&counts);