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

Go to the source code of this file.

Functions

SetOpStateExecInitSetOp (SetOp *node, EState *estate, int eflags)
 
TupleTableSlotExecSetOp (SetOpState *node)
 
void ExecEndSetOp (SetOpState *node)
 
void ExecReScanSetOp (SetOpState *node)
 

Function Documentation

void ExecEndSetOp ( SetOpState node)

Definition at line 575 of file nodeSetOp.c.

References ExecClearTuple(), ExecEndNode(), MemoryContextDelete(), outerPlanState, SetOpState::ps, PlanState::ps_ResultTupleSlot, SetOpState::tableContext, and SetOpState::tempContext.

Referenced by ExecEndNode().

576 {
577  /* clean up tuple table */
579 
580  /* free subsidiary stuff including hashtable */
582  if (node->tableContext)
584 
586 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:200
MemoryContext tableContext
Definition: execnodes.h:1970
MemoryContext tempContext
Definition: execnodes.h:1964
void ExecEndNode(PlanState *node)
Definition: execProcnode.c:654
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
PlanState ps
Definition: execnodes.h:1959
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:861
#define outerPlanState(node)
Definition: execnodes.h:874
SetOpState* ExecInitSetOp ( SetOp node,
EState estate,
int  eflags 
)

Definition at line 470 of file nodeSetOp.c.

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate(), Assert, build_hash_table(), CurrentMemoryContext, SetOp::dupOperators, SetOpState::eqfunctions, EXEC_FLAG_BACKWARD, EXEC_FLAG_MARK, EXEC_FLAG_REWIND, ExecAssignResultTypeFromTL(), ExecInitNode(), ExecInitResultTupleSlot(), execTuplesHashPrepare(), execTuplesMatchPrepare(), SetOpState::grp_firstTuple, SetOpState::hashfunctions, SetOpState::hashtable, makeNode, NULL, SetOp::numCols, SetOpState::numOutput, outerPlan, outerPlanState, palloc0(), SetOpState::pergroup, PlanState::plan, SetOpState::ps, PlanState::ps_ProjInfo, SetOpState::setop_done, SETOP_HASHED, PlanState::state, SetOp::strategy, SetOpState::table_filled, SetOpState::tableContext, and SetOpState::tempContext.

Referenced by ExecInitNode().

471 {
472  SetOpState *setopstate;
473 
474  /* check for unsupported flags */
475  Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
476 
477  /*
478  * create state structure
479  */
480  setopstate = makeNode(SetOpState);
481  setopstate->ps.plan = (Plan *) node;
482  setopstate->ps.state = estate;
483 
484  setopstate->eqfunctions = NULL;
485  setopstate->hashfunctions = NULL;
486  setopstate->setop_done = false;
487  setopstate->numOutput = 0;
488  setopstate->pergroup = NULL;
489  setopstate->grp_firstTuple = NULL;
490  setopstate->hashtable = NULL;
491  setopstate->tableContext = NULL;
492 
493  /*
494  * Miscellaneous initialization
495  *
496  * SetOp nodes have no ExprContext initialization because they never call
497  * ExecQual or ExecProject. But they do need a per-tuple memory context
498  * anyway for calling execTuplesMatch.
499  */
500  setopstate->tempContext =
502  "SetOp",
504 
505  /*
506  * If hashing, we also need a longer-lived context to store the hash
507  * table. The table can't just be kept in the per-query context because
508  * we want to be able to throw it away in ExecReScanSetOp.
509  */
510  if (node->strategy == SETOP_HASHED)
511  setopstate->tableContext =
513  "SetOp hash table",
515 
516  /*
517  * Tuple table initialization
518  */
519  ExecInitResultTupleSlot(estate, &setopstate->ps);
520 
521  /*
522  * initialize child nodes
523  *
524  * If we are hashing then the child plan does not need to handle REWIND
525  * efficiently; see ExecReScanSetOp.
526  */
527  if (node->strategy == SETOP_HASHED)
528  eflags &= ~EXEC_FLAG_REWIND;
529  outerPlanState(setopstate) = ExecInitNode(outerPlan(node), estate, eflags);
530 
531  /*
532  * setop nodes do no projections, so initialize projection info for this
533  * node appropriately
534  */
535  ExecAssignResultTypeFromTL(&setopstate->ps);
536  setopstate->ps.ps_ProjInfo = NULL;
537 
538  /*
539  * Precompute fmgr lookup data for inner loop. We need both equality and
540  * hashing functions to do it by hashing, but only equality if not
541  * hashing.
542  */
543  if (node->strategy == SETOP_HASHED)
545  node->dupOperators,
546  &setopstate->eqfunctions,
547  &setopstate->hashfunctions);
548  else
549  setopstate->eqfunctions =
551  node->dupOperators);
552 
553  if (node->strategy == SETOP_HASHED)
554  {
555  build_hash_table(setopstate);
556  setopstate->table_filled = false;
557  }
558  else
559  {
560  setopstate->pergroup =
562  }
563 
564  return setopstate;
565 }
SetOpStrategy strategy
Definition: plannodes.h:879
MemoryContext tableContext
Definition: execnodes.h:1970
MemoryContext tempContext
Definition: execnodes.h:1964
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:863
struct SetOpStatePerGroupData * SetOpStatePerGroup
Definition: execnodes.h:1955
PlanState ps
Definition: execnodes.h:1959
HeapTuple grp_firstTuple
Definition: execnodes.h:1967
EState * state
Definition: execnodes.h:834
int numCols
Definition: plannodes.h:880
void execTuplesHashPrepare(int numCols, Oid *eqOperators, FmgrInfo **eqFunctions, FmgrInfo **hashFunctions)
Definition: execGrouping.c:233
void ExecAssignResultTypeFromTL(PlanState *planstate)
Definition: execUtils.c:440
void ExecInitResultTupleSlot(EState *estate, PlanState *planstate)
Definition: execTuples.c:832
static void build_hash_table(SetOpState *setopstate)
Definition: nodeSetOp.c:119
Oid * dupOperators
Definition: plannodes.h:883
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:165
#define EXEC_FLAG_BACKWARD
Definition: executor.h:60
#define outerPlanState(node)
Definition: execnodes.h:874
bool table_filled
Definition: execnodes.h:1971
long numOutput
Definition: execnodes.h:1963
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
#define EXEC_FLAG_REWIND
Definition: executor.h:59
#define outerPlan(node)
Definition: plannodes.h:174
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:322
void * palloc0(Size size)
Definition: mcxt.c:878
FmgrInfo * hashfunctions
Definition: execnodes.h:1961
Plan * plan
Definition: execnodes.h:832
#define makeNode(_type_)
Definition: nodes.h:557
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
#define EXEC_FLAG_MARK
Definition: executor.h:61
bool setop_done
Definition: execnodes.h:1962
FmgrInfo * eqfunctions
Definition: execnodes.h:1960
SetOpStatePerGroup pergroup
Definition: execnodes.h:1966
FmgrInfo * execTuplesMatchPrepare(int numCols, Oid *eqOperators)
Definition: execGrouping.c:204
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
Definition: execProcnode.c:140
TupleHashTable hashtable
Definition: execnodes.h:1969
void ExecReScanSetOp ( SetOpState node)

