diff options
Diffstat (limited to 'src/backend/optimizer/util/clauses.c')
-rw-r--r-- | src/backend/optimizer/util/clauses.c | 41 |
1 files changed, 6 insertions, 35 deletions
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index 99dbf8da189..7ad9d9ab79e 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -4870,6 +4870,10 @@ evaluate_expr(Expr *expr, Oid result_type, int32 result_typmod, * set-returning SQL function that can safely be inlined, expand the function * and return the substitute Query structure. Otherwise, return NULL. * + * We assume that the RTE's expression has already been put through + * eval_const_expressions(), which among other things will take care of + * default arguments and named-argument notation. + * * This has a good deal of similarity to inline_function(), but that's * for the non-set-returning case, and there are enough differences to * justify separate functions. @@ -4888,7 +4892,6 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte) bool modifyTargetList; MemoryContext oldcxt; MemoryContext mycxt; - List *saveInvalItems; inline_error_callback_arg callback_arg; ErrorContextCallback sqlerrcontext; SQLFunctionParseInfoPtr pinfo; @@ -4966,7 +4969,7 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte) * sharing the snapshot of the calling query. We also disallow returning * SETOF VOID, because inlining would result in exposing the actual result * of the function's last SELECT, which should not happen in that case. - * (Rechecking prokind and proretset is just paranoia.) + * (Rechecking prokind, proretset, and pronargs is just paranoia.) */ if (funcform->prolang != SQLlanguageId || funcform->prokind != PROKIND_FUNCTION || @@ -4975,6 +4978,7 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte) funcform->prorettype == VOIDOID || funcform->prosecdef || !funcform->proretset || + list_length(fexpr->args) != funcform->pronargs || !heap_attisnull(func_tuple, Anum_pg_proc_proconfig, NULL)) { ReleaseSysCache(func_tuple); @@ -4990,16 +4994,6 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte) ALLOCSET_DEFAULT_SIZES); oldcxt = MemoryContextSwitchTo(mycxt); - /* - * When we call eval_const_expressions below, it might try to add items to - * root->glob->invalItems. Since it is running in the temp context, those - * items will be in that context, and will need to be copied out if we're - * successful. Temporarily reset the list so that we can keep those items - * separate from the pre-existing list contents. - */ - saveInvalItems = root->glob->invalItems; - root->glob->invalItems = NIL; - /* Fetch the function body */ tmp = SysCacheGetAttr(PROCOID, func_tuple, @@ -5022,24 +5016,6 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte) error_context_stack = &sqlerrcontext; /* - * Run eval_const_expressions on the function call. This is necessary to - * ensure that named-argument notation is converted to positional notation - * and any default arguments are inserted. It's a bit of overkill for the - * arguments, since they'll get processed again later, but no harm will be - * done. - */ - fexpr = (FuncExpr *) eval_const_expressions(root, (Node *) fexpr); - - /* It should still be a call of the same function, but let's check */ - if (!IsA(fexpr, FuncExpr) || - fexpr->funcid != func_oid) - goto fail; - - /* Arg list length should now match the function */ - if (list_length(fexpr->args) != funcform->pronargs) - goto fail; - - /* * Set up to handle parameters while parsing the function body. We can * use the FuncExpr just created as the input for * prepare_sql_fn_parse_info. @@ -5129,10 +5105,6 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte) querytree = copyObject(querytree); - /* copy up any new invalItems, too */ - root->glob->invalItems = list_concat(saveInvalItems, - copyObject(root->glob->invalItems)); - MemoryContextDelete(mycxt); error_context_stack = sqlerrcontext.previous; ReleaseSysCache(func_tuple); @@ -5153,7 +5125,6 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte) /* Here if func is not inlinable: release temp memory and return NULL */ fail: MemoryContextSwitchTo(oldcxt); - root->glob->invalItems = saveInvalItems; MemoryContextDelete(mycxt); error_context_stack = sqlerrcontext.previous; ReleaseSysCache(func_tuple); |