Fix inconsistencies in SRF checks of pg_config() and string_to_table()
authorMichael Paquier <[email protected]>
Sat, 19 Feb 2022 05:58:51 +0000 (14:58 +0900)
committerMichael Paquier <[email protected]>
Sat, 19 Feb 2022 05:58:51 +0000 (14:58 +0900)
The execution paths of those functions have been using a set of checks
inconsistent with any other SRF function:
- string_to_table() missed a check on expectedDesc, the tuple descriptor
expected by the caller, that should never be NULL.  Introduced in
66f1630.
- pg_config() should check for a ReturnSetInfo, and expectedDesc cannot
be NULL.  Its error messages were also inconsistent.  Introduced in
a5c43b8.

Extracted from a larger patch by the same author, in preparation for a
larger patch set aimed at refactoring the way tuplestores are created
and checked in SRF functions.

Author: Melanie Plageman
Reviewed-by: Justin Pryzby
Discussion: https://postgr.es/m/CAAKRu_azyd1Z3W_r7Ou4sorTjRCs+PxeHw1CWJeXKofkE6TuZg@mail.gmail.com

src/backend/utils/adt/varlena.c
src/backend/utils/misc/pg_config.c

index eda9c1e42c0476390c0075c00d8266882244619a..b2003f5672e83cfbb345959d1ebabb91a49e0bc3 100644 (file)
@@ -4839,7 +4839,8 @@ text_to_table(PG_FUNCTION_ARGS)
        ereport(ERROR,
                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                 errmsg("set-valued function called in context that cannot accept a set")));
-   if (!(rsi->allowedModes & SFRM_Materialize))
+   if (!(rsi->allowedModes & SFRM_Materialize) ||
+       rsi->expectedDesc == NULL)
        ereport(ERROR,
                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                 errmsg("materialize mode required, but it is not allowed in this context")));
index d916d7b2c47f89bcf607ba99e6eb256fdae58353..2dc875ebfbb64d1cf5601469e2f65bdf59e6cef1 100644 (file)
@@ -37,11 +37,15 @@ pg_config(PG_FUNCTION_ARGS)
    int         i = 0;
 
    /* check to see if caller supports us returning a tuplestore */
-   if (!rsinfo || !(rsinfo->allowedModes & SFRM_Materialize))
+   if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
        ereport(ERROR,
-               (errcode(ERRCODE_SYNTAX_ERROR),
-                errmsg("materialize mode required, but it is not "
-                       "allowed in this context")));
+               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                errmsg("set-valued function called in context that cannot accept a set")));
+   if (!(rsinfo->allowedModes & SFRM_Materialize) ||
+       rsinfo->expectedDesc == NULL)
+       ereport(ERROR,
+               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                errmsg("materialize mode required, but it is not allowed in this context")));
 
    per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
    oldcontext = MemoryContextSwitchTo(per_query_ctx);