Definition at line 590 of file nodeSetOp.c.

References build_hash_table(), PlanState::chgParam, ExecClearTuple(), ExecReScan(), SetOpState::grp_firstTuple, SetOpState::hashiter, SetOpState::hashtable, heap_freetuple(), PlanState::lefttree, MemoryContextResetAndDeleteChildren, NULL, SetOpState::numOutput, PlanState::plan, SetOpState::ps, PlanState::ps_ResultTupleSlot, ResetTupleHashIterator, SetOpState::setop_done, SETOP_HASHED, SetOpState::table_filled, and SetOpState::tableContext.

Referenced by ExecReScan().

591 {
593  node->setop_done = false;
594  node->numOutput = 0;
595 
596  if (((SetOp *) node->ps.plan)->strategy == SETOP_HASHED)
597  {
598  /*
599  * In the hashed case, if we haven't yet built the hash table then we
600  * can just return; nothing done yet, so nothing to undo. If subnode's
601  * chgParam is not NULL then it will be re-scanned by ExecProcNode,
602  * else no reason to re-scan it at all.
603  */
604  if (!node->table_filled)
605  return;
606 
607  /*
608  * If we do have the hash table and the subplan does not have any
609  * parameter changes, then we can just rescan the existing hash table;
610  * no need to build it again.
611  */
612  if (node->ps.lefttree->chgParam == NULL)
613  {
615  return;
616  }
617  }
618 
619  /* Release first tuple of group, if we have made a copy */
620  if (node->grp_firstTuple != NULL)
621  {
623  node->grp_firstTuple = NULL;
624  }
625 
626  /* Release any hashtable storage */
627  if (node->tableContext)
629 
630  /* And rebuild empty hashtable if needed */
631  if (((SetOp *) node->ps.plan)->strategy == SETOP_HASHED)
632  {
633  build_hash_table(node);
634  node->table_filled = false;
635  }
636 
637  /*
638  * if chgParam of subnode is not null then plan will be re-scanned by
639  * first ExecProcNode.
640  */
641  if (node->ps.lefttree->chgParam == NULL)
642  ExecReScan(node->ps.lefttree);
643 }
MemoryContext tableContext
Definition: execnodes.h:1970
void ExecReScan(PlanState *node)
Definition: execAmi.c:75
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
PlanState ps
Definition: execnodes.h:1959
HeapTuple grp_firstTuple
Definition: execnodes.h:1967
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1372
struct PlanState * lefttree
Definition: execnodes.h:847
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:861
static void build_hash_table(SetOpState *setopstate)
Definition: nodeSetOp.c:119
bool table_filled
Definition: execnodes.h:1971
long numOutput
Definition: execnodes.h:1963
TupleHashIterator hashiter
Definition: execnodes.h:1972
Bitmapset * chgParam
Definition: execnodes.h:856
#define MemoryContextResetAndDeleteChildren(ctx)
Definition: memutils.h:67
Plan * plan
Definition: execnodes.h:832
#define ResetTupleHashIterator(htable, iter)
Definition: execnodes.h:629
#define NULL
Definition: c.h:229
bool setop_done
Definition: execnodes.h:1962
TupleHashTable hashtable
Definition: execnodes.h:1969
TupleTableSlot* ExecSetOp ( SetOpState node)

