PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
pquery.h File Reference
#include "nodes/parsenodes.h"
#include "utils/portal.h"
Include dependency graph for pquery.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

PortalStrategy ChoosePortalStrategy (List *stmts)
 
ListFetchPortalTargetList (Portal portal)
 
ListFetchStatementTargetList (Node *stmt)
 
void PortalStart (Portal portal, ParamListInfo params, int eflags, Snapshot snapshot)
 
void PortalSetResultFormat (Portal portal, int nFormats, int16 *formats)
 
bool PortalRun (Portal portal, long count, bool isTopLevel, DestReceiver *dest, DestReceiver *altdest, char *completionTag)
 
uint64 PortalRunFetch (Portal portal, FetchDirection fdirection, long count, DestReceiver *dest)
 

Variables

PGDLLIMPORT Portal ActivePortal
 

Function Documentation

PortalStrategy ChoosePortalStrategy ( List stmts)

Definition at line 215 of file pquery.c.

References PlannedStmt::canSetTag, Query::canSetTag, CMD_SELECT, CMD_UTILITY, PlannedStmt::commandType, Query::commandType, elog, ERROR, PlannedStmt::hasModifyingCTE, Query::hasModifyingCTE, PlannedStmt::hasReturning, IsA, lfirst, linitial, list_length(), NIL, nodeTag, PORTAL_MULTI_QUERY, PORTAL_ONE_MOD_WITH, PORTAL_ONE_RETURNING, PORTAL_ONE_SELECT, PORTAL_UTIL_SELECT, Query::returningList, UtilityReturnsTuples(), PlannedStmt::utilityStmt, and Query::utilityStmt.

Referenced by PlanCacheComputeResultDesc(), and PortalStart().

216 {
217  int nSetTag;
218  ListCell *lc;
219 
220  /*
221  * PORTAL_ONE_SELECT and PORTAL_UTIL_SELECT need only consider the
222  * single-statement case, since there are no rewrite rules that can add
223  * auxiliary queries to a SELECT or a utility command. PORTAL_ONE_MOD_WITH
224  * likewise allows only one top-level statement.
225  */
226  if (list_length(stmts) == 1)
227  {
228  Node *stmt = (Node *) linitial(stmts);
229 
230  if (IsA(stmt, Query))
231  {
232  Query *query = (Query *) stmt;
233 
234  if (query->canSetTag)
235  {
236  if (query->commandType == CMD_SELECT)
237  {
238  if (query->hasModifyingCTE)
239  return PORTAL_ONE_MOD_WITH;
240  else
241  return PORTAL_ONE_SELECT;
242  }
243  if (query->commandType == CMD_UTILITY)
244  {
245  if (UtilityReturnsTuples(query->utilityStmt))
246  return PORTAL_UTIL_SELECT;
247  /* it can't be ONE_RETURNING, so give up */
248  return PORTAL_MULTI_QUERY;
249  }
250  }
251  }
252  else if (IsA(stmt, PlannedStmt))
253  {
254  PlannedStmt *pstmt = (PlannedStmt *) stmt;
255 
256  if (pstmt->canSetTag)
257  {
258  if (pstmt->commandType == CMD_SELECT)
259  {
260  if (pstmt->hasModifyingCTE)
261  return PORTAL_ONE_MOD_WITH;
262  else
263  return PORTAL_ONE_SELECT;
264  }
265  if (pstmt->commandType == CMD_UTILITY)
266  {
267  if (UtilityReturnsTuples(pstmt->utilityStmt))
268  return PORTAL_UTIL_SELECT;
269  /* it can't be ONE_RETURNING, so give up */
270  return PORTAL_MULTI_QUERY;
271  }
272  }
273  }
274  else
275  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(stmt));
276  }
277 
278  /*
279  * PORTAL_ONE_RETURNING has to allow auxiliary queries added by rewrite.
280  * Choose PORTAL_ONE_RETURNING if there is exactly one canSetTag query and
281  * it has a RETURNING list.
282  */
283  nSetTag = 0;
284  foreach(lc, stmts)
285  {
286  Node *stmt = (Node *) lfirst(lc);
287 
288  if (IsA(stmt, Query))
289  {
290  Query *query = (Query *) stmt;
291 
292  if (query->canSetTag)
293  {
294  if (++nSetTag > 1)
295  return PORTAL_MULTI_QUERY; /* no need to look further */
296  if (query->commandType == CMD_UTILITY ||
297  query->returningList == NIL)
298  return PORTAL_MULTI_QUERY; /* no need to look further */
299  }
300  }
301  else if (IsA(stmt, PlannedStmt))
302  {
303  PlannedStmt *pstmt = (PlannedStmt *) stmt;
304 
305  if (pstmt->canSetTag)
306  {
307  if (++nSetTag > 1)
308  return PORTAL_MULTI_QUERY; /* no need to look further */
309  if (pstmt->commandType == CMD_UTILITY ||
310  !pstmt->hasReturning)
311  return PORTAL_MULTI_QUERY; /* no need to look further */
312  }
313  }
314  else
315  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(stmt));
316  }
317  if (nSetTag == 1)
318  return PORTAL_ONE_RETURNING;
319 
320  /* Else, it's the general case... */
321  return PORTAL_MULTI_QUERY;
322 }
#define NIL
Definition: pg_list.h:69
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
Definition: nodes.h:509
Node * utilityStmt
Definition: parsenodes.h:111
#define linitial(l)
Definition: pg_list.h:110
#define ERROR
Definition: elog.h:43
bool hasReturning
Definition: plannodes.h:49
Node * utilityStmt
Definition: plannodes.h:80
bool UtilityReturnsTuples(Node *parsetree)
Definition: utility.c:1694
List * returningList
Definition: parsenodes.h:135
bool canSetTag
Definition: plannodes.h:53
CmdType commandType
Definition: plannodes.h:45
CmdType commandType
Definition: parsenodes.h:103
#define lfirst(lc)
Definition: pg_list.h:106
bool hasModifyingCTE
Definition: plannodes.h:51
bool canSetTag
Definition: parsenodes.h:109
static int list_length(const List *l)
Definition: pg_list.h:89
#define nodeTag(nodeptr)
Definition: nodes.h:514
bool hasModifyingCTE
Definition: parsenodes.h:122
#define elog
Definition: elog.h:219
List* FetchPortalTargetList ( Portal  portal)

