From 5fe6dc44963ad55ed7800919fa3db73049c45d30 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 26 Aug 2008 02:16:39 +0000 Subject: [PATCH] Teach eval_const_expressions() to simplify an ArrayCoerceExpr to a constant when its input is constant and the element coercion function is immutable (or nonexistent, ie, binary-coercible case). This is an oversight in the 8.3 implementation of ArrayCoerceExpr, and its result is that certain cases involving IN or NOT IN with constants don't get optimized as they should be. Per experimentation with an example from Ow Mun Heng. --- src/backend/optimizer/util/clauses.c | 35 ++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index 46b8852e79..0934469706 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -2359,6 +2359,41 @@ eval_const_expressions_mutator(Node *node, newexpr->coerceformat = expr->coerceformat; return (Node *) newexpr; } + if (IsA(node, ArrayCoerceExpr)) + { + ArrayCoerceExpr *expr = (ArrayCoerceExpr *) node; + Expr *arg; + ArrayCoerceExpr *newexpr; + + /* + * Reduce constants in the ArrayCoerceExpr's argument, then build + * a new ArrayCoerceExpr. + */ + arg = (Expr *) eval_const_expressions_mutator((Node *) expr->arg, + context); + + newexpr = makeNode(ArrayCoerceExpr); + newexpr->arg = arg; + newexpr->elemfuncid = expr->elemfuncid; + newexpr->resulttype = expr->resulttype; + newexpr->resulttypmod = expr->resulttypmod; + newexpr->isExplicit = expr->isExplicit; + newexpr->coerceformat = expr->coerceformat; + + /* + * If constant argument and it's a binary-coercible or immutable + * conversion, we can simplify it to a constant. + */ + if (arg && IsA(arg, Const) && + (!OidIsValid(newexpr->elemfuncid) || + func_volatile(newexpr->elemfuncid) == PROVOLATILE_IMMUTABLE)) + return (Node *) evaluate_expr((Expr *) newexpr, + newexpr->resulttype, + newexpr->resulttypmod); + + /* Else we must return the partially-simplified node */ + return (Node *) newexpr; + } if (IsA(node, CaseExpr)) { /*---------- -- 2.39.5