Definition at line 183 of file nodeSetOp.c.

References NULL, SetOpState::numOutput, PlanState::plan, SetOpState::ps, PlanState::ps_ResultTupleSlot, SetOpState::setop_done, setop_fill_hash_table(), SETOP_HASHED, setop_retrieve_direct(), setop_retrieve_hash_table(), SetOp::strategy, and SetOpState::table_filled.

Referenced by ExecProcNode().

184 {
185  SetOp *plannode = (SetOp *) node->ps.plan;
186  TupleTableSlot *resultTupleSlot = node->ps.ps_ResultTupleSlot;
187 
188  /*
189  * If the previously-returned tuple needs to be returned more than once,
190  * keep returning it.
191  */
192  if (node->numOutput > 0)
193  {
194  node->numOutput--;
195  return resultTupleSlot;
196  }
197 
198  /* Otherwise, we're done if we are out of groups */
199  if (node->setop_done)
200  return NULL;
201 
202  /* Fetch the next tuple group according to the correct strategy */
203  if (plannode->strategy == SETOP_HASHED)
204  {
205  if (!node->table_filled)
206  setop_fill_hash_table(node);
207  return setop_retrieve_hash_table(node);
208  }
209  else
210  return setop_retrieve_direct(node);
211 }
SetOpStrategy strategy
Definition: plannodes.h:879
PlanState ps
Definition: execnodes.h:1959
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:861
static void setop_fill_hash_table(SetOpState *setopstate)
Definition: nodeSetOp.c:331
bool table_filled
Definition: execnodes.h:1971
static TupleTableSlot * setop_retrieve_direct(SetOpState *setopstate)
Definition: nodeSetOp.c:217
long numOutput
Definition: execnodes.h:1963
static TupleTableSlot * setop_retrieve_hash_table(SetOpState *setopstate)
Definition: nodeSetOp.c:416
Plan * plan
Definition: execnodes.h:832
#define NULL
Definition: c.h:229
bool setop_done
Definition: execnodes.h:1962