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

Go to the source code of this file.

Functions

NestLoopStateExecInitNestLoop (NestLoop *node, EState *estate, int eflags)
 
void ExecEndNestLoop (NestLoopState *node)
 
void ExecReScanNestLoop (NestLoopState *node)
 

Function Documentation

void ExecEndNestLoop ( NestLoopState node)

Definition at line 366 of file nodeNestloop.c.

References ExecClearTuple(), ExecEndNode(), ExecFreeExprContext(), innerPlanState, NestLoopState::js, NL1_printf, outerPlanState, JoinState::ps, and PlanState::ps_ResultTupleSlot.

Referenced by ExecEndNode().

367 {
368  NL1_printf("ExecEndNestLoop: %s\n",
369  "ending node processing");
370 
371  /*
372  * Free the exprcontext
373  */
374  ExecFreeExprContext(&node->js.ps);
375 
376  /*
377  * clean out the tuple table
378  */
380 
381  /*
382  * close down subplans
383  */
386 
387  NL1_printf("ExecEndNestLoop: %s\n",
388  "node processing ended");
389 }
PlanState ps
Definition: execnodes.h:1587
void ExecEndNode(PlanState *node)
Definition: execProcnode.c:523
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
void ExecFreeExprContext(PlanState *planstate)
Definition: execUtils.c:521
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:880
#define outerPlanState(node)
Definition: execnodes.h:893
#define NL1_printf(s, a)
Definition: execdebug.h:77
JoinState js
Definition: execnodes.h:1604
#define innerPlanState(node)
Definition: execnodes.h:892
NestLoopState* ExecInitNestLoop ( NestLoop node,
EState estate,
int  eflags 
)

Definition at line 263 of file nodeNestloop.c.

References Assert, elog, ERROR, EXEC_FLAG_BACKWARD, EXEC_FLAG_MARK, EXEC_FLAG_REWIND, ExecAssignExprContext(), ExecAssignProjectionInfo(), ExecAssignResultTypeFromTL(), ExecGetResultType(), ExecInitNode(), ExecInitNullTupleSlot(), ExecInitQual(), ExecInitResultTupleSlot(), ExecNestLoop(), PlanState::ExecProcNode, Join::inner_unique, innerPlan, innerPlanState, NestLoop::join, JOIN_ANTI, JOIN_INNER, JOIN_LEFT, JOIN_SEMI, Join::joinqual, JoinState::joinqual, Join::jointype, JoinState::jointype, NestLoopState::js, makeNode, NestLoop::nestParams, NIL, NL1_printf, NestLoopState::nl_MatchedOuter, NestLoopState::nl_NeedNewOuter, NestLoopState::nl_NullInnerTupleSlot, NULL, outerPlan, outerPlanState, Join::plan, PlanState::plan, JoinState::ps, Plan::qual, PlanState::qual, JoinState::single_match, and PlanState::state.

Referenced by ExecInitNode().