Definition at line 332 of file pquery.c.

References FetchStatementTargetList(), NIL, PORTAL_MULTI_QUERY, PortalGetPrimaryStmt(), and PortalData::strategy.

Referenced by exec_describe_portal_message(), FetchStatementTargetList(), and printtup_startup().

333 {
334  /* no point in looking if we determined it doesn't return tuples */
335  if (portal->strategy == PORTAL_MULTI_QUERY)
336  return NIL;
337  /* get the primary statement and find out what it returns */
339 }
#define NIL
Definition: pg_list.h:69
Definition: nodes.h:509
PlannedStmt * PortalGetPrimaryStmt(Portal portal)
Definition: portalmem.c:150
List * FetchStatementTargetList(Node *stmt)
Definition: pquery.c:354
PortalStrategy strategy
Definition: portal.h:142
List* FetchStatementTargetList ( Node stmt)

Definition at line 354 of file pquery.c.

References Assert, CMD_SELECT, CMD_UTILITY, PlannedStmt::commandType, Query::commandType, FetchPortalTargetList(), FetchPreparedStatement(), FetchPreparedStatementTargetList(), GetPortalByName(), PlannedStmt::hasReturning, IsA, FetchStmt::ismove, ExecuteStmt::name, NIL, NULL, PlannedStmt::planTree, PortalIsValid, FetchStmt::portalname, Query::returningList, Plan::targetlist, Query::targetList, PlannedStmt::utilityStmt, and Query::utilityStmt.

Referenced by CachedPlanGetTargetList(), and FetchPortalTargetList().

