]> granicus.if.org Git - postgresql/commitdiff
Add UtilityReturnsTuples() support for CALL
authorPeter Eisentraut <peter_e@gmx.net>
Mon, 9 Jul 2018 11:58:08 +0000 (13:58 +0200)
committerPeter Eisentraut <peter_e@gmx.net>
Mon, 9 Jul 2018 11:58:08 +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,