aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2024-04-15 12:56:56 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2024-04-15 12:56:56 -0400
commite0df80828abc0c01fcde123389032370b98f2015 (patch)
tree6c51e7ebf35c307ad5070f44c8d909f557047fac /src/backend/utils
parentcee8db3f680b737b64d747530b48d30828cf4790 (diff)
downloadpostgresql-e0df80828abc0c01fcde123389032370b98f2015.tar.gz
postgresql-e0df80828abc0c01fcde123389032370b98f2015.zip
Fix type-checking of RECORD-returning functions in FROM, redux.
Commit 2ed8f9a01 intended to institute a policy that if a RangeTblFunction has a coldeflist, then the function return type is certainly RECORD, and we should use the coldeflist as the source of truth about what the columns of the record type are. When the original function has been folded to a constant, inspection of the constant might give a different answer. This situation will lead to a tuple-type-mismatch error at execution, but up until that point we need to consistently believe the coldeflist, or we'll have problems from different bits of code reaching different conclusions. expandRTE didn't get that memo though, and would try to produce a tupdesc based on the constant in this situation, leading to an assertion failure. (Desultory testing suggests that non-assert builds often manage to give the expected error, although I also saw a "cache lookup failed for type 0" error, and it seems at least possible that a crash could happen.) Some other callers of get_expr_result_type and get_expr_result_tupdesc were also being incautious about this. While none of them seem to have actual bugs, they're working harder than necessary in this case, besides which it seems safest to have an explicit policy of not using those functions on an RTE with a coldeflist. Adjust the code accordingly, and add commentary to funcapi.c about this policy. Also fix an obsolete comment that claimed "get_expr_result_type() doesn't know how to extract type info from a RECORD constant". That hasn't been true since commit d57534740. Per bug #18422 from Alexander Lakhin. As with the previous commit, back-patch to all supported branches. Discussion: https://postgr.es/m/18422-89ca86c8eac5246d@postgresql.org
Diffstat (limited to 'src/backend/utils')
-rw-r--r--src/backend/utils/fmgr/funcapi.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/src/backend/utils/fmgr/funcapi.c b/src/backend/utils/fmgr/funcapi.c
index 5c03704ef9b..05d763fa06e 100644
--- a/src/backend/utils/fmgr/funcapi.c
+++ b/src/backend/utils/fmgr/funcapi.c
@@ -287,6 +287,13 @@ get_call_result_type(FunctionCallInfo fcinfo,
/*
* get_expr_result_type
* As above, but work from a calling expression node tree
+ *
+ * Beware of using this on the funcexpr of a RTE that has a coldeflist.
+ * The correct conclusion in such cases is always that the function returns
+ * RECORD with the columns defined by the coldeflist fields (funccolnames etc).
+ * If it does not, it's the executor's responsibility to catch the discrepancy
+ * at runtime; but code processing the query in advance of that point might
+ * come to inconsistent conclusions if it checks the actual expression.
*/
TypeFuncClass
get_expr_result_type(Node *expr,
@@ -537,7 +544,8 @@ internal_get_result_type(Oid funcid,
* if noError is true, else throws error.
*
* This is a simpler version of get_expr_result_type() for use when the caller
- * is only interested in determinate rowtype results.
+ * is only interested in determinate rowtype results. As with that function,
+ * beware of using this on the funcexpr of a RTE that has a coldeflist.
*/
TupleDesc
get_expr_result_tupdesc(Node *expr, bool noError)