Skip to content

Commit 0fdb350

Browse files
committed
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.
1 parent 93c701e commit 0fdb350

File tree

1 file changed

+66
-1
lines changed

1 file changed

+66
-1
lines changed

src/backend/optimizer/util/clauses.c

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.258 2008/05/12 00:00:49 alvherre Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.259 2008/05/15 17:37:49 tgl Exp $
1212
*
1313
* HISTORY
1414
* AUTHOR DATE MAJOR EVENT
@@ -2106,6 +2106,71 @@ eval_const_expressions_mutator(Node *node,
21062106
return (Node *) newrelabel;
21072107
}
21082108
}
2109+
if (IsA(node, CoerceViaIO))
2110+
{
2111+
CoerceViaIO *expr = (CoerceViaIO *) node;
2112+
Expr *arg;
2113+
Oid outfunc;
2114+
bool outtypisvarlena;
2115+
Oid infunc;
2116+
Oid intypioparam;
2117+
Expr *simple;
2118+
CoerceViaIO *newexpr;
2119+
2120+
/*
2121+
* Reduce constants in the CoerceViaIO's argument.
2122+
*/
2123+
arg = (Expr *) eval_const_expressions_mutator((Node *) expr->arg,
2124+
context);
2125+
2126+
/*
2127+
* CoerceViaIO represents calling the source type's output function
2128+
* then the result type's input function. So, try to simplify it
2129+
* as though it were a stack of two such function calls. First we
2130+
* need to know what the functions are.
2131+
*/
2132+
getTypeOutputInfo(exprType((Node *) arg), &outfunc, &outtypisvarlena);
2133+
getTypeInputInfo(expr->resulttype, &infunc, &intypioparam);
2134+
2135+
simple = simplify_function(outfunc,
2136+
CSTRINGOID, -1,
2137+
list_make1(arg),
2138+
true, context);
2139+
if (simple) /* successfully simplified output fn */
2140+
{
2141+
/*
2142+
* Input functions may want 1 to 3 arguments. We always supply
2143+
* all three, trusting that nothing downstream will complain.
2144+
*/
2145+
List *args;
2146+
2147+
args = list_make3(simple,
2148+
makeConst(OIDOID, -1, sizeof(Oid),
2149+
ObjectIdGetDatum(intypioparam),
2150+
false, true),
2151+
makeConst(INT4OID, -1, sizeof(int32),
2152+
Int32GetDatum(-1),
2153+
false, true));
2154+
2155+
simple = simplify_function(infunc,
2156+
expr->resulttype, -1,
2157+
args,
2158+
true, context);
2159+
if (simple) /* successfully simplified input fn */
2160+
return (Node *) simple;
2161+
}
2162+
2163+
/*
2164+
* The expression cannot be simplified any further, so build and
2165+
* return a replacement CoerceViaIO node using the possibly-simplified
2166+
* argument.
2167+
*/
2168+
newexpr = makeNode(CoerceViaIO);
2169+
newexpr->arg = arg;
2170+
newexpr->resulttype = expr->resulttype;
2171+
newexpr->coerceformat = expr->coerceformat;
2172+
return (Node *) newexpr;
2173+
}
21092174
if (IsA(node, CaseExpr))
21102175
{
21112176
/*----------

0 commit comments

Comments
 (0)