Add UtilityReturnsTuples() support for CALL
authorPeter Eisentraut
Mon, 9 Jul 2018 11:58:08 +0000 (13:58 +0200)
committerPeter Eisentraut
Mon, 9 Jul 2018 11:58:51 +0000 (13:58 +0200)
This ensures that prepared statements for CALL can return tuples.

src/backend/commands/functioncmds.c
src/backend/tcop/utility.c
src/include/commands/defrem.h

index acc08b1990ee6b9de51cef52c9988f7731d8e07b..84daa19e06417aaf85cba8e59d9529bb22f9db15 100644 (file)
@@ -51,6 +51,7 @@
 #include "commands/proclang.h"
 #include "executor/execdesc.h"
 #include "executor/executor.h"
+#include "funcapi.h"
 #include "miscadmin.h"
 #include "optimizer/clauses.h"
 #include "optimizer/var.h"
@@ -2340,3 +2341,26 @@ ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver
 
    FreeExecutorState(estate);
 }
+
+/*
+ * Construct the tuple descriptor for a CALL statement return
+ */
+TupleDesc
+CallStmtResultDesc(CallStmt *stmt)
+{
+   FuncExpr   *fexpr;
+   HeapTuple   tuple;
+   TupleDesc   tupdesc;
+
+   fexpr = stmt->funcexpr;
+
+   tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(fexpr->funcid));
+   if (!HeapTupleIsValid(tuple))
+       elog(ERROR, "cache lookup failed for procedure %u", fexpr->funcid);
+
+   tupdesc = build_function_result_tupdesc_t(tuple);
+
+   ReleaseSysCache(tuple);
+
+   return tupdesc;
+}
index 4e1c21298e80754248900a1b6a63dcb6e57286df..b5804f64ad46cbb95991dfbfaf572e4ae4bc34b4 100644 (file)
@@ -1744,6 +1744,12 @@ UtilityReturnsTuples(Node *parsetree)
 {
    switch (nodeTag(parsetree))
    {
+       case T_CallStmt:
+           {
+               CallStmt   *stmt = (CallStmt *) parsetree;
+
+               return (stmt->funcexpr->funcresulttype == RECORDOID);
+           }
        case T_FetchStmt:
            {
                FetchStmt  *stmt = (FetchStmt *) parsetree;
@@ -1794,6 +1800,9 @@ UtilityTupleDescriptor(Node *parsetree)
 {
    switch (nodeTag(parsetree))
    {
+       case T_CallStmt:
+           return CallStmtResultDesc((CallStmt *) parsetree);
+
        case T_FetchStmt:
            {
                FetchStmt  *stmt = (FetchStmt *) parsetree;
index 8fc9e424cfc33891fea2fd787b82cc437d4003cd..6b837236d4d25c2184b715868d85d0603e448d5b 100644 (file)
@@ -64,6 +64,7 @@ extern void IsThereFunctionInNamespace(const char *proname, int pronargs,
                           oidvector *proargtypes, Oid nspOid);
 extern void ExecuteDoStmt(DoStmt *stmt, bool atomic);
 extern void ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver *dest);
+extern TupleDesc CallStmtResultDesc(CallStmt *stmt);
 extern Oid get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok);
 extern Oid get_transform_oid(Oid type_id, Oid lang_id, bool missing_ok);
 extern void interpret_function_parameter_list(ParseState *pstate,