summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2008-08-26 02:16:39 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2008-08-26 02:16:39 +0000
commita9ff5f07229039cbbef813b7384a35af88058f46 (patch)
treeeabc1353c11e072e317631ded2d349dae0619a88 /src
parentbc846323d3b83e992086702902548bdd71cfa4ee (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/backend/optimizer/util/clauses.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 11b6613426e..7094ed0c87c 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.254.2.2 2008/05/15 17:37:57 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.254.2.3 2008/08/26 02:16:39 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -2160,6 +2160,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))
{
/*----------