264 {
265  NestLoopState *nlstate;
266 
267  /* check for unsupported flags */
268  Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
269 
270  NL1_printf("ExecInitNestLoop: %s\n",
271  "initializing node");
272 
273  /*
274  * create state structure
275  */
276  nlstate = makeNode(NestLoopState);
277  nlstate->js.ps.plan = (Plan *) node;
278  nlstate->js.ps.state = estate;
279  nlstate->js.ps.ExecProcNode = ExecNestLoop;
280 
281  /*
282  * Miscellaneous initialization
283  *
284  * create expression context for node
285  */
286  ExecAssignExprContext(estate, &nlstate->js.ps);
287 
288  /*
289  * initialize child expressions
290  */
291  nlstate->js.ps.qual =
292  ExecInitQual(node->join.plan.qual, (PlanState *) nlstate);
293  nlstate->js.jointype = node->join.jointype;
294  nlstate->js.joinqual =
295  ExecInitQual(node->join.joinqual, (PlanState *) nlstate);
296 
297  /*
298  * initialize child nodes
299  *
300  * If we have no parameters to pass into the inner rel from the outer,
301  * tell the inner child that cheap rescans would be good. If we do have
302  * such parameters, then there is no point in REWIND support at all in the
303  * inner child, because it will always be rescanned with fresh parameter
304  * values.
305  */
306  outerPlanState(nlstate) = ExecInitNode(outerPlan(node), estate, eflags);
307  if (node->nestParams == NIL)
308  eflags |= EXEC_FLAG_REWIND;
309  else
310  eflags &= ~EXEC_FLAG_REWIND;
311  innerPlanState(nlstate) = ExecInitNode(innerPlan(node), estate, eflags);
312 
313  /*
314  * tuple table initialization
315  */
316  ExecInitResultTupleSlot(estate, &nlstate->js.ps);
317 
318  /*
319  * detect whether we need only consider the first matching inner tuple
320  */
321  nlstate->js.single_match = (node->join.inner_unique ||
322  node->join.jointype == JOIN_SEMI);
323 
324  /* set up null tuples for outer joins, if needed */
325  switch (node->join.jointype)
326  {
327  case JOIN_INNER:
328  case JOIN_SEMI:
329  break;
330  case JOIN_LEFT:
331  case JOIN_ANTI:
332  nlstate->nl_NullInnerTupleSlot =
333  ExecInitNullTupleSlot(estate,
335  break;
336  default:
337  elog(ERROR, "unrecognized join type: %d",
338  (int) node->join.jointype);
339  }
340 
341  /*
342  * initialize tuple type and projection info
343  */
344  ExecAssignResultTypeFromTL(&nlstate->js.ps);
345  ExecAssignProjectionInfo(&nlstate->js.ps, NULL);
346 
347  /*
348  * finally, wipe the current outer tuple clean.
349  */
350  nlstate->nl_NeedNewOuter = true;
351  nlstate->nl_MatchedOuter = false;
352 
353  NL1_printf("ExecInitNestLoop: %s\n",
354  "node initialized");
355 
356  return nlstate;
357 }
JoinType jointype
Definition: execnodes.h:1588
#define NIL
Definition: pg_list.h:69
List * qual
Definition: plannodes.h:145
bool nl_MatchedOuter
Definition: execnodes.h:1606
ExprState * joinqual
Definition: execnodes.h:1591
List * nestParams
Definition: plannodes.h:686
PlanState ps
Definition: execnodes.h:1587
bool nl_NeedNewOuter
Definition: execnodes.h:1605
bool single_match
Definition: execnodes.h:1589
EState * state
Definition: execnodes.h:849
ExprState * ExecInitQual(List *qual, PlanState *parent)
Definition: execExpr.c:160
void ExecAssignResultTypeFromTL(PlanState *planstate)
Definition: execUtils.c:445
JoinType jointype
Definition: plannodes.h:667
TupleTableSlot * ExecInitNullTupleSlot(EState *estate, TupleDesc tupType)
Definition: execTuples.c:866
Join join
Definition: plannodes.h:685
#define ERROR
Definition: elog.h:43
void ExecInitResultTupleSlot(EState *estate, PlanState *planstate)
Definition: execTuples.c:832
#define EXEC_FLAG_BACKWARD
Definition: executor.h:60
#define outerPlanState(node)
Definition: execnodes.h:893
#define innerPlan(node)
Definition: plannodes.h:173
void ExecAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc)
Definition: execUtils.c:492
#define EXEC_FLAG_REWIND
Definition: executor.h:59
#define outerPlan(node)
Definition: plannodes.h:174
static TupleTableSlot * ExecNestLoop(PlanState *pstate)
Definition: nodeNestloop.c:61
ExecProcNodeMtd ExecProcNode
Definition: execnodes.h:853
TupleTableSlot * nl_NullInnerTupleSlot
Definition: execnodes.h:1607
Plan * plan
Definition: execnodes.h:847
#define makeNode(_type_)
Definition: nodes.h:557
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:676
#define EXEC_FLAG_MARK
Definition: executor.h:61
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:423
#define NL1_printf(s, a)
Definition: execdebug.h:77
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:474
ExprState * qual
Definition: execnodes.h:865
JoinState js
Definition: execnodes.h:1604
#define elog
Definition: elog.h:219
bool inner_unique
Definition: plannodes.h:668
#define innerPlanState(node)
Definition: execnodes.h:892
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
Definition: execProcnode.c:139
List * joinqual
Definition: plannodes.h:669
Plan plan
Definition: plannodes.h:666
void ExecReScanNestLoop ( NestLoopState node)

Definition at line 396 of file nodeNestloop.c.

References PlanState::chgParam, ExecReScan(), NestLoopState::nl_MatchedOuter, NestLoopState::nl_NeedNewOuter, NULL, outerPlan, and outerPlanState.

Referenced by ExecReScan().

397 {
399 
400  /*
401  * If outerPlan->chgParam is not null then plan will be automatically
402  * re-scanned by first ExecProcNode.
403  */
404  if (outerPlan->chgParam == NULL)
405  ExecReScan(outerPlan);
406 
407  /*
408  * innerPlan is re-scanned for each new outer tuple and MUST NOT be
409  * re-scanned from here or you'll get troubles from inner index scans when
410  * outer Vars are used as run-time keys...
411  */
412 
413  node->nl_NeedNewOuter = true;
414  node->nl_MatchedOuter = false;
415 }
bool nl_MatchedOuter
Definition: execnodes.h:1606
bool nl_NeedNewOuter
Definition: execnodes.h:1605
void ExecReScan(PlanState *node)
Definition: execAmi.c:76
#define outerPlanState(node)
Definition: execnodes.h:893
Bitmapset * chgParam
Definition: execnodes.h:875
#define outerPlan(node)
Definition: plannodes.h:174
#define NULL
Definition: c.h:229