From ca77b087725d1c670250538c017f88150b3df868 Mon Sep 17 00:00:00 2001 From: Tomas Vondra Date: Wed, 4 Mar 2020 15:55:46 +0100 Subject: [PATCH 01/11] Apply functional dependencies to ScalarArrayOpExpr Until now functional dependencies handled only plain equality clauses. We can apply them to IN some cases of ANY, which can be translated to an equality. --- src/backend/statistics/dependencies.c | 28 +++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/backend/statistics/dependencies.c b/src/backend/statistics/dependencies.c index e2f6c5bb97..36941b8535 100644 --- a/src/backend/statistics/dependencies.c +++ b/src/backend/statistics/dependencies.c @@ -801,6 +801,34 @@ dependency_is_compatible_clause(Node *clause, Index relid, AttrNumber *attnum) /* OK to proceed with checking "var" */ } + else if (IsA(rinfo->clause, ScalarArrayOpExpr)) + { + /* If it's an opclause, check for Var IN Const. */ + ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) rinfo->clause; + + /* Only expressions with two arguments are candidates. */ + if (list_length(expr->args) != 2) + return false; + + /* Make sure non-selected argument is a pseudoconstant. */ + if (is_pseudo_constant_clause(lsecond(expr->args))) + var = linitial(expr->args); + else if (is_pseudo_constant_clause(linitial(expr->args))) + var = lsecond(expr->args); + else + return false; + + /* + * If it's not an "=" operator, just ignore the clause, as it's not + * compatible with functional dependencies. The operator is identified + * simply by looking at which function it uses to estimate selectivity. + * That's a bit strange, but it's what other similar places do. + */ + if (get_oprrest(expr->opno) != F_EQSEL) + return false; + + /* OK to proceed with checking "var" */ + } else if (is_notclause(rinfo->clause)) { /* -- 2.21.1