PostgreSQL Source Code  git master
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, bool run_once, DestReceiver *dest, DestReceiver *altdest, QueryCompletion *qc)
 
uint64 PortalRunFetch (Portal portal, FetchDirection fdirection, long count, DestReceiver *dest)
 

Variables

PGDLLIMPORT Portal ActivePortal
 

Function Documentation

◆ ChoosePortalStrategy()

PortalStrategy ChoosePortalStrategy ( List stmts)

Definition at line 206 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().

207 {
208  int nSetTag;
209  ListCell *lc;
210 
211  /*
212  * PORTAL_ONE_SELECT and PORTAL_UTIL_SELECT need only consider the
213  * single-statement case, since there are no rewrite rules that can add
214  * auxiliary queries to a SELECT or a utility command. PORTAL_ONE_MOD_WITH
215  * likewise allows only one top-level statement.
216  */
217  if (list_length(stmts) == 1)
218  {
219  Node *stmt = (Node *) linitial(stmts);
220 
221  if (IsA(stmt, Query))
222  {
223  Query *query = (Query *) stmt;
224 
225  if (query->canSetTag)
226  {
227  if (query->commandType == CMD_SELECT)
228  {
229  if (query->hasModifyingCTE)
230  return PORTAL_ONE_MOD_WITH;
231  else
232  return PORTAL_ONE_SELECT;
233  }
234  if (query->commandType == CMD_UTILITY)
235  {
236  if (UtilityReturnsTuples(query->utilityStmt))
237  return PORTAL_UTIL_SELECT;
238  /* it can't be ONE_RETURNING, so give up */
239  return PORTAL_MULTI_QUERY;
240  }
241  }
242  }
243  else if (IsA(stmt, PlannedStmt))
244  {
245  PlannedStmt *pstmt = (PlannedStmt *) stmt;
246 
247  if (pstmt->canSetTag)
248  {
249  if (pstmt->commandType == CMD_SELECT)
250  {
251  if (pstmt->hasModifyingCTE)
252  return PORTAL_ONE_MOD_WITH;
253  else
254  return PORTAL_ONE_SELECT;
255  }
256  if (pstmt->commandType == CMD_UTILITY)
257  {
258  if (UtilityReturnsTuples(pstmt->utilityStmt))
259  return PORTAL_UTIL_SELECT;
260  /* it can't be ONE_RETURNING, so give up */
261  return PORTAL_MULTI_QUERY;
262  }
263  }
264  }
265  else
266  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(stmt));
267  }
268 
269  /*
270  * PORTAL_ONE_RETURNING has to allow auxiliary queries added by rewrite.
271  * Choose PORTAL_ONE_RETURNING if there is exactly one canSetTag query and
272  * it has a RETURNING list.
273  */
274  nSetTag = 0;
275  foreach(lc, stmts)
276  {
277  Node *stmt = (Node *) lfirst(lc);
278 
279  if (IsA(stmt, Query))
280  {
281  Query *query = (Query *) stmt;
282 
283  if (query->canSetTag)
284  {
285  if (++nSetTag > 1)
286  return PORTAL_MULTI_QUERY; /* no need to look further */
287  if (query->commandType == CMD_UTILITY ||
288  query->returningList == NIL)
289  return PORTAL_MULTI_QUERY; /* no need to look further */
290  }
291  }
292  else if (IsA(stmt, PlannedStmt))
293  {
294  PlannedStmt *pstmt = (PlannedStmt *) stmt;
295 
296  if (pstmt->canSetTag)
297  {
298  if (++nSetTag > 1)
299  return PORTAL_MULTI_QUERY; /* no need to look further */
300  if (pstmt->commandType == CMD_UTILITY ||
301  !pstmt->hasReturning)
302  return PORTAL_MULTI_QUERY; /* no need to look further */
303  }
304  }
305  else
306  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(stmt));
307  }
308  if (nSetTag == 1)
309  return PORTAL_ONE_RETURNING;
310 
311  /* Else, it's the general case... */
312  return PORTAL_MULTI_QUERY;
313 }
#define NIL
Definition: pg_list.h:65
#define IsA(nodeptr, _type_)
Definition: nodes.h:580
Definition: nodes.h:529
Node * utilityStmt
Definition: parsenodes.h:120
#define linitial(l)
Definition: pg_list.h:195
#define ERROR
Definition: elog.h:43
bool hasReturning
Definition: plannodes.h:50
Node * utilityStmt
Definition: plannodes.h:92
bool UtilityReturnsTuples(Node *parsetree)
Definition: utility.c:1913
List * returningList
Definition: parsenodes.h:146
bool canSetTag
Definition: plannodes.h:54
CmdType commandType
Definition: plannodes.h:46
CmdType commandType
Definition: parsenodes.h:112
#define lfirst(lc)
Definition: pg_list.h:190
bool hasModifyingCTE
Definition: plannodes.h:52
bool canSetTag
Definition: parsenodes.h:118
static int list_length(const List *l)
Definition: pg_list.h:169
#define nodeTag(nodeptr)
Definition: nodes.h:534
#define elog(elevel,...)
Definition: elog.h:214
bool hasModifyingCTE
Definition: parsenodes.h:131

