summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2021-03-08 23:54:55 +0000
committerTom Lane2021-03-08 23:54:55 +0000
commitd4545dc19b8ea670bf62e06d22b0e4e6fcb45153 (patch)
tree876687b611af2b5d936d260c796fc79012b3c6af
parentfed10d4eec79242688382d03ddca82007160ee6f (diff)
Complain if a function-in-FROM returns a set when it shouldn't.
Throw a "function protocol violation" error if a function in FROM tries to return a set though it wasn't marked proretset. Although such cases work at the moment, it doesn't seem like something we want to guarantee will keep working. Besides, there are other negative consequences of not setting the proretset flag, such as potentially bad plans. No back-patch, since if there is any third-party code violating this expectation, people wouldn't appreciate us breaking it in a minor release. Discussion: https://postgr.es/m/[email protected]
-rw-r--r--src/backend/executor/execSRF.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/src/backend/executor/execSRF.c b/src/backend/executor/execSRF.c
index 8aec3b549b..545b6c19da 100644
--- a/src/backend/executor/execSRF.c
+++ b/src/backend/executor/execSRF.c
@@ -353,11 +353,21 @@ ExecMakeTableFunctionResult(SetExprState *setexpr,
*/
if (rsinfo.isDone != ExprMultipleResult)
break;
+
+ /*
+ * Check that set-returning functions were properly declared.
+ * (Note: for historical reasons, we don't complain if a non-SRF
+ * returns ExprEndResult; that's treated as returning NULL.)
+ */
+ if (!returnsSet)
+ ereport(ERROR,
+ (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
+ errmsg("table-function protocol for value-per-call mode was not followed")));
}
else if (rsinfo.returnMode == SFRM_Materialize)
{
/* check we're on the same page as the function author */
- if (!first_time || rsinfo.isDone != ExprSingleResult)
+ if (!first_time || rsinfo.isDone != ExprSingleResult || !returnsSet)
ereport(ERROR,
(errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED),
errmsg("table-function protocol for materialize mode was not followed")));