355 {
356  if (stmt == NULL)
357  return NIL;
358  if (IsA(stmt, Query))
359  {
360  Query *query = (Query *) stmt;
361 
362  if (query->commandType == CMD_UTILITY)
363  {
364  /* transfer attention to utility statement */
365  stmt = query->utilityStmt;
366  }
367  else
368  {
369  if (query->commandType == CMD_SELECT)
370  return query->targetList;
371  if (query->returningList)
372  return query->returningList;
373  return NIL;
374  }
375  }
376  if (IsA(stmt, PlannedStmt))
377  {
378  PlannedStmt *pstmt = (PlannedStmt *) stmt;
379 
380  if (pstmt->commandType == CMD_UTILITY)
381  {
382  /* transfer attention to utility statement */
383  stmt = pstmt->utilityStmt;
384  }
385  else
386  {
387  if (pstmt->commandType == CMD_SELECT)
388  return pstmt->planTree->targetlist;
389  if (pstmt->hasReturning)
390  return pstmt->planTree->targetlist;
391  return NIL;
392  }
393  }
394  if (IsA(stmt, FetchStmt))
395  {
396  FetchStmt *fstmt = (FetchStmt *) stmt;
397  Portal subportal;
398 
399  Assert(!fstmt->ismove);
400  subportal = GetPortalByName(fstmt->portalname);
401  Assert(PortalIsValid(subportal));
402  return FetchPortalTargetList(subportal);
403  }
404  if (IsA(stmt, ExecuteStmt))
405  {
406  ExecuteStmt *estmt = (ExecuteStmt *) stmt;
407  PreparedStatement *entry;
408 
409  entry = FetchPreparedStatement(estmt->name, true);
410  return FetchPreparedStatementTargetList(entry);
411  }
412  return NIL;
413 }
#define NIL
Definition: pg_list.h:69
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
Portal GetPortalByName(const char *name)
Definition: portalmem.c:129
Node * utilityStmt
Definition: parsenodes.h:111
struct Plan * planTree
Definition: plannodes.h:61
List * targetList
Definition: parsenodes.h:131
bool hasReturning
Definition: plannodes.h:49
Node * utilityStmt
Definition: plannodes.h:80
List * returningList
Definition: parsenodes.h:135
char * portalname
Definition: parsenodes.h:2570
#define PortalIsValid(p)
Definition: portal.h:197
bool ismove
Definition: parsenodes.h:2571
CmdType commandType
Definition: plannodes.h:45
List * FetchPreparedStatementTargetList(PreparedStatement *stmt)
Definition: prepare.c:549
CmdType commandType
Definition: parsenodes.h:103
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
List * targetlist
Definition: plannodes.h:129
char * name
Definition: parsenodes.h:3180
List * FetchPortalTargetList(Portal portal)
Definition: pquery.c:332
PreparedStatement * FetchPreparedStatement(const char *stmt_name, bool throwError)
Definition: prepare.c:494
bool PortalRun ( Portal  portal,
long  count,
bool  isTopLevel,
DestReceiver dest,
DestReceiver altdest,
char *  completionTag 
)

Definition at line 682 of file pquery.c.

References ActivePortal, AssertArg, PortalData::atEnd, PortalData::commandTag, COMPLETION_TAG_BUFSIZE, CurrentMemoryContext, CurrentResourceOwner, DEBUG3, elog, ERROR, FillPortalStore(), PortalData::holdStore, log_executor_stats, MarkPortalActive(), MarkPortalDone(), MarkPortalFailed(), MemoryContextSwitchTo(), PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, PORTAL_MULTI_QUERY, PORTAL_ONE_MOD_WITH, PORTAL_ONE_RETURNING, PORTAL_ONE_SELECT, PORTAL_READY, PORTAL_UTIL_SELECT, PortalContext, PortalGetHeapMemory, PortalIsValid, PortalRunMulti(), PortalRunSelect(), ResetUsage(), PortalData::resowner, ShowUsage(), snprintf(), PortalData::status, PortalData::strategy, TopTransactionContext, TopTransactionResourceOwner, and UINT64_FORMAT.

Referenced by exec_execute_message(), exec_simple_query(), and ExecuteQuery().