◆ FetchPortalTargetList()

List* FetchPortalTargetList ( Portal  portal)

Definition at line 323 of file pquery.c.

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

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

324 {
325  /* no point in looking if we determined it doesn't return tuples */
326  if (portal->strategy == PORTAL_MULTI_QUERY)
327  return NIL;
328  /* get the primary statement and find out what it returns */
330 }
#define NIL
Definition: pg_list.h:65
Definition: nodes.h:529
PlannedStmt * PortalGetPrimaryStmt(Portal portal)
Definition: portalmem.c:151
List * FetchStatementTargetList(Node *stmt)
Definition: pquery.c:345
PortalStrategy strategy
Definition: portal.h:145

◆ FetchStatementTargetList()

List* FetchStatementTargetList ( Node stmt)

Definition at line 345 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, PlannedStmt::planTree, PortalIsValid, FetchStmt::portalname, Query::returningList, Query::targetList, Plan::targetlist, PlannedStmt::utilityStmt, and Query::utilityStmt.

Referenced by CachedPlanGetTargetList(), and FetchPortalTargetList().

346 {
347  if (stmt == NULL)
348  return NIL;
349  if (IsA(stmt, Query))
350  {
351  Query *query = (Query *) stmt;
352 
353  if (query->commandType == CMD_UTILITY)
354  {
355  /* transfer attention to utility statement */
356  stmt = query->utilityStmt;
357  }
358  else
359  {
360  if (query->commandType == CMD_SELECT)
361  return query->targetList;
362  if (query->returningList)
363  return query->returningList;
364  return NIL;
365  }
366  }
367  if (IsA(stmt, PlannedStmt))
368  {
369  PlannedStmt *pstmt = (PlannedStmt *) stmt;
370 
371  if (pstmt->commandType == CMD_UTILITY)
372  {
373  /* transfer attention to utility statement */
374  stmt = pstmt->utilityStmt;
375  }
376  else
377  {
378  if (pstmt->commandType == CMD_SELECT)
379  return pstmt->planTree->targetlist;
380  if (pstmt->hasReturning)
381  return pstmt->planTree->targetlist;
382  return NIL;
383  }
384  }
385  if (IsA(stmt, FetchStmt))
386  {
387  FetchStmt *fstmt = (FetchStmt *) stmt;
388  Portal subportal;
389 
390  Assert(!fstmt->ismove);
391  subportal = GetPortalByName(fstmt->portalname);
392  Assert(PortalIsValid(subportal));
393  return FetchPortalTargetList(subportal);
394  }
395  if (IsA(stmt, ExecuteStmt))
396  {
397  ExecuteStmt *estmt = (ExecuteStmt *) stmt;
398  PreparedStatement *entry;
399 
400  entry = FetchPreparedStatement(estmt->name, true);
401  return FetchPreparedStatementTargetList(entry);
402  }
403  return NIL;
404 }
#define NIL
Definition: pg_list.h:65
#define IsA(nodeptr, _type_)
Definition: nodes.h:580
Portal GetPortalByName(const char *name)
Definition: portalmem.c:130
Node * utilityStmt
Definition: parsenodes.h:120
struct Plan * planTree
Definition: plannodes.h:64
List * targetList
Definition: parsenodes.h:140
bool hasReturning
Definition: plannodes.h:50
Node * utilityStmt
Definition: plannodes.h:92
List * returningList
Definition: parsenodes.h:146
char * portalname
Definition: parsenodes.h:2757
#define PortalIsValid(p)
Definition: portal.h:203
bool ismove
Definition: parsenodes.h:2758
CmdType commandType
Definition: plannodes.h:46
List * FetchPreparedStatementTargetList(PreparedStatement *stmt)
Definition: prepare.c:524
CmdType commandType
Definition: parsenodes.h:112
#define Assert(condition)
Definition: c.h:738
List * targetlist
Definition: plannodes.h:142
char * name
Definition: parsenodes.h:3438
List * FetchPortalTargetList(Portal portal)
Definition: pquery.c:323
PreparedStatement * FetchPreparedStatement(const char *stmt_name, bool throwError)
Definition: prepare.c:469

◆ PortalRun()

bool PortalRun ( Portal  portal,
long  count,
bool  isTopLevel,
bool  run_once,
DestReceiver dest,
DestReceiver altdest,
QueryCompletion qc 
)

Definition at line 672 of file pquery.c.

References ActivePortal, Assert, AssertArg, PortalData::atEnd, QueryCompletion::commandTag, CopyQueryCompletion(), CurrentMemoryContext, CurrentResourceOwner, DEBUG3, elog, ERROR, FillPortalStore(), PortalData::holdStore, InitializeQueryCompletion(), log_executor_stats, MarkPortalActive(), MarkPortalDone(), MarkPortalFailed(), MemoryContextSwitchTo(), QueryCompletion::nprocessed, 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, PortalData::portalContext, PortalIsValid, PortalRunMulti(), PortalRunSelect(), PortalData::qc, ResetUsage(), PortalData::resowner, PortalData::run_once, ShowUsage(), PortalData::status, PortalData::strategy, TopTransactionContext, and TopTransactionResourceOwner.

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

675 {
676  bool result;
677  uint64 nprocessed;
678  ResourceOwner saveTopTransactionResourceOwner;
679  MemoryContext saveTopTransactionContext;
680  Portal saveActivePortal;
681  ResourceOwner saveResourceOwner;
682  MemoryContext savePortalContext;
683  MemoryContext saveMemoryContext;
684 
685  AssertArg(PortalIsValid(portal));
686 
687  TRACE_POSTGRESQL_QUERY_EXECUTE_START();
688 
689  /* Initialize empty completion data */
690  if (qc)
692 
694  {
695  elog(DEBUG3, "PortalRun");
696  /* PORTAL_MULTI_QUERY logs its own stats per query */
697  ResetUsage();
698  }
699 
700  /*
701  * Check for improper portal use, and mark portal active.
702  */
703  MarkPortalActive(portal);
704 
705  /* Set run_once flag. Shouldn't be clear if previously set. */
706  Assert(!portal->run_once || run_once);
707  portal->run_once = run_once;
708 
709  /*
710  * Set up global portal context pointers.
711  *
712  * We have to play a special game here to support utility commands like
713  * VACUUM and CLUSTER, which internally start and commit transactions.
714  * When we are called to execute such a command, CurrentResourceOwner will
715  * be pointing to the TopTransactionResourceOwner --- which will be
716  * destroyed and replaced in the course of the internal commit and
717  * restart. So we need to be prepared to restore it as pointing to the
718  * exit-time TopTransactionResourceOwner. (Ain't that ugly? This idea of
719  * internally starting whole new transactions is not good.)
720  * CurrentMemoryContext has a similar problem, but the other pointers we
721  * save here will be NULL or pointing to longer-lived objects.
722  */
723  saveTopTransactionResourceOwner = TopTransactionResourceOwner;
724  saveTopTransactionContext = TopTransactionContext;
725  saveActivePortal = ActivePortal;
726  saveResourceOwner = CurrentResourceOwner;
727  savePortalContext = PortalContext;
728  saveMemoryContext = CurrentMemoryContext;
729  PG_TRY();
730  {
731  ActivePortal = portal;
732  if (portal->resowner)
733  CurrentResourceOwner = portal->resowner;
734  PortalContext = portal->portalContext;
735 
737 
738  switch (portal->strategy)
739  {
740  case PORTAL_ONE_SELECT:
742  case PORTAL_ONE_MOD_WITH:
743  case PORTAL_UTIL_SELECT:
744 
745  /*
746  * If we have not yet run the command, do so, storing its
747  * results in the portal's tuplestore. But we don't do that
748  * for the PORTAL_ONE_SELECT case.
749  */
750  if (portal->strategy != PORTAL_ONE_SELECT && !portal->holdStore)
751  FillPortalStore(portal, isTopLevel);
752 
753  /*
754  * Now fetch desired portion of results.
755  */
756  nprocessed = PortalRunSelect(portal, true, count, dest);
757 
758  /*
759  * If the portal result contains a command tag and the caller
760  * gave us a pointer to store it, copy it and update the
761  * rowcount.
762  */
763  if (qc && portal->qc.commandTag != CMDTAG_UNKNOWN)
764  {
765  CopyQueryCompletion(qc, &portal->qc);
766  qc->nprocessed = nprocessed;
767  }
768 
769  /* Mark portal not active */
770  portal->status = PORTAL_READY;
771 
772  /*
773  * Since it's a forward fetch, say DONE iff atEnd is now true.
774  */
775  result = portal->atEnd;
776  break;
777 
778  case PORTAL_MULTI_QUERY:
779  PortalRunMulti(portal, isTopLevel, false,
780  dest, altdest, qc);
781 
782  /* Prevent portal's commands from being re-executed */
783  MarkPortalDone(portal);
784 
785  /* Always complete at end of RunMulti */
786  result = true;
787  break;
788 
789  default:
790  elog(ERROR, "unrecognized portal strategy: %d",
791  (int) portal->strategy);
792  result = false; /* keep compiler quiet */
793  break;
794  }
795  }
796  PG_CATCH();
797  {
798  /* Uncaught error while executing portal: mark it dead */
799  MarkPortalFailed(portal);
800 
801  /* Restore global vars and propagate error */
802  if (saveMemoryContext == saveTopTransactionContext)
804  else
805  MemoryContextSwitchTo(saveMemoryContext);
806  ActivePortal = saveActivePortal;
807  if (saveResourceOwner == saveTopTransactionResourceOwner)
809  else
810  CurrentResourceOwner = saveResourceOwner;
811  PortalContext = savePortalContext;
812 
813  PG_RE_THROW();
814  }
815  PG_END_TRY();
816 
817  if (saveMemoryContext == saveTopTransactionContext)
819  else
820  MemoryContextSwitchTo(saveMemoryContext);
821  ActivePortal = saveActivePortal;
822  if (saveResourceOwner == saveTopTransactionResourceOwner)
824  else
825  CurrentResourceOwner = saveResourceOwner;
826  PortalContext = savePortalContext;
827 
829  ShowUsage("EXECUTOR STATISTICS");
830 
831  TRACE_POSTGRESQL_QUERY_EXECUTE_DONE();
832 
833  return result;
834 }
bool atEnd
Definition: portal.h:191
MemoryContext TopTransactionContext
Definition: mcxt.c:49
#define DEBUG3
Definition: elog.h:23
Portal ActivePortal
Definition: pquery.c:35
ResourceOwner TopTransactionResourceOwner
Definition: resowner.c:144
void ShowUsage(const char *title)
Definition: postgres.c:4618
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
void MarkPortalActive(Portal portal)
Definition: portalmem.c:394
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext portalContext
Definition: portal.h:120
static uint64 PortalRunSelect(Portal portal, bool forward, long count, DestReceiver *dest)
Definition: pquery.c:855
bool run_once
Definition: portal.h:147
MemoryContext PortalContext
Definition: mcxt.c:53
void ResetUsage(void)
Definition: postgres.c:4611
#define ERROR
Definition: elog.h:43
uint64 nprocessed
Definition: cmdtag.h:31
void InitializeQueryCompletion(QueryCompletion *qc)
Definition: cmdtag.c:38
static void FillPortalStore(Portal portal, bool isTopLevel)
Definition: pquery.c:988
void MarkPortalDone(Portal portal)
Definition: portalmem.c:413
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
PortalStrategy strategy
Definition: portal.h:145
#define AssertArg(condition)
Definition: c.h:740
#define PortalIsValid(p)
Definition: portal.h:203
CommandTag commandTag
Definition: cmdtag.h:30
static void CopyQueryCompletion(QueryCompletion *dst, const QueryCompletion *src)
Definition: cmdtag.h:44
#define PG_CATCH()
Definition: elog.h:305
QueryCompletion qc
Definition: portal.h:137
#define Assert(condition)
Definition: c.h:738
void MarkPortalFailed(Portal portal)
Definition: portalmem.c:441
PortalStatus status
Definition: portal.h:150
#define PG_RE_THROW()
Definition: elog.h:336
ResourceOwner resowner
Definition: portal.h:121
Tuplestorestate * holdStore
Definition: portal.h:168
#define elog(elevel,...)
Definition: elog.h:214
bool log_executor_stats
Definition: guc.c:526
static void PortalRunMulti(Portal portal, bool isTopLevel, bool setHoldSnapshot, DestReceiver *dest, DestReceiver *altdest, QueryCompletion *qc)
Definition: pquery.c:1184
#define PG_TRY()
Definition: elog.h:295
#define PG_END_TRY()
Definition: elog.h:320

◆ PortalRunFetch()

uint64 PortalRunFetch ( Portal  portal,
FetchDirection  fdirection,
long  count,
DestReceiver dest 
)

Definition at line 1368 of file pquery.c.

References ActivePortal, Assert, 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, PortalData::portalContext, PortalIsValid, PortalData::resowner, PortalData::run_once, PortalData::status, and PortalData::strategy.

Referenced by _SPI_cursor_operation(), and PerformPortalFetch().

1372 {
1373  uint64 result;
1374  Portal saveActivePortal;
1375  ResourceOwner saveResourceOwner;
1376  MemoryContext savePortalContext;
1377  MemoryContext oldContext;
1378 
1379  AssertArg(PortalIsValid(portal));
1380 
1381  /*
1382  * Check for improper portal use, and mark portal active.
1383  */
1384  MarkPortalActive(portal);
1385 
1386  /* If supporting FETCH, portal can't be run-once. */
1387  Assert(!portal->run_once);
1388 
1389  /*
1390  * Set up global portal context pointers.
1391  */
1392  saveActivePortal = ActivePortal;
1393  saveResourceOwner = CurrentResourceOwner;
1394  savePortalContext = PortalContext;
1395  PG_TRY();
1396  {
1397  ActivePortal = portal;
1398  if (portal->resowner)
1399  CurrentResourceOwner = portal->resowner;
1400  PortalContext = portal->portalContext;
1401 
1402  oldContext = MemoryContextSwitchTo(PortalContext);
1403 
1404  switch (portal->strategy)
1405  {
1406  case PORTAL_ONE_SELECT:
1407  result = DoPortalRunFetch(portal, fdirection, count, dest);
1408  break;
1409 
1410  case PORTAL_ONE_RETURNING:
1411  case PORTAL_ONE_MOD_WITH:
1412  case PORTAL_UTIL_SELECT:
1413 
1414  /*
1415  * If we have not yet run the command, do so, storing its
1416  * results in the portal's tuplestore.
1417  */
1418  if (!portal->holdStore)
1419  FillPortalStore(portal, false /* isTopLevel */ );
1420 
1421  /*
1422  * Now fetch desired portion of results.
1423  */
1424  result = DoPortalRunFetch(portal, fdirection, count, dest);
1425  break;
1426 
1427  default:
1428  elog(ERROR, "unsupported portal strategy");
1429  result = 0; /* keep compiler quiet */
1430  break;
1431  }
1432  }
1433  PG_CATCH();
1434  {
1435  /* Uncaught error while executing portal: mark it dead */
1436  MarkPortalFailed(portal);
1437 
1438  /* Restore global vars and propagate error */
1439  ActivePortal = saveActivePortal;
1440  CurrentResourceOwner = saveResourceOwner;
1441  PortalContext = savePortalContext;
1442 
1443  PG_RE_THROW();
1444  }
1445  PG_END_TRY();
1446 
1447  MemoryContextSwitchTo(oldContext);
1448 
1449  /* Mark portal not active */
1450  portal->status = PORTAL_READY;
1451 
1452  ActivePortal = saveActivePortal;
1453  CurrentResourceOwner = saveResourceOwner;
1454  PortalContext = savePortalContext;
1455 
1456  return result;
1457 }
Portal ActivePortal
Definition: pquery.c:35
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
void MarkPortalActive(Portal portal)
Definition: portalmem.c:394
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext portalContext
Definition: portal.h:120
static uint64 DoPortalRunFetch(Portal portal, FetchDirection fdirection, long count, DestReceiver *dest)
Definition: pquery.c:1470
bool run_once
Definition: portal.h:147
MemoryContext PortalContext
Definition: mcxt.c:53
#define ERROR
Definition: elog.h:43
static void FillPortalStore(Portal portal, bool isTopLevel)
Definition: pquery.c:988
PortalStrategy strategy
Definition: portal.h:145
#define AssertArg(condition)
Definition: c.h:740
#define PortalIsValid(p)
Definition: portal.h:203
#define PG_CATCH()
Definition: elog.h:305
#define Assert(condition)
Definition: c.h:738
void MarkPortalFailed(Portal portal)
Definition: portalmem.c:441
PortalStatus status
Definition: portal.h:150
#define PG_RE_THROW()
Definition: elog.h:336
ResourceOwner resowner
Definition: portal.h:121
Tuplestorestate * holdStore
Definition: portal.h:168
#define elog(elevel,...)
Definition: elog.h:214
#define PG_TRY()
Definition: elog.h:295
#define PG_END_TRY()
Definition: elog.h:320

◆ PortalSetResultFormat()

void PortalSetResultFormat ( Portal  portal,
int  nFormats,
int16 formats 
)

Definition at line 611 of file pquery.c.

References ereport, errcode(), errmsg(), ERROR, PortalData::formats, i, MemoryContextAlloc(), TupleDescData::natts, PortalData::portalContext, and PortalData::tupDesc.

Referenced by exec_bind_message(), and exec_simple_query().

612 {
613  int natts;
614  int i;
615 
616  /* Do nothing if portal won't return tuples */
617  if (portal->tupDesc == NULL)
618  return;
619  natts = portal->tupDesc->natts;
620  portal->formats = (int16 *)
622  natts * sizeof(int16));
623  if (nFormats > 1)
624  {
625  /* format specified for each column */
626  if (nFormats != natts)
627  ereport(ERROR,
628  (errcode(ERRCODE_PROTOCOL_VIOLATION),
629  errmsg("bind message has %d result formats but query has %d columns",
630  nFormats, natts)));
631  memcpy(portal->formats, formats, natts * sizeof(int16));
632  }
633  else if (nFormats > 0)
634  {
635  /* single format specified, use for all columns */
636  int16 format1 = formats[0];
637 
638  for (i = 0; i < natts; i++)
639  portal->formats[i] = format1;
640  }
641  else
642  {
643  /* use default format for all columns */
644  for (i = 0; i < natts; i++)
645  portal->formats[i] = 0;
646  }
647 }
signed short int16
Definition: c.h:354
int errcode(int sqlerrcode)
Definition: elog.c:610
MemoryContext portalContext
Definition: portal.h:120
#define ERROR
Definition: elog.h:43
int16 * formats
Definition: portal.h:161
TupleDesc tupDesc
Definition: portal.h:159
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:796
int i

