aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2005-06-22 17:45:46 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2005-06-22 17:45:46 +0000
commite98edb5555de0197ba4ffc99b4f3db134c99a86f (patch)
treef022547496d97cf1984bae42f972e5da458510a5
parent84d73a6dbc23dda43bf4d83ee71b344063524cbe (diff)
downloadpostgresql-e98edb5555de0197ba4ffc99b4f3db134c99a86f.tar.gz
postgresql-e98edb5555de0197ba4ffc99b4f3db134c99a86f.zip
Fix the mechanism for reporting the original table OID and column number
of columns of a query result so that it can "see through" cursors and prepared statements. Per gripe a couple months back from John DeSoi.
-rw-r--r--src/backend/access/common/printtup.c16
-rw-r--r--src/backend/commands/prepare.c54
-rw-r--r--src/backend/tcop/postgres.c25
-rw-r--r--src/backend/tcop/pquery.c53
-rw-r--r--src/include/commands/prepare.h3
-rw-r--r--src/include/tcop/pquery.h4
6 files changed, 121 insertions, 34 deletions
diff --git a/src/backend/access/common/printtup.c b/src/backend/access/common/printtup.c
index 78939e2bd05..9080d047fc2 100644
--- a/src/backend/access/common/printtup.c
+++ b/src/backend/access/common/printtup.c
@@ -9,7 +9,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/common/printtup.c,v 1.90 2005/05/01 18:56:17 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/common/printtup.c,v 1.91 2005/06/22 17:45:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -19,6 +19,7 @@
#include "access/printtup.h"
#include "libpq/libpq.h"
#include "libpq/pqformat.h"
+#include "tcop/pquery.h"
#include "utils/lsyscache.h"
#include "utils/portal.h"
@@ -130,16 +131,9 @@ printtup_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
* descriptions, then we send back the tuple descriptor of the tuples.
*/
if (operation == CMD_SELECT && myState->sendDescrip)
- {
- List *targetlist;
-
- if (portal->strategy == PORTAL_ONE_SELECT)
- targetlist = ((Query *) linitial(portal->parseTrees))->targetList;
- else
- targetlist = NIL;
-
- SendRowDescriptionMessage(typeinfo, targetlist, portal->formats);
- }
+ SendRowDescriptionMessage(typeinfo,
+ FetchPortalTargetList(portal),
+ portal->formats);
/* ----------------
* We could set up the derived attr info at this time, but we postpone it
diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c
index be3416bd3e5..dec3d249dfa 100644
--- a/src/backend/commands/prepare.c
+++ b/src/backend/commands/prepare.c
@@ -10,7 +10,7 @@
* Copyright (c) 2002-2005, PostgreSQL Global Development Group
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.39 2005/06/03 23:05:28 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.40 2005/06/22 17:45:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -446,6 +446,58 @@ FetchPreparedStatementResultDesc(PreparedStatement *stmt)
}
/*
+ * Given a prepared statement that returns tuples, extract the query
+ * targetlist. Returns NIL if the statement doesn't have a determinable
+ * targetlist.
+ *
+ * Note: do not modify the result.
+ *
+ * XXX be careful to keep this in sync with FetchPortalTargetList,
+ * and with UtilityReturnsTuples.
+ */
+List *
+FetchPreparedStatementTargetList(PreparedStatement *stmt)
+{
+ PortalStrategy strategy = ChoosePortalStrategy(stmt->query_list);
+
+ if (strategy == PORTAL_ONE_SELECT)
+ return ((Query *) linitial(stmt->query_list))->targetList;
+ if (strategy == PORTAL_UTIL_SELECT)
+ {
+ Node *utilityStmt;
+
+ utilityStmt = ((Query *) linitial(stmt->query_list))->utilityStmt;
+ switch (nodeTag(utilityStmt))
+ {
+ case T_FetchStmt:
+ {
+ FetchStmt *substmt = (FetchStmt *) utilityStmt;
+ Portal subportal;
+
+ Assert(!substmt->ismove);
+ subportal = GetPortalByName(substmt->portalname);
+ Assert(PortalIsValid(subportal));
+ return FetchPortalTargetList(subportal);
+ }
+
+ case T_ExecuteStmt:
+ {
+ ExecuteStmt *substmt = (ExecuteStmt *) utilityStmt;
+ PreparedStatement *entry;
+
+ Assert(!substmt->into);
+ entry = FetchPreparedStatement(substmt->name, true);
+ return FetchPreparedStatementTargetList(entry);
+ }
+
+ default:
+ break;
+ }
+ }
+ return NIL;
+}
+
+/*
* Implements the 'DEALLOCATE' utility statement: deletes the
* specified plan from storage.
*/
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 454bc2577e1..a676edd9a97 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.449 2005/06/17 22:32:46 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.450 2005/06/22 17:45:45 tgl Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
@@ -1928,15 +1928,9 @@ exec_describe_statement_message(const char *stmt_name)
*/
tupdesc = FetchPreparedStatementResultDesc(pstmt);
if (tupdesc)
- {
- List *targetlist;
-
- if (ChoosePortalStrategy(pstmt->query_list) == PORTAL_ONE_SELECT)
- targetlist = ((Query *) linitial(pstmt->query_list))->targetList;
- else
- targetlist = NIL;
- SendRowDescriptionMessage(tupdesc, targetlist, NULL);
- }
+ SendRowDescriptionMessage(tupdesc,
+ FetchPreparedStatementTargetList(pstmt),
+ NULL);
else
pq_putemptymessage('n'); /* NoData */
@@ -1962,16 +1956,9 @@ exec_describe_portal_message(const char *portal_name)
return; /* can't actually do anything... */
if (portal->tupDesc)
- {
- List *targetlist;
-
- if (portal->strategy == PORTAL_ONE_SELECT)
- targetlist = ((Query *) linitial(portal->parseTrees))->targetList;
- else
- targetlist = NIL;
- SendRowDescriptionMessage(portal->tupDesc, targetlist,
+ SendRowDescriptionMessage(portal->tupDesc,
+ FetchPortalTargetList(portal),
portal->formats);
- }
else
pq_putemptymessage('n'); /* NoData */
}
diff --git a/src/backend/tcop/pquery.c b/src/backend/tcop/pquery.c
index 51f3df8e56b..75eb75f6de7 100644
--- a/src/backend/tcop/pquery.c
+++ b/src/backend/tcop/pquery.c
@@ -8,13 +8,14 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/tcop/pquery.c,v 1.93 2005/03/25 21:57:58 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/tcop/pquery.c,v 1.94 2005/06/22 17:45:46 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
+#include "commands/prepare.h"
#include "commands/trigger.h"
#include "executor/executor.h"
#include "miscadmin.h"
@@ -253,6 +254,56 @@ ChoosePortalStrategy(List *parseTrees)
}
/*
+ * FetchPortalTargetList
+ * Given a portal that returns tuples, extract the query targetlist.
+ * Returns NIL if the portal doesn't have a determinable targetlist.
+ *
+ * Note: do not modify the result.
+ *
+ * XXX be careful to keep this in sync with FetchPreparedStatementTargetList,
+ * and with UtilityReturnsTuples.
+ */
+List *
+FetchPortalTargetList(Portal portal)
+{
+ if (portal->strategy == PORTAL_ONE_SELECT)
+ return ((Query *) linitial(portal->parseTrees))->targetList;
+ if (portal->strategy == PORTAL_UTIL_SELECT)
+ {
+ Node *utilityStmt;
+
+ utilityStmt = ((Query *) linitial(portal->parseTrees))->utilityStmt;
+ switch (nodeTag(utilityStmt))
+ {
+ case T_FetchStmt:
+ {
+ FetchStmt *substmt = (FetchStmt *) utilityStmt;
+ Portal subportal;
+
+ Assert(!substmt->ismove);
+ subportal = GetPortalByName(substmt->portalname);
+ Assert(PortalIsValid(subportal));
+ return FetchPortalTargetList(subportal);
+ }
+
+ case T_ExecuteStmt:
+ {
+ ExecuteStmt *substmt = (ExecuteStmt *) utilityStmt;
+ PreparedStatement *entry;
+
+ Assert(!substmt->into);
+ entry = FetchPreparedStatement(substmt->name, true);
+ return FetchPreparedStatementTargetList(entry);
+ }
+
+ default:
+ break;
+ }
+ }
+ return NIL;
+}
+
+/*
* PortalStart
* Prepare a portal for execution.
*
diff --git a/src/include/commands/prepare.h b/src/include/commands/prepare.h
index 4a8cde52354..b6c315bd42d 100644
--- a/src/include/commands/prepare.h
+++ b/src/include/commands/prepare.h
@@ -6,7 +6,7 @@
*
* Copyright (c) 2002-2005, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/include/commands/prepare.h,v 1.13 2005/01/01 05:43:09 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/commands/prepare.h,v 1.14 2005/06/22 17:45:46 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -59,5 +59,6 @@ extern PreparedStatement *FetchPreparedStatement(const char *stmt_name,
extern void DropPreparedStatement(const char *stmt_name, bool showError);
extern List *FetchPreparedStatementParams(const char *stmt_name);
extern TupleDesc FetchPreparedStatementResultDesc(PreparedStatement *stmt);
+extern List *FetchPreparedStatementTargetList(PreparedStatement *stmt);
#endif /* PREPARE_H */
diff --git a/src/include/tcop/pquery.h b/src/include/tcop/pquery.h
index c3c87baa3f9..da2d29aea89 100644
--- a/src/include/tcop/pquery.h
+++ b/src/include/tcop/pquery.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/tcop/pquery.h,v 1.34 2004/12/31 22:03:44 pgsql Exp $
+ * $PostgreSQL: pgsql/src/include/tcop/pquery.h,v 1.35 2005/06/22 17:45:46 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -22,6 +22,8 @@ extern DLLIMPORT Portal ActivePortal;
extern PortalStrategy ChoosePortalStrategy(List *parseTrees);
+extern List *FetchPortalTargetList(Portal portal);
+
extern void PortalStart(Portal portal, ParamListInfo params,
Snapshot snapshot);