Skip to content
Snippets Groups Projects
Commit e98edb55 authored by Tom Lane's avatar Tom Lane
Browse files

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.
parent 84d73a6d
Branches
Tags
No related merge requests found
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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 @@ ...@@ -19,6 +19,7 @@
#include "access/printtup.h" #include "access/printtup.h"
#include "libpq/libpq.h" #include "libpq/libpq.h"
#include "libpq/pqformat.h" #include "libpq/pqformat.h"
#include "tcop/pquery.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
#include "utils/portal.h" #include "utils/portal.h"
...@@ -130,16 +131,9 @@ printtup_startup(DestReceiver *self, int operation, TupleDesc typeinfo) ...@@ -130,16 +131,9 @@ printtup_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
* descriptions, then we send back the tuple descriptor of the tuples. * descriptions, then we send back the tuple descriptor of the tuples.
*/ */
if (operation == CMD_SELECT && myState->sendDescrip) if (operation == CMD_SELECT && myState->sendDescrip)
{ SendRowDescriptionMessage(typeinfo,
List *targetlist; FetchPortalTargetList(portal),
portal->formats);
if (portal->strategy == PORTAL_ONE_SELECT)
targetlist = ((Query *) linitial(portal->parseTrees))->targetList;
else
targetlist = NIL;
SendRowDescriptionMessage(typeinfo, targetlist, portal->formats);
}
/* ---------------- /* ----------------
* We could set up the derived attr info at this time, but we postpone it * We could set up the derived attr info at this time, but we postpone it
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* Copyright (c) 2002-2005, PostgreSQL Global Development Group * Copyright (c) 2002-2005, PostgreSQL Global Development Group
* *
* IDENTIFICATION * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -445,6 +445,58 @@ FetchPreparedStatementResultDesc(PreparedStatement *stmt) ...@@ -445,6 +445,58 @@ FetchPreparedStatementResultDesc(PreparedStatement *stmt)
return NULL; return NULL;
} }
/*
* 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 * Implements the 'DEALLOCATE' utility statement: deletes the
* specified plan from storage. * specified plan from storage.
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* this is the "main" module of the postgres backend and * this is the "main" module of the postgres backend and
...@@ -1928,15 +1928,9 @@ exec_describe_statement_message(const char *stmt_name) ...@@ -1928,15 +1928,9 @@ exec_describe_statement_message(const char *stmt_name)
*/ */
tupdesc = FetchPreparedStatementResultDesc(pstmt); tupdesc = FetchPreparedStatementResultDesc(pstmt);
if (tupdesc) if (tupdesc)
{ SendRowDescriptionMessage(tupdesc,
List *targetlist; FetchPreparedStatementTargetList(pstmt),
NULL);
if (ChoosePortalStrategy(pstmt->query_list) == PORTAL_ONE_SELECT)
targetlist = ((Query *) linitial(pstmt->query_list))->targetList;
else
targetlist = NIL;
SendRowDescriptionMessage(tupdesc, targetlist, NULL);
}
else else
pq_putemptymessage('n'); /* NoData */ pq_putemptymessage('n'); /* NoData */
...@@ -1962,16 +1956,9 @@ exec_describe_portal_message(const char *portal_name) ...@@ -1962,16 +1956,9 @@ exec_describe_portal_message(const char *portal_name)
return; /* can't actually do anything... */ return; /* can't actually do anything... */
if (portal->tupDesc) if (portal->tupDesc)
{ SendRowDescriptionMessage(portal->tupDesc,
List *targetlist; FetchPortalTargetList(portal),
if (portal->strategy == PORTAL_ONE_SELECT)
targetlist = ((Query *) linitial(portal->parseTrees))->targetList;
else
targetlist = NIL;
SendRowDescriptionMessage(portal->tupDesc, targetlist,
portal->formats); portal->formats);
}
else else
pq_putemptymessage('n'); /* NoData */ pq_putemptymessage('n'); /* NoData */
} }
......
...@@ -8,13 +8,14 @@ ...@@ -8,13 +8,14 @@
* *
* *
* IDENTIFICATION * 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 "postgres.h"
#include "commands/prepare.h"
#include "commands/trigger.h" #include "commands/trigger.h"
#include "executor/executor.h" #include "executor/executor.h"
#include "miscadmin.h" #include "miscadmin.h"
...@@ -252,6 +253,56 @@ ChoosePortalStrategy(List *parseTrees) ...@@ -252,6 +253,56 @@ ChoosePortalStrategy(List *parseTrees)
return strategy; return strategy;
} }
/*
* 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 * PortalStart
* Prepare a portal for execution. * Prepare a portal for execution.
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 2002-2005, PostgreSQL Global Development Group * 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, ...@@ -59,5 +59,6 @@ extern PreparedStatement *FetchPreparedStatement(const char *stmt_name,
extern void DropPreparedStatement(const char *stmt_name, bool showError); extern void DropPreparedStatement(const char *stmt_name, bool showError);
extern List *FetchPreparedStatementParams(const char *stmt_name); extern List *FetchPreparedStatementParams(const char *stmt_name);
extern TupleDesc FetchPreparedStatementResultDesc(PreparedStatement *stmt); extern TupleDesc FetchPreparedStatementResultDesc(PreparedStatement *stmt);
extern List *FetchPreparedStatementTargetList(PreparedStatement *stmt);
#endif /* PREPARE_H */ #endif /* PREPARE_H */
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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; ...@@ -22,6 +22,8 @@ extern DLLIMPORT Portal ActivePortal;
extern PortalStrategy ChoosePortalStrategy(List *parseTrees); extern PortalStrategy ChoosePortalStrategy(List *parseTrees);
extern List *FetchPortalTargetList(Portal portal);
extern void PortalStart(Portal portal, ParamListInfo params, extern void PortalStart(Portal portal, ParamListInfo params,
Snapshot snapshot); Snapshot snapshot);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment