diff options
Diffstat (limited to '')
-rw-r--r-- | src/backend/optimizer/util/clauses.c | 43 |
1 files changed, 26 insertions, 17 deletions
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index e1cedd9..9fcfd55 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -2347,6 +2347,10 @@ static Node * eval_const_expressions_mutator(Node *node, eval_const_expressions_context *context) { + + /* since this function recurses, it could be driven to stack overflow */ + check_stack_depth(); + if (node == NULL) return NULL; switch (nodeTag(node)) @@ -4319,12 +4323,11 @@ evaluate_function(Oid funcid, Oid result_type, int32 result_typmod, * Can't simplify if it returns RECORD. The immediate problem is that it * will be needing an expected tupdesc which we can't supply here. * - * In the case where it has OUT parameters, it could get by without an - * expected tupdesc, but we still have issues: get_expr_result_type() - * doesn't know how to extract type info from a RECORD constant, and in - * the case of a NULL function result there doesn't seem to be any clean - * way to fix that. In view of the likelihood of there being still other - * gotchas, seems best to leave the function call unreduced. + * In the case where it has OUT parameters, we could build an expected + * tupdesc from those, but there may be other gotchas lurking. In + * particular, if the function were to return NULL, we would produce a + * null constant with no remaining indication of which concrete record + * type it is. For now, seems best to leave the function call unreduced. */ if (funcform->prorettype == RECORDOID) return NULL; @@ -4618,9 +4621,10 @@ inline_function(Oid funcid, Oid result_type, Oid result_collid, * needed; that's probably not important, but let's be careful. */ querytree_list = list_make1(querytree); - if (check_sql_fn_retval(list_make1(querytree_list), - result_type, rettupdesc, - false, NULL)) + if (check_sql_fn_retval_ext(list_make1(querytree_list), + result_type, rettupdesc, + funcform->prokind, + false, NULL)) goto fail; /* reject whole-tuple-result cases */ /* @@ -5134,16 +5138,20 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte) } /* - * Also resolve the actual function result tupdesc, if composite. If the - * function is just declared to return RECORD, dig the info out of the AS - * clause. + * Also resolve the actual function result tupdesc, if composite. If we + * have a coldeflist, believe that; otherwise use get_expr_result_type. + * (This logic should match ExecInitFunctionScan.) */ - functypclass = get_expr_result_type((Node *) fexpr, NULL, &rettupdesc); - if (functypclass == TYPEFUNC_RECORD) + if (rtfunc->funccolnames != NIL) + { + functypclass = TYPEFUNC_RECORD; rettupdesc = BuildDescFromLists(rtfunc->funccolnames, rtfunc->funccoltypes, rtfunc->funccoltypmods, rtfunc->funccolcollations); + } + else + functypclass = get_expr_result_type((Node *) fexpr, NULL, &rettupdesc); /* * The single command must be a plain SELECT. @@ -5165,9 +5173,10 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte) * shows it's returning a whole tuple result; otherwise what it's * returning is a single composite column which is not what we need. */ - if (!check_sql_fn_retval(list_make1(querytree_list), - fexpr->funcresulttype, rettupdesc, - true, NULL) && + if (!check_sql_fn_retval_ext(list_make1(querytree_list), + fexpr->funcresulttype, rettupdesc, + funcform->prokind, + true, NULL) && (functypclass == TYPEFUNC_COMPOSITE || functypclass == TYPEFUNC_COMPOSITE_DOMAIN || functypclass == TYPEFUNC_RECORD)) |