Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e98edb5

Browse files
committed
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.
1 parent 84d73a6 commit e98edb5

File tree

6 files changed

+121
-34
lines changed

6 files changed

+121
-34
lines changed

src/backend/access/common/printtup.c

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* Portions Copyright (c) 1994, Regents of the University of California
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/access/common/printtup.c,v 1.90 2005/05/01 18:56:17 tgl Exp $
12+
* $PostgreSQL: pgsql/src/backend/access/common/printtup.c,v 1.91 2005/06/22 17:45:45 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -19,6 +19,7 @@
1919
#include "access/printtup.h"
2020
#include "libpq/libpq.h"
2121
#include "libpq/pqformat.h"
22+
#include "tcop/pquery.h"
2223
#include "utils/lsyscache.h"
2324
#include "utils/portal.h"
2425

@@ -130,16 +131,9 @@ printtup_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
130131
* descriptions, then we send back the tuple descriptor of the tuples.
131132
*/
132133
if (operation == CMD_SELECT && myState->sendDescrip)
133-
{
134-
List *targetlist;
135-
136-
if (portal->strategy == PORTAL_ONE_SELECT)
137-
targetlist = ((Query *) linitial(portal->parseTrees))->targetList;
138-
else
139-
targetlist = NIL;
140-
141-
SendRowDescriptionMessage(typeinfo, targetlist, portal->formats);
142-
}
134+
SendRowDescriptionMessage(typeinfo,
135+
FetchPortalTargetList(portal),
136+
portal->formats);
143137

144138
/* ----------------
145139
* We could set up the derived attr info at this time, but we postpone it

src/backend/commands/prepare.c

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* Copyright (c) 2002-2005, PostgreSQL Global Development Group
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.39 2005/06/03 23:05:28 tgl Exp $
13+
* $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.40 2005/06/22 17:45:45 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -445,6 +445,58 @@ FetchPreparedStatementResultDesc(PreparedStatement *stmt)
445445
return NULL;
446446
}
447447

448+
/*
449+
* Given a prepared statement that returns tuples, extract the query
450+
* targetlist. Returns NIL if the statement doesn't have a determinable
451+
* targetlist.
452+
*
453+
* Note: do not modify the result.
454+
*
455+
* XXX be careful to keep this in sync with FetchPortalTargetList,
456+
* and with UtilityReturnsTuples.
457+
*/
458+
List *
459+
FetchPreparedStatementTargetList(PreparedStatement *stmt)
460+
{
461+
PortalStrategy strategy = ChoosePortalStrategy(stmt->query_list);
462+
463+
if (strategy == PORTAL_ONE_SELECT)
464+
return ((Query *) linitial(stmt->query_list))->targetList;
465+
if (strategy == PORTAL_UTIL_SELECT)
466+
{
467+
Node *utilityStmt;
468+
469+
utilityStmt = ((Query *) linitial(stmt->query_list))->utilityStmt;
470+
switch (nodeTag(utilityStmt))
471+
{
472+
case T_FetchStmt:
473+
{
474+
FetchStmt *substmt = (FetchStmt *) utilityStmt;
475+
Portal subportal;
476+
477+
Assert(!substmt->ismove);
478+
subportal = GetPortalByName(substmt->portalname);
479+
Assert(PortalIsValid(subportal));
480+
return FetchPortalTargetList(subportal);
481+
}
482+
483+
case T_ExecuteStmt:
484+
{
485+
ExecuteStmt *substmt = (ExecuteStmt *) utilityStmt;
486+
PreparedStatement *entry;
487+
488+
Assert(!substmt->into);
489+
entry = FetchPreparedStatement(substmt->name, true);
490+
return FetchPreparedStatementTargetList(entry);
491+
}
492+
493+
default:
494+
break;
495+
}
496+
}
497+
return NIL;
498+
}
499+
448500
/*
449501
* Implements the 'DEALLOCATE' utility statement: deletes the
450502
* specified plan from storage.

src/backend/tcop/postgres.c

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.449 2005/06/17 22:32:46 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.450 2005/06/22 17:45:45 tgl Exp $
1212
*
1313
* NOTES
1414
* this is the "main" module of the postgres backend and
@@ -1928,15 +1928,9 @@ exec_describe_statement_message(const char *stmt_name)
19281928
*/
19291929
tupdesc = FetchPreparedStatementResultDesc(pstmt);
19301930
if (tupdesc)
1931-
{
1932-
List *targetlist;
1933-
1934-
if (ChoosePortalStrategy(pstmt->query_list) == PORTAL_ONE_SELECT)
1935-
targetlist = ((Query *) linitial(pstmt->query_list))->targetList;
1936-
else
1937-
targetlist = NIL;
1938-
SendRowDescriptionMessage(tupdesc, targetlist, NULL);
1939-
}
1931+
SendRowDescriptionMessage(tupdesc,
1932+
FetchPreparedStatementTargetList(pstmt),
1933+
NULL);
19401934
else
19411935
pq_putemptymessage('n'); /* NoData */
19421936

@@ -1962,16 +1956,9 @@ exec_describe_portal_message(const char *portal_name)
19621956
return; /* can't actually do anything... */
19631957

19641958
if (portal->tupDesc)
1965-
{
1966-
List *targetlist;
1967-
1968-
if (portal->strategy == PORTAL_ONE_SELECT)
1969-
targetlist = ((Query *) linitial(portal->parseTrees))->targetList;
1970-
else
1971-
targetlist = NIL;
1972-
SendRowDescriptionMessage(portal->tupDesc, targetlist,
1959+
SendRowDescriptionMessage(portal->tupDesc,
1960+
FetchPortalTargetList(portal),
19731961
portal->formats);
1974-
}
19751962
else
19761963
pq_putemptymessage('n'); /* NoData */
19771964
}

src/backend/tcop/pquery.c

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/tcop/pquery.c,v 1.93 2005/03/25 21:57:58 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/tcop/pquery.c,v 1.94 2005/06/22 17:45:46 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
1515

1616
#include "postgres.h"
1717

18+
#include "commands/prepare.h"
1819
#include "commands/trigger.h"
1920
#include "executor/executor.h"
2021
#include "miscadmin.h"
@@ -252,6 +253,56 @@ ChoosePortalStrategy(List *parseTrees)
252253
return strategy;
253254
}
254255

256+
/*
257+
* FetchPortalTargetList
258+
* Given a portal that returns tuples, extract the query targetlist.
259+
* Returns NIL if the portal doesn't have a determinable targetlist.
260+
*
261+
* Note: do not modify the result.
262+
*
263+
* XXX be careful to keep this in sync with FetchPreparedStatementTargetList,
264+
* and with UtilityReturnsTuples.
265+
*/
266+
List *
267+
FetchPortalTargetList(Portal portal)
268+
{
269+
if (portal->strategy == PORTAL_ONE_SELECT)
270+
return ((Query *) linitial(portal->parseTrees))->targetList;
271+
if (portal->strategy == PORTAL_UTIL_SELECT)
272+
{
273+
Node *utilityStmt;
274+
275+
utilityStmt = ((Query *) linitial(portal->parseTrees))->utilityStmt;
276+
switch (nodeTag(utilityStmt))
277+
{
278+
case T_FetchStmt:
279+
{
280+
FetchStmt *substmt = (FetchStmt *) utilityStmt;
281+
Portal subportal;
282+
283+
Assert(!substmt->ismove);
284+
subportal = GetPortalByName(substmt->portalname);
285+
Assert(PortalIsValid(subportal));
286+
return FetchPortalTargetList(subportal);
287+
}
288+
289+
case T_ExecuteStmt:
290+
{
291+
ExecuteStmt *substmt = (ExecuteStmt *) utilityStmt;
292+
PreparedStatement *entry;
293+
294+
Assert(!substmt->into);
295+
entry = FetchPreparedStatement(substmt->name, true);
296+
return FetchPreparedStatementTargetList(entry);
297+
}
298+
299+
default:
300+
break;
301+
}
302+
}
303+
return NIL;
304+
}
305+
255306
/*
256307
* PortalStart
257308
* Prepare a portal for execution.

src/include/commands/prepare.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* Copyright (c) 2002-2005, PostgreSQL Global Development Group
88
*
9-
* $PostgreSQL: pgsql/src/include/commands/prepare.h,v 1.13 2005/01/01 05:43:09 momjian Exp $
9+
* $PostgreSQL: pgsql/src/include/commands/prepare.h,v 1.14 2005/06/22 17:45:46 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -59,5 +59,6 @@ extern PreparedStatement *FetchPreparedStatement(const char *stmt_name,
5959
extern void DropPreparedStatement(const char *stmt_name, bool showError);
6060
extern List *FetchPreparedStatementParams(const char *stmt_name);
6161
extern TupleDesc FetchPreparedStatementResultDesc(PreparedStatement *stmt);
62+
extern List *FetchPreparedStatementTargetList(PreparedStatement *stmt);
6263

6364
#endif /* PREPARE_H */

src/include/tcop/pquery.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/tcop/pquery.h,v 1.34 2004/12/31 22:03:44 pgsql Exp $
10+
* $PostgreSQL: pgsql/src/include/tcop/pquery.h,v 1.35 2005/06/22 17:45:46 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -22,6 +22,8 @@ extern DLLIMPORT Portal ActivePortal;
2222

2323
extern PortalStrategy ChoosePortalStrategy(List *parseTrees);
2424

25+
extern List *FetchPortalTargetList(Portal portal);
26+
2527
extern void PortalStart(Portal portal, ParamListInfo params,
2628
Snapshot snapshot);
2729

0 commit comments

Comments
 (0)