◆ PortalStart()

void PortalStart ( Portal  portal,
ParamListInfo  params,
int  eflags,
Snapshot  snapshot 
)

Definition at line 430 of file pquery.c.

References ActivePortal, Assert, AssertArg, AssertState, PortalData::atEnd, PortalData::atStart, ChoosePortalStrategy(), CMD_UTILITY, PlannedStmt::commandType, CreateQueryDesc(), CurrentResourceOwner, CURSOR_OPT_SCROLL, PortalData::cursorOptions, EXEC_FLAG_BACKWARD, EXEC_FLAG_REWIND, ExecCleanTypeFromTL(), ExecutorStart(), GetActiveSnapshot(), GetTransactionSnapshot(), InvalidSnapshot, linitial_node, MarkPortalFailed(), MemoryContextSwitchTo(), None_Receiver, 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, PortalData::portalContext, PortalGetPrimaryStmt(), PortalIsValid, PortalData::portalParams, PortalData::portalPos, PushActiveSnapshot(), PortalData::queryDesc, PortalData::queryEnv, 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().

432 {
433  Portal saveActivePortal;
434  ResourceOwner saveResourceOwner;
435  MemoryContext savePortalContext;
436  MemoryContext oldContext;
437  QueryDesc *queryDesc;
438  int myeflags;
439 
440  AssertArg(PortalIsValid(portal));
441  AssertState(portal->status == PORTAL_DEFINED);
442 
443  /*
444  * Set up global portal context pointers.
445  */
446  saveActivePortal = ActivePortal;
447  saveResourceOwner = CurrentResourceOwner;
448  savePortalContext = PortalContext;
449  PG_TRY();
450  {
451  ActivePortal = portal;
452  if (portal->resowner)
453  CurrentResourceOwner = portal->resowner;
454  PortalContext = portal->portalContext;
455 
456  oldContext = MemoryContextSwitchTo(PortalContext);
457 
458  /* Must remember portal param list, if any */
459  portal->portalParams = params;
460 
461  /*
462  * Determine the portal execution strategy
463  */
464  portal->strategy = ChoosePortalStrategy(portal->stmts);
465 
466  /*
467  * Fire her up according to the strategy
468  */
469  switch (portal->strategy)
470  {
471  case PORTAL_ONE_SELECT:
472 
473  /* Must set snapshot before starting executor. */
474  if (snapshot)
475  PushActiveSnapshot(snapshot);
476  else
478 
479  /*
480  * Create QueryDesc in portal's context; for the moment, set
481  * the destination to DestNone.
482  */
483  queryDesc = CreateQueryDesc(linitial_node(PlannedStmt, portal->stmts),
484  portal->sourceText,
488  params,
489  portal->queryEnv,
490  0);
491 
492  /*
493  * If it's a scrollable cursor, executor needs to support
494  * REWIND and backwards scan, as well as whatever the caller
495  * might've asked for.
496  */
497  if (portal->cursorOptions & CURSOR_OPT_SCROLL)
498  myeflags = eflags | EXEC_FLAG_REWIND | EXEC_FLAG_BACKWARD;
499  else
500  myeflags = eflags;
501 
502  /*
503  * Call ExecutorStart to prepare the plan for execution
504  */
505  ExecutorStart(queryDesc, myeflags);
506 
507  /*
508  * This tells PortalCleanup to shut down the executor
509  */
510  portal->queryDesc = queryDesc;
511 
512  /*
513  * Remember tuple descriptor (computed by ExecutorStart)
514  */
515  portal->tupDesc = queryDesc->tupDesc;
516 
517  /*
518  * Reset cursor position data to "start of query"
519  */
520  portal->atStart = true;
521  portal->atEnd = false; /* allow fetches */
522  portal->portalPos = 0;
523 
525  break;
526 
528  case PORTAL_ONE_MOD_WITH:
529 
530  /*
531  * We don't start the executor until we are told to run the
532  * portal. We do need to set up the result tupdesc.
533  */
534  {
535  PlannedStmt *pstmt;
536 
537  pstmt = PortalGetPrimaryStmt(portal);
538  portal->tupDesc =
540  }
541 
542  /*
543  * Reset cursor position data to "start of query"
544  */
545  portal->atStart = true;
546  portal->atEnd = false; /* allow fetches */
547  portal->portalPos = 0;
548  break;
549 
550  case PORTAL_UTIL_SELECT:
551 
552  /*
553  * We don't set snapshot here, because PortalRunUtility will
554  * take care of it if needed.
555  */
556  {
557  PlannedStmt *pstmt = PortalGetPrimaryStmt(portal);
558 
559  Assert(pstmt->commandType == CMD_UTILITY);
560  portal->tupDesc = UtilityTupleDescriptor(pstmt->utilityStmt);
561  }
562 
563  /*
564  * Reset cursor position data to "start of query"
565  */
566  portal->atStart = true;
567  portal->atEnd = false; /* allow fetches */
568  portal->portalPos = 0;
569  break;
570 
571  case PORTAL_MULTI_QUERY:
572  /* Need do nothing now */
573  portal->tupDesc = NULL;
574  break;
575  }
576  }
577  PG_CATCH();
578  {
579  /* Uncaught error while executing portal: mark it dead */
580  MarkPortalFailed(portal);
581 
582  /* Restore global vars and propagate error */
583  ActivePortal = saveActivePortal;
584  CurrentResourceOwner = saveResourceOwner;
585  PortalContext = savePortalContext;
586 
587  PG_RE_THROW();
588  }
589  PG_END_TRY();
590 
591  MemoryContextSwitchTo(oldContext);
592 
593  ActivePortal = saveActivePortal;
594  CurrentResourceOwner = saveResourceOwner;
595  PortalContext = savePortalContext;
596 
597  portal->status = PORTAL_READY;
598 }
#define AssertState(condition)
Definition: c.h:741
bool atEnd
Definition: portal.h:191
TupleDesc ExecCleanTypeFromTL(List *targetList)
Definition: execTuples.c:1920
Portal ActivePortal
Definition: pquery.c:35
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
void ExecutorStart(QueryDesc *queryDesc, int eflags)
Definition: execMain.c:143
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Snapshot GetActiveSnapshot(void)
Definition: snapmgr.c:841
void PopActiveSnapshot(void)
Definition: snapmgr.c:814
List * stmts
Definition: portal.h:138
#define linitial_node(type, l)
Definition: pg_list.h:198
DestReceiver * None_Receiver
Definition: dest.c:96
Snapshot GetTransactionSnapshot(void)
Definition: snapmgr.c:306
MemoryContext portalContext
Definition: portal.h:120
struct Plan * planTree
Definition: plannodes.h:64
MemoryContext PortalContext
Definition: mcxt.c:53
ParamListInfo portalParams
Definition: portal.h:141
PlannedStmt * PortalGetPrimaryStmt(Portal portal)
Definition: portalmem.c:151
QueryDesc * CreateQueryDesc(PlannedStmt *plannedstmt, const char *sourceText, Snapshot snapshot, Snapshot crosscheck_snapshot, DestReceiver *dest, ParamListInfo params, QueryEnvironment *queryEnv, int instrument_options)
Definition: pquery.c:67
#define EXEC_FLAG_BACKWARD
Definition: executor.h:58
void PushActiveSnapshot(Snapshot snap)
Definition: snapmgr.c:735
Node * utilityStmt
Definition: plannodes.h:92
PortalStrategy strategy
Definition: portal.h:145
#define EXEC_FLAG_REWIND
Definition: executor.h:57
#define AssertArg(condition)
Definition: c.h:740
QueryDesc * queryDesc
Definition: portal.h:156
TupleDesc tupDesc
Definition: execdesc.h:47
#define InvalidSnapshot
Definition: snapshot.h:123
#define PortalIsValid(p)
Definition: portal.h:203
CmdType commandType
Definition: plannodes.h:46
const char * sourceText
Definition: portal.h:135
TupleDesc tupDesc
Definition: portal.h:159
#define PG_CATCH()
Definition: elog.h:305
#define Assert(condition)
Definition: c.h:738
void MarkPortalFailed(Portal portal)
Definition: portalmem.c:441
PortalStatus status
Definition: portal.h:150
#define PG_RE_THROW()
Definition: elog.h:336
QueryEnvironment * queryEnv
Definition: portal.h:142
PortalStrategy ChoosePortalStrategy(List *stmts)
Definition: pquery.c:206
List * targetlist
Definition: plannodes.h:142
ResourceOwner resowner
Definition: portal.h:121
bool atStart
Definition: portal.h:190
#define CURSOR_OPT_SCROLL
Definition: parsenodes.h:2707
int cursorOptions
Definition: portal.h:146
#define PG_TRY()
Definition: elog.h:295
TupleDesc UtilityTupleDescriptor(Node *parsetree)
Definition: utility.c:1969
#define PG_END_TRY()
Definition: elog.h:320
uint64 portalPos
Definition: portal.h:192

Variable Documentation

◆ ActivePortal