685 {
686  bool result;
687  uint64 nprocessed;
688  ResourceOwner saveTopTransactionResourceOwner;
689  MemoryContext saveTopTransactionContext;
690  Portal saveActivePortal;
691  ResourceOwner saveResourceOwner;
692  MemoryContext savePortalContext;
693  MemoryContext saveMemoryContext;
694 
695  AssertArg(PortalIsValid(portal));
696 
697  TRACE_POSTGRESQL_QUERY_EXECUTE_START();
698 
699  /* Initialize completion tag to empty string */
700  if (completionTag)
701  completionTag[0] = '\0';
702 
704  {
705  elog(DEBUG3, "PortalRun");
706  /* PORTAL_MULTI_QUERY logs its own stats per query */
707  ResetUsage();
708  }
709 
710  /*
711  * Check for improper portal use, and mark portal active.
712  */
713  MarkPortalActive(portal);
714 
715  /*
716  * Set up global portal context pointers.
717  *
718  * We have to play a special game here to support utility commands like
719  * VACUUM and CLUSTER, which internally start and commit transactions.
720  * When we are called to execute such a command, CurrentResourceOwner will
721  * be pointing to the TopTransactionResourceOwner --- which will be
722  * destroyed and replaced in the course of the internal commit and
723  * restart. So we need to be prepared to restore it as pointing to the
724  * exit-time TopTransactionResourceOwner. (Ain't that ugly? This idea of
725  * internally starting whole new transactions is not good.)
726  * CurrentMemoryContext has a similar problem, but the other pointers we
727  * save here will be NULL or pointing to longer-lived objects.
728  */
729  saveTopTransactionResourceOwner = TopTransactionResourceOwner;
730  saveTopTransactionContext = TopTransactionContext;
731  saveActivePortal = ActivePortal;
732  saveResourceOwner = CurrentResourceOwner;
733  savePortalContext = PortalContext;
734  saveMemoryContext = CurrentMemoryContext;
735  PG_TRY();
736  {
737  ActivePortal = portal;
738  if (portal->resowner)
739  CurrentResourceOwner = portal->resowner;
741 
743 
744  switch (portal->strategy)
745  {
746  case PORTAL_ONE_SELECT:
748  case PORTAL_ONE_MOD_WITH:
749  case PORTAL_UTIL_SELECT:
750 
751  /*
752  * If we have not yet run the command, do so, storing its
753  * results in the portal's tuplestore. But we don't do that
754  * for the PORTAL_ONE_SELECT case.
755  */
756  if (portal->strategy != PORTAL_ONE_SELECT && !portal->holdStore)
757  FillPortalStore(portal, isTopLevel);
758 
759  /*
760  * Now fetch desired portion of results.
761  */
762  nprocessed = PortalRunSelect(portal, true, count, dest);
763 
764  /*
765  * If the portal result contains a command tag and the caller
766  * gave us a pointer to store it, copy it. Patch the "SELECT"
767  * tag to also provide the rowcount.
768  */
769  if (completionTag && portal->commandTag)
770  {
771  if (strcmp(portal->commandTag, "SELECT") == 0)
772  snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
773  "SELECT " UINT64_FORMAT, nprocessed);
774  else
775  strcpy(completionTag, portal->commandTag);
776  }
777 
778  /* Mark portal not active */
779  portal->status = PORTAL_READY;
780 
781  /*
782  * Since it's a forward fetch, say DONE iff atEnd is now true.
783  */
784  result = portal->atEnd;
785  break;
786 
787  case PORTAL_MULTI_QUERY:
788  PortalRunMulti(portal, isTopLevel, false,
789  dest, altdest, completionTag);
790 
791  /* Prevent portal's commands from being re-executed */
792  MarkPortalDone(portal);
793 
794  /* Always complete at end of RunMulti */
795  result = true;
796  break;
797 
798  default:
799  elog(ERROR, "unrecognized portal strategy: %d",
800  (int) portal->strategy);
801  result = false; /* keep compiler quiet */
802  break;
803  }
804  }
805  PG_CATCH();
806  {
807  /* Uncaught error while executing portal: mark it dead */
808  MarkPortalFailed(portal);
809 
810  /* Restore global vars and propagate error */
811  if (saveMemoryContext == saveTopTransactionContext)
813  else
814  MemoryContextSwitchTo(saveMemoryContext);
815  ActivePortal = saveActivePortal;
816  if (saveResourceOwner == saveTopTransactionResourceOwner)
818  else
819  CurrentResourceOwner = saveResourceOwner;
820  PortalContext = savePortalContext;
821 
822  PG_RE_THROW();
823  }
824  PG_END_TRY();
825 
826  if (saveMemoryContext == saveTopTransactionContext)
828  else
829  MemoryContextSwitchTo(saveMemoryContext);
830  ActivePortal = saveActivePortal;
831  if (saveResourceOwner == saveTopTransactionResourceOwner)
833  else
834  CurrentResourceOwner = saveResourceOwner;
835  PortalContext = savePortalContext;
836 
838  ShowUsage("EXECUTOR STATISTICS");
839 
840  TRACE_POSTGRESQL_QUERY_EXECUTE_DONE();
841 
842  return result;
843 }
bool atEnd
Definition: portal.h:185
MemoryContext TopTransactionContext
Definition: mcxt.c:48
#define DEBUG3
Definition: elog.h:23
Portal ActivePortal
Definition: pquery.c:35
ResourceOwner TopTransactionResourceOwner
Definition: resowner.c:140
void ShowUsage(const char *title)
Definition: postgres.c:4383
ResourceOwner CurrentResourceOwner
Definition: resowner.c:138
void MarkPortalActive(Portal portal)
Definition: portalmem.c:388
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
static uint64 PortalRunSelect(Portal portal, bool forward, long count, DestReceiver *dest)
Definition: pquery.c:864
MemoryContext PortalContext
Definition: mcxt.c:52
void ResetUsage(void)
Definition: postgres.c:4376
#define ERROR
Definition: elog.h:43
static void FillPortalStore(Portal portal, bool isTopLevel)
Definition: pquery.c:995
const char * commandTag
Definition: portal.h:135
void MarkPortalDone(Portal portal)
Definition: portalmem.c:407
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
PortalStrategy strategy
Definition: portal.h:142
#define AssertArg(condition)
Definition: c.h:673
#define PortalIsValid(p)
Definition: portal.h:197
#define PG_CATCH()
Definition: elog.h:293
#define COMPLETION_TAG_BUFSIZE
Definition: dest.h:74
static void PortalRunMulti(Portal portal, bool isTopLevel, bool setHoldSnapshot, DestReceiver *dest, DestReceiver *altdest, char *completionTag)
Definition: pquery.c:1191
#define PortalGetHeapMemory(portal)
Definition: portal.h:203
void MarkPortalFailed(Portal portal)
Definition: portalmem.c:435
PortalStatus status
Definition: portal.h:146
#define PG_RE_THROW()
Definition: elog.h:314
ResourceOwner resowner
Definition: portal.h:120
Tuplestorestate * holdStore
Definition: portal.h:162
bool log_executor_stats
Definition: guc.c:442
#define elog
Definition: elog.h:219
#define PG_TRY()
Definition: elog.h:284
#define UINT64_FORMAT
Definition: c.h:313
#define PG_END_TRY()
Definition: elog.h:300
uint64 PortalRunFetch ( Portal  portal,
FetchDirection  fdirection,
long  count,
DestReceiver dest 
)

Definition at line 1379 of file pquery.c.

References ActivePortal, AssertArg, CurrentResourceOwner, DoPortalRunFetch(), elog, ERROR, FillPortalStore(), PortalData::holdStore, MarkPortalActive(), MarkPortalFailed(), MemoryContextSwitchTo(), PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, PORTAL_ONE_MOD_WITH, PORTAL_ONE_RETURNING, PORTAL_ONE_SELECT, PORTAL_READY, PORTAL_UTIL_SELECT, PortalContext, PortalGetHeapMemory, PortalIsValid, PortalData::resowner, PortalData::status, and PortalData::strategy.

Referenced by _SPI_cursor_operation(), and PerformPortalFetch().

1383 {
1384  uint64 result;
1385  Portal saveActivePortal;
1386  ResourceOwner saveResourceOwner;
1387  MemoryContext savePortalContext;
1388  MemoryContext oldContext;
1389 
1390  AssertArg(PortalIsValid(portal));
1391 
1392  /*
1393  * Check for improper portal use, and mark portal active.
1394  */
1395  MarkPortalActive(portal);
1396 
1397  /*
1398  * Set up global portal context pointers.
1399  */
1400  saveActivePortal = ActivePortal;
1401  saveResourceOwner = CurrentResourceOwner;
1402  savePortalContext = PortalContext;
1403  PG_TRY();
1404  {
1405  ActivePortal = portal;
1406  if (portal->resowner)
1407  CurrentResourceOwner = portal->resowner;
1409 
1410  oldContext = MemoryContextSwitchTo(PortalContext);
1411 
1412  switch (portal->strategy)
1413  {
1414  case PORTAL_ONE_SELECT:
1415  result = DoPortalRunFetch(portal, fdirection, count, dest);
1416  break;
1417 
1418  case PORTAL_ONE_RETURNING:
1419  case PORTAL_ONE_MOD_WITH:
1420  case PORTAL_UTIL_SELECT:
1421 
1422  /*
1423  * If we have not yet run the command, do so, storing its
1424  * results in the portal's tuplestore.
1425  */
1426  if (!portal->holdStore)
1427  FillPortalStore(portal, false /* isTopLevel */ );
1428 
1429  /*
1430  * Now fetch desired portion of results.
1431  */
1432  result = DoPortalRunFetch(portal, fdirection, count, dest);
1433  break;
1434 
1435  default:
1436  elog(ERROR, "unsupported portal strategy");
1437  result = 0; /* keep compiler quiet */
1438  break;
1439  }
1440  }
1441  PG_CATCH();
1442  {
1443  /* Uncaught error while executing portal: mark it dead */
1444  MarkPortalFailed(portal);
1445 
1446  /* Restore global vars and propagate error */
1447  ActivePortal = saveActivePortal;
1448  CurrentResourceOwner = saveResourceOwner;
1449  PortalContext = savePortalContext;
1450 
1451  PG_RE_THROW();
1452  }
1453  PG_END_TRY();
1454 
1455  MemoryContextSwitchTo(oldContext);
1456 
1457  /* Mark portal not active */
1458  portal->status = PORTAL_READY;
1459 
1460  ActivePortal = saveActivePortal;
1461  CurrentResourceOwner = saveResourceOwner;
1462  PortalContext = savePortalContext;
1463 
1464  return result;
1465 }
Portal ActivePortal
Definition: pquery.c:35
ResourceOwner CurrentResourceOwner
Definition: resowner.c:138
void MarkPortalActive(Portal portal)
Definition: portalmem.c:388
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static uint64 DoPortalRunFetch(Portal portal, FetchDirection fdirection, long count, DestReceiver *dest)
Definition: pquery.c:1478
MemoryContext PortalContext
Definition: mcxt.c:52
#define ERROR
Definition: elog.h:43
static void FillPortalStore(Portal portal, bool isTopLevel)
Definition: pquery.c:995
PortalStrategy strategy
Definition: portal.h:142
#define AssertArg(condition)
Definition: c.h:673
#define PortalIsValid(p)
Definition: portal.h:197
#define PG_CATCH()
Definition: elog.h:293
#define PortalGetHeapMemory(portal)
Definition: portal.h:203
void MarkPortalFailed(Portal portal)
Definition: portalmem.c:435
PortalStatus status
Definition: portal.h:146
#define PG_RE_THROW()
Definition: elog.h:314
ResourceOwner resowner
Definition: portal.h:120
Tuplestorestate * holdStore
Definition: portal.h:162
#define elog
Definition: elog.h:219
#define PG_TRY()
Definition: elog.h:284
#define PG_END_TRY()
Definition: elog.h:300
void PortalSetResultFormat ( Portal  portal,
int  nFormats,
int16 formats 
)

