From 0fdb350cae6cd1ade5029c469a74d38cc38a0be1 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 15 May 2008 17:37:49 +0000 Subject: [PATCH] Add code to eval_const_expressions() to support const-simplification of CoerceViaIO nodes. This improves the ability of the planner to deal with cases where the node input is a constant. Per bug #4170. --- src/backend/optimizer/util/clauses.c | 67 +++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index 8665418539..ea92422279 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.258 2008/05/12 00:00:49 alvherre Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.259 2008/05/15 17:37:49 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -2106,6 +2106,71 @@ eval_const_expressions_mutator(Node *node, return (Node *) newrelabel; } } + if (IsA(node, CoerceViaIO)) + { + CoerceViaIO *expr = (CoerceViaIO *) node; + Expr *arg; + Oid outfunc; + bool outtypisvarlena; + Oid infunc; + Oid intypioparam; + Expr *simple; + CoerceViaIO *newexpr; + + /* + * Reduce constants in the CoerceViaIO's argument. + */ + arg = (Expr *) eval_const_expressions_mutator((Node *) expr->arg, + context); + + /* + * CoerceViaIO represents calling the source type's output function + * then the result type's input function. So, try to simplify it + * as though it were a stack of two such function calls. First we + * need to know what the functions are. + */ + getTypeOutputInfo(exprType((Node *) arg), &outfunc, &outtypisvarlena); + getTypeInputInfo(expr->resulttype, &infunc, &intypioparam); + + simple = simplify_function(outfunc, + CSTRINGOID, -1, + list_make1(arg), + true, context); + if (simple) /* successfully simplified output fn */ + { + /* + * Input functions may want 1 to 3 arguments. We always supply + * all three, trusting that nothing downstream will complain. + */ + List *args; + + args = list_make3(simple, + makeConst(OIDOID, -1, sizeof(Oid), + ObjectIdGetDatum(intypioparam), + false, true), + makeConst(INT4OID, -1, sizeof(int32), + Int32GetDatum(-1), + false, true)); + + simple = simplify_function(infunc, + expr->resulttype, -1, + args, + true, context); + if (simple) /* successfully simplified input fn */ + return (Node *) simple; + } + + /* + * The expression cannot be simplified any further, so build and + * return a replacement CoerceViaIO node using the possibly-simplified + * argument. + */ + newexpr = makeNode(CoerceViaIO); + newexpr->arg = arg; + newexpr->resulttype = expr->resulttype; + newexpr->coerceformat = expr->coerceformat; + return (Node *) newexpr; + } if (IsA(node, CaseExpr)) { /*---------- -- 2.11.0