@@ -106,9 +106,9 @@ static List *simplify_and_arguments(List *args,
106106eval_const_expressions_context * context ,
107107bool * haveNull ,bool * forceFalse );
108108static Node * simplify_boolean_equality (Oid opno ,List * args );
109- static Expr * simplify_function (Oid funcid ,
110- Oid result_type ,int32 result_typmod ,
111- Oid result_collid , Oid input_collid ,List * * args ,
109+ static Expr * simplify_function (Expr * oldexpr , Oid funcid ,
110+ Oid result_type ,int32 result_typmod ,Oid result_collid ,
111+ Oid input_collid ,List * * args ,
112112bool has_named_args ,
113113bool allow_inline ,
114114eval_const_expressions_context * context );
@@ -2223,7 +2223,8 @@ eval_const_expressions_mutator(Node *node,
22232223 * FuncExpr, but not when the node is recognizably a length coercion;
22242224 * we want to preserve the typmod in the eventual Const if so.
22252225 */
2226- simple = simplify_function (expr -> funcid ,
2226+ simple = simplify_function ((Expr * )expr ,
2227+ expr -> funcid ,
22272228expr -> funcresulttype ,exprTypmod (node ),
22282229expr -> funccollid ,
22292230expr -> inputcollid ,
@@ -2275,7 +2276,8 @@ eval_const_expressions_mutator(Node *node,
22752276 * Code for op/func reduction is pretty bulky, so split it out as a
22762277 * separate function.
22772278 */
2278- simple = simplify_function (expr -> opfuncid ,
2279+ simple = simplify_function ((Expr * )expr ,
2280+ expr -> opfuncid ,
22792281expr -> opresulttype ,-1 ,
22802282expr -> opcollid ,
22812283expr -> inputcollid ,
@@ -2372,7 +2374,8 @@ eval_const_expressions_mutator(Node *node,
23722374 * Code for op/func reduction is pretty bulky, so split it out as
23732375 * a separate function.
23742376 */
2375- simple = simplify_function (expr -> opfuncid ,
2377+ simple = simplify_function ((Expr * )expr ,
2378+ expr -> opfuncid ,
23762379expr -> opresulttype ,-1 ,
23772380expr -> opcollid ,
23782381expr -> inputcollid ,
@@ -2561,7 +2564,8 @@ eval_const_expressions_mutator(Node *node,
25612564getTypeOutputInfo (exprType ((Node * )arg ),& outfunc ,& outtypisvarlena );
25622565getTypeInputInfo (expr -> resulttype ,& infunc ,& intypioparam );
25632566
2564- simple = simplify_function (outfunc ,
2567+ simple = simplify_function (NULL ,
2568+ outfunc ,
25652569CSTRINGOID ,-1 ,
25662570InvalidOid ,
25672571InvalidOid ,
@@ -2581,7 +2585,8 @@ eval_const_expressions_mutator(Node *node,
25812585Int32GetDatum (-1 ),
25822586 false, true));
25832587
2584- simple = simplify_function (infunc ,
2588+ simple = simplify_function (NULL ,
2589+ infunc ,
25852590expr -> resulttype ,-1 ,
25862591expr -> resultcollid ,
25872592InvalidOid ,
@@ -3417,11 +3422,15 @@ simplify_boolean_equality(Oid opno, List *args)
34173422 * Subroutine for eval_const_expressions: try to simplify a function call
34183423 * (which might originally have been an operator; we don't care)
34193424 *
3420- * Inputs are the function OID, actual result type OID (which is needed for
3421- * polymorphic functions), result typmod, result collation,
3422- * the input collation to use for the function,
3423- * the pre-simplified argument list, and some flags;
3424- * also the context data for eval_const_expressions.
3425+ * Inputs are the original expression (can be NULL), function OID, actual
3426+ * result type OID (which is needed for polymorphic functions), result typmod,
3427+ * result collation, the input collation to use for the function, the
3428+ * pre-simplified argument list, and some flags; also the context data for
3429+ * eval_const_expressions. In common cases, several of the arguments could be
3430+ * derived from the original expression. Sending them separately avoids
3431+ * duplicating NodeTag-specific knowledge, and it's necessary for CoerceViaIO.
3432+ * A NULL original expression disables use of transform functions while
3433+ * retaining all other behaviors.
34253434 *
34263435 * Returns a simplified expression if successful, or NULL if cannot
34273436 * simplify the function call.
@@ -3433,22 +3442,24 @@ simplify_boolean_equality(Oid opno, List *args)
34333442 * pass-by-reference, and it may get modified even if simplification fails.
34343443 */
34353444static Expr *
3436- simplify_function (Oid funcid ,Oid result_type ,int32 result_typmod ,
3437- Oid result_collid ,Oid input_collid ,List * * args ,
3445+ simplify_function (Expr * oldexpr ,Oid funcid ,
3446+ Oid result_type ,int32 result_typmod ,Oid result_collid ,
3447+ Oid input_collid ,List * * args ,
34383448bool has_named_args ,
34393449bool allow_inline ,
34403450eval_const_expressions_context * context )
34413451{
34423452HeapTuple func_tuple ;
34433453Expr * newexpr ;
3454+ Oid transform ;
34443455
34453456/*
3446- * We havetwo strategies for simplification:either execute the function
3447- *to deliver a constant result,or expand in-line the body of the
3448- *function definition (which only works for simple SQL-language
3449- *functions, but that is a common case). In either case we need access
3450- *to the function's pg_proc tuple, so fetch it just once touse in both
3451- *attempts .
3457+ * We havethree strategies for simplification: execute the function to
3458+ * deliver a constant result,use a transform function to generate a
3459+ *substitute node tree, or expand in-line the body of the function
3460+ *definition (which only works for simple SQL-language functions, but
3461+ *that is a common case). Each needs access tothe function's pg_proc
3462+ *tuple, so fetch it just once .
34523463 */
34533464func_tuple = SearchSysCache1 (PROCOID ,ObjectIdGetDatum (funcid ));
34543465if (!HeapTupleIsValid (func_tuple ))
@@ -3468,6 +3479,40 @@ simplify_function(Oid funcid, Oid result_type, int32 result_typmod,
34683479result_collid ,input_collid ,* args ,
34693480func_tuple ,context );
34703481
3482+ /*
3483+ * Some functions calls can be simplified at plan time based on properties
3484+ * specific to the function. For example, "varchar(s::varchar(4), 8,
3485+ * true)" simplifies to "s::varchar(4)", and "int4mul(n, 1)" could
3486+ * simplify to "n". To define such function-specific optimizations, write
3487+ * a "transform function" and store its OID in the pg_proc.protransform of
3488+ * the primary function. Give each transform function the signature
3489+ * "protransform(internal) RETURNS internal". The argument, internally an
3490+ * Expr *, is the node representing a call to the primary function. If
3491+ * the transform function's study of that node proves that a simplified
3492+ * Expr substitutes for all possible concrete calls represented thereby,
3493+ * return that simplified Expr. Otherwise, return the NULL pointer.
3494+ *
3495+ * Currently, the specific Expr nodetag can be FuncExpr, OpExpr or
3496+ * DistinctExpr. This list may change in the future. The function should
3497+ * check the nodetag and return the NULL pointer for unexpected inputs.
3498+ *
3499+ * We make no guarantee that PostgreSQL will never call the primary
3500+ * function in cases that the transform function would simplify. Ensure
3501+ * rigorous equivalence between the simplified expression and an actual
3502+ * call to the primary function.
3503+ *
3504+ * Currently, this facility is undocumented and not exposed to users at
3505+ * the SQL level. Core length coercion casts use it to avoid calls
3506+ * guaranteed to return their input unchanged. This in turn allows ALTER
3507+ * TABLE ALTER TYPE to avoid rewriting tables for some typmod changes. In
3508+ * the future, this facility may find other applications, like simplifying
3509+ * x*0, x*1, and x+0.
3510+ */
3511+ transform = ((Form_pg_proc )GETSTRUCT (func_tuple ))-> protransform ;
3512+ if (!newexpr && OidIsValid (transform )&& oldexpr )
3513+ newexpr = (Expr * )DatumGetPointer (OidFunctionCall1 (transform ,
3514+ PointerGetDatum (oldexpr )));
3515+
34713516if (!newexpr && allow_inline )
34723517newexpr = inline_function (funcid ,result_type ,result_collid ,
34733518input_collid ,* args ,