Definition at line 620 of file pquery.c.

References ereport, errcode(), errmsg(), ERROR, PortalData::formats, i, MemoryContextAlloc(), tupleDesc::natts, NULL, PortalGetHeapMemory, and PortalData::tupDesc.

Referenced by exec_bind_message(), and exec_simple_query().

621 {
622  int natts;
623  int i;
624 
625  /* Do nothing if portal won't return tuples */
626  if (portal->tupDesc == NULL)
627  return;
628  natts = portal->tupDesc->natts;
629  portal->formats = (int16 *)
631  natts * sizeof(int16));
632  if (nFormats > 1)
633  {
634  /* format specified for each column */
635  if (nFormats != natts)
636  ereport(ERROR,
637  (errcode(ERRCODE_PROTOCOL_VIOLATION),
638  errmsg("bind message has %d result formats but query has %d columns",
639  nFormats, natts)));
640  memcpy(portal->formats, formats, natts * sizeof(int16));
641  }
642  else if (nFormats > 0)
643  {
644  /* single format specified, use for all columns */
645  int16 format1 = formats[0];
646 
647  for (i = 0; i < natts; i++)
648  portal->formats[i] = format1;
649  }
650  else
651  {
652  /* use default format for all columns */
653  for (i = 0; i < natts; i++)
654  portal->formats[i] = 0;
655  }
656 }
signed short int16
Definition: c.h:252
int errcode(int sqlerrcode)
Definition: elog.c:575
int natts
Definition: tupdesc.h:73
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
int16 * formats
Definition: portal.h:155
TupleDesc tupDesc
Definition: portal.h:153
#define NULL
Definition: c.h:226
#define PortalGetHeapMemory(portal)
Definition: portal.h:203
int errmsg(const char *fmt,...)
Definition: elog.c:797
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:749
int i
void PortalStart ( Portal  portal,
ParamListInfo  params,
int  eflags,
Snapshot  snapshot 
)

Definition at line 439 of file pquery.c.

References ActivePortal, Assert, AssertArg, AssertState, PortalData::atEnd, PortalData::atStart, castNode, ChoosePortalStrategy(), CMD_UTILITY, PlannedStmt::commandType, CreateQueryDesc(), CurrentResourceOwner, CURSOR_OPT_SCROLL, PortalData::cursorOptions, EXEC_FLAG_BACKWARD, EXEC_FLAG_REWIND, ExecCleanTypeFromTL(), ExecutorStart(), GetActiveSnapshot(), GetTransactionSnapshot(), InvalidSnapshot, linitial, MarkPortalFailed(), MemoryContextSwitchTo(), None_Receiver, NULL, PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, PlannedStmt::planTree, PopActiveSnapshot(), PORTAL_DEFINED, PORTAL_MULTI_QUERY, PORTAL_ONE_MOD_WITH, PORTAL_ONE_RETURNING, PORTAL_ONE_SELECT, PORTAL_READY, PORTAL_UTIL_SELECT, PortalContext, PortalGetHeapMemory, PortalGetPrimaryStmt(), PortalIsValid, PortalData::portalParams, PortalData::portalPos, PushActiveSnapshot(), PortalData::queryDesc, PortalData::resowner, PortalData::sourceText, PortalData::status, PortalData::stmts, PortalData::strategy, Plan::targetlist, QueryDesc::tupDesc, PortalData::tupDesc, PlannedStmt::utilityStmt, and UtilityTupleDescriptor().

Referenced by exec_bind_message(), exec_simple_query(), ExecuteQuery(), PerformCursorOpen(), and SPI_cursor_open_internal().

441 {
442  Portal saveActivePortal;
443  ResourceOwner saveResourceOwner;
444  MemoryContext savePortalContext;
445  MemoryContext oldContext;
446  QueryDesc *queryDesc;
447  int myeflags;
448 
449  AssertArg(PortalIsValid(portal));
450  AssertState(portal->status == PORTAL_DEFINED);
451 
452  /*
453  * Set up global portal context pointers.
454  */
455  saveActivePortal = ActivePortal;
456  saveResourceOwner = CurrentResourceOwner;
457  savePortalContext = PortalContext;
458  PG_TRY();
459  {
460  ActivePortal = portal;
461  if (portal->resowner)
462  CurrentResourceOwner = portal->resowner;
464 
465  oldContext = MemoryContextSwitchTo(PortalGetHeapMemory(portal));
466 
467  /* Must remember portal param list, if any */
468  portal->portalParams = params;
469 
470  /*
471  * Determine the portal execution strategy
472  */
473  portal->strategy = ChoosePortalStrategy(portal->stmts);
474 
475  /*
476  * Fire her up according to the strategy
477  */
478  switch (portal->strategy)
479  {
480  case PORTAL_ONE_SELECT:
481 
482  /* Must set snapshot before starting executor. */
483  if (snapshot)
484  PushActiveSnapshot(snapshot);
485  else
487 
488  /*
489  * Create QueryDesc in portal's context; for the moment, set
490  * the destination to DestNone.
491  */
492  queryDesc = CreateQueryDesc(castNode(PlannedStmt, linitial(portal->stmts)),
493  portal->sourceText,
497  params,
498  0);
499 
500  /*
501  * If it's a scrollable cursor, executor needs to support
502  * REWIND and backwards scan, as well as whatever the caller
503  * might've asked for.
504  */
505  if (portal->cursorOptions & CURSOR_OPT_SCROLL)
506  myeflags = eflags | EXEC_FLAG_REWIND | EXEC_FLAG_BACKWARD;
507  else
508  myeflags = eflags;
509 
510  /*
511  * Call ExecutorStart to prepare the plan for execution
512  */
513  ExecutorStart(queryDesc, myeflags);
514 
515  /*
516  * This tells PortalCleanup to shut down the executor
517  */
518  portal->queryDesc = queryDesc;
519 
520  /*
521  * Remember tuple descriptor (computed by ExecutorStart)
522  */
523  portal->tupDesc = queryDesc->tupDesc;
524 
525  /*
526  * Reset cursor position data to "start of query"
527  */
528  portal->atStart = true;
529  portal->atEnd = false; /* allow fetches */
530  portal->portalPos = 0;
531 
533  break;
534 
536  case PORTAL_ONE_MOD_WITH:
537 
538  /*
539  * We don't start the executor until we are told to run the
540  * portal. We do need to set up the result tupdesc.
541  */
542  {
543  PlannedStmt *pstmt;
544 
545  pstmt = PortalGetPrimaryStmt(portal);
546  portal->tupDesc =
548  false);
549  }
550 
551  /*
552  * Reset cursor position data to "start of query"
553  */
554  portal->atStart = true;
555  portal->atEnd = false; /* allow fetches */
556  portal->portalPos = 0;
557  break;
558 
559  case PORTAL_UTIL_SELECT:
560 
561  /*
562  * We don't set snapshot here, because PortalRunUtility will
563  * take care of it if needed.
564  */
565  {
566  PlannedStmt *pstmt = PortalGetPrimaryStmt(portal);
567 
568  Assert(pstmt->commandType == CMD_UTILITY);
569  portal->tupDesc = UtilityTupleDescriptor(pstmt->utilityStmt);
570  }
571 
572  /*
573  * Reset cursor position data to "start of query"
574  */
575  portal->atStart = true;
576  portal->atEnd = false; /* allow fetches */
577  portal->portalPos = 0;
578  break;
579 
580  case PORTAL_MULTI_QUERY:
581  /* Need do nothing now */
582  portal->tupDesc = NULL;
583  break;
584  }
585  }
586  PG_CATCH();
587  {
588  /* Uncaught error while executing portal: mark it dead */
589  MarkPortalFailed(portal);
590 
591  /* Restore global vars and propagate error */
592  ActivePortal = saveActivePortal;
593  CurrentResourceOwner = saveResourceOwner;
594  PortalContext = savePortalContext;
595 
596  PG_RE_THROW();
597  }
598  PG_END_TRY();
599 
600  MemoryContextSwitchTo(oldContext);
601 
602  ActivePortal = saveActivePortal;
603  CurrentResourceOwner = saveResourceOwner;
604  PortalContext = savePortalContext;
605 
606  portal->status = PORTAL_READY;
607 }
#define AssertState(condition)
Definition: c.h:674
bool atEnd
Definition: portal.h:185
#define castNode(_type_, nodeptr)
Definition: nodes.h:578
Portal ActivePortal
Definition: pquery.c:35
ResourceOwner CurrentResourceOwner
Definition: resowner.c:138
void ExecutorStart(QueryDesc *queryDesc, int eflags)
Definition: execMain.c:138
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Snapshot GetActiveSnapshot(void)
Definition: snapmgr.c:834
void PopActiveSnapshot(void)
Definition: snapmgr.c:807
QueryDesc * CreateQueryDesc(PlannedStmt *plannedstmt, const char *sourceText, Snapshot snapshot, Snapshot crosscheck_snapshot, DestReceiver *dest, ParamListInfo params, int instrument_options)
Definition: pquery.c:66
List * stmts
Definition: portal.h:136
DestReceiver * None_Receiver
Definition: dest.c:91
Snapshot GetTransactionSnapshot(void)
Definition: snapmgr.c:300
struct Plan * planTree
Definition: plannodes.h:61
MemoryContext PortalContext
Definition: mcxt.c:52
ParamListInfo portalParams
Definition: portal.h:139
PlannedStmt * PortalGetPrimaryStmt(Portal portal)
Definition: portalmem.c:150
#define linitial(l)
Definition: pg_list.h:110
#define EXEC_FLAG_BACKWARD
Definition: executor.h:60
void PushActiveSnapshot(Snapshot snap)
Definition: snapmgr.c:728
Node * utilityStmt
Definition: plannodes.h:80
PortalStrategy strategy
Definition: portal.h:142
#define EXEC_FLAG_REWIND
Definition: executor.h:59
#define AssertArg(condition)
Definition: c.h:673
QueryDesc * queryDesc
Definition: portal.h:150
TupleDesc tupDesc
Definition: execdesc.h:46
#define InvalidSnapshot
Definition: snapshot.h:25
#define PortalIsValid(p)
Definition: portal.h:197
CmdType commandType
Definition: plannodes.h:45
const char * sourceText
Definition: portal.h:134
TupleDesc tupDesc
Definition: portal.h:153
#define PG_CATCH()
Definition: elog.h:293
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
#define PortalGetHeapMemory(portal)
Definition: portal.h:203
void MarkPortalFailed(Portal portal)
Definition: portalmem.c:435
PortalStatus status
Definition: portal.h:146
#define PG_RE_THROW()
Definition: elog.h:314
PortalStrategy ChoosePortalStrategy(List *stmts)
Definition: pquery.c:215
List * targetlist
Definition: plannodes.h:129
ResourceOwner resowner
Definition: portal.h:120
bool atStart
Definition: portal.h:184
#define CURSOR_OPT_SCROLL
Definition: parsenodes.h:2520
TupleDesc ExecCleanTypeFromTL(List *targetList, bool hasoid)
Definition: execTuples.c:900
int cursorOptions
Definition: portal.h:143
#define PG_TRY()
Definition: elog.h:284
TupleDesc UtilityTupleDescriptor(Node *parsetree)
Definition: utility.c:1744
#define PG_END_TRY()
Definition: elog.h:300
uint64 portalPos
Definition: portal.h:186

Variable Documentation