execProcnode.c 17.4 KB
Newer Older
1 2
/*-------------------------------------------------------------------------
 *
3
 * execProcnode.c
4 5 6
 *	 contains dispatch functions which call the appropriate "initialize",
 *	 "get a tuple", and "cleanup" routines for the given node type.
 *	 If the node has children, then it will presumably call ExecInitNode,
B
Bruce Momjian 已提交
7
 *	 ExecProcNode, or ExecEndNode on its subnodes and do the appropriate
8
 *	 processing.
9
 *
10
 * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
B
Add:  
Bruce Momjian 已提交
11
 * Portions Copyright (c) 1994, Regents of the University of California
12 13 14
 *
 *
 * IDENTIFICATION
15
 *	  $PostgreSQL: pgsql/src/backend/executor/execProcnode.c,v 1.57 2006/07/14 14:52:18 momjian Exp $
16 17 18 19
 *
 *-------------------------------------------------------------------------
 */
/*
20
 *	 INTERFACE ROUTINES
21
 *		ExecCountSlotsNode -	count tuple slots needed by plan tree
B
Bruce Momjian 已提交
22
 *		ExecInitNode	-		initialize a plan node and its subplans
23
 *		ExecProcNode	-		get a tuple by executing the plan node
B
Bruce Momjian 已提交
24
 *		ExecEndNode		-		shut down a plan node and its subplans
25
 *
26 27 28 29
 *	 NOTES
 *		This used to be three files.  It is now all combined into
 *		one file so that it is easier to keep ExecInitNode, ExecProcNode,
 *		and ExecEndNode in sync when new nodes are added.
30
 *
31
 *	 EXAMPLE
32 33
 *		Suppose we want the age of the manager of the shoe department and
 *		the number of employees in that department.  So we have the query:
34
 *
35
 *				select DEPT.no_emps, EMP.age
36 37
 *				where EMP.name = DEPT.mgr and
 *					  DEPT.name = "shoe"
38
 *
39
 *		Suppose the planner gives us the following plan:
40
 *
41 42 43 44 45 46 47
 *						Nest Loop (DEPT.mgr = EMP.name)
 *						/		\
 *					   /		 \
 *				   Seq Scan		Seq Scan
 *					DEPT		  EMP
 *				(name = "shoe")
 *
48
 *		ExecutorStart() is called first.
49 50 51 52 53 54
 *		It calls InitPlan() which calls ExecInitNode() on
 *		the root of the plan -- the nest loop node.
 *
 *	  * ExecInitNode() notices that it is looking at a nest loop and
 *		as the code below demonstrates, it calls ExecInitNestLoop().
 *		Eventually this calls ExecInitNode() on the right and left subplans
B
Bruce Momjian 已提交
55
 *		and so forth until the entire plan is initialized.	The result
56 57
 *		of ExecInitNode() is a plan state tree built with the same structure
 *		as the underlying plan tree.
58
 *
59 60
 *	  * Then when ExecRun() is called, it calls ExecutePlan() which calls
 *		ExecProcNode() repeatedly on the top node of the plan state tree.
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
 *		Each time this happens, ExecProcNode() will end up calling
 *		ExecNestLoop(), which calls ExecProcNode() on its subplans.
 *		Each of these subplans is a sequential scan so ExecSeqScan() is
 *		called.  The slots returned by ExecSeqScan() may contain
 *		tuples which contain the attributes ExecNestLoop() uses to
 *		form the tuples it returns.
 *
 *	  * Eventually ExecSeqScan() stops returning tuples and the nest
 *		loop join ends.  Lastly, ExecEnd() calls ExecEndNode() which
 *		calls ExecEndNestLoop() which in turn calls ExecEndNode() on
 *		its subplans which result in ExecEndSeqScan().
 *
 *		This should show how the executor works by having
 *		ExecInitNode(), ExecProcNode() and ExecEndNode() dispatch
 *		their work to the appopriate node support routines which may
 *		in turn call these routines themselves on their subplans.
77
 */
78 79
#include "postgres.h"

80
#include "executor/executor.h"
81
#include "executor/instrument.h"
B
Bruce Momjian 已提交
82
#include "executor/nodeAgg.h"
83
#include "executor/nodeAppend.h"
84 85 86 87
#include "executor/nodeBitmapAnd.h"
#include "executor/nodeBitmapHeapscan.h"
#include "executor/nodeBitmapIndexscan.h"
#include "executor/nodeBitmapOr.h"
88
#include "executor/nodeFunctionscan.h"
89 90 91
#include "executor/nodeGroup.h"
#include "executor/nodeHash.h"
#include "executor/nodeHashjoin.h"
B
Bruce Momjian 已提交
92
#include "executor/nodeIndexscan.h"
93
#include "executor/nodeLimit.h"
B
Bruce Momjian 已提交
94 95 96 97 98
#include "executor/nodeMaterial.h"
#include "executor/nodeMergejoin.h"
#include "executor/nodeNestloop.h"
#include "executor/nodeResult.h"
#include "executor/nodeSeqscan.h"
99
#include "executor/nodeSetOp.h"
B
Bruce Momjian 已提交
100
#include "executor/nodeSort.h"
V
Vadim B. Mikheev 已提交
101
#include "executor/nodeSubplan.h"
102
#include "executor/nodeSubqueryscan.h"
103
#include "executor/nodeTidscan.h"
B
Bruce Momjian 已提交
104 105
#include "executor/nodeUnique.h"
#include "miscadmin.h"
106 107

/* ------------------------------------------------------------------------
108 109
 *		ExecInitNode
 *
110
 *		Recursively initializes all the nodes in the plan tree rooted
111 112
 *		at 'node'.
 *
113 114 115 116
 *		Inputs:
 *		  'node' is the current node of the plan produced by the query planner
 *		  'estate' is the shared execution state for the plan tree
 *		  'eflags' is a bitwise OR of flag bits described in executor.h
117
 *
118
 *		Returns a PlanState node corresponding to the given Plan node.
119 120
 * ------------------------------------------------------------------------
 */
121
PlanState *
122
ExecInitNode(Plan *node, EState *estate, int eflags)
123
{
124 125
	PlanState  *result;
	List	   *subps;
126
	ListCell   *l;
127

128 129
	/*
	 * do nothing when we get to the end of a leaf on tree.
130
	 */
131
	if (node == NULL)
132
		return NULL;
133

134 135
	switch (nodeTag(node))
	{
136 137
			/*
			 * control nodes
138 139
			 */
		case T_Result:
140 141
			result = (PlanState *) ExecInitResult((Result *) node,
												  estate, eflags);
142 143 144
			break;

		case T_Append:
145 146
			result = (PlanState *) ExecInitAppend((Append *) node,
												  estate, eflags);
147 148
			break;

149
		case T_BitmapAnd:
150 151
			result = (PlanState *) ExecInitBitmapAnd((BitmapAnd *) node,
													 estate, eflags);
152 153 154
			break;

		case T_BitmapOr:
155 156
			result = (PlanState *) ExecInitBitmapOr((BitmapOr *) node,
													estate, eflags);
157 158
			break;

159 160
			/*
			 * scan nodes
161 162
			 */
		case T_SeqScan:
163 164
			result = (PlanState *) ExecInitSeqScan((SeqScan *) node,
												   estate, eflags);
165 166 167
			break;

		case T_IndexScan:
168 169
			result = (PlanState *) ExecInitIndexScan((IndexScan *) node,
													 estate, eflags);
170 171
			break;

172
		case T_BitmapIndexScan:
173 174
			result = (PlanState *) ExecInitBitmapIndexScan((BitmapIndexScan *) node,
														   estate, eflags);
175 176 177
			break;

		case T_BitmapHeapScan:
178 179
			result = (PlanState *) ExecInitBitmapHeapScan((BitmapHeapScan *) node,
														  estate, eflags);
180 181
			break;

182
		case T_TidScan:
183 184
			result = (PlanState *) ExecInitTidScan((TidScan *) node,
												   estate, eflags);
185 186 187
			break;

		case T_SubqueryScan:
188 189
			result = (PlanState *) ExecInitSubqueryScan((SubqueryScan *) node,
														estate, eflags);
190 191
			break;

192
		case T_FunctionScan:
193 194
			result = (PlanState *) ExecInitFunctionScan((FunctionScan *) node,
														estate, eflags);
195 196
			break;

197 198
			/*
			 * join nodes
199 200
			 */
		case T_NestLoop:
201 202
			result = (PlanState *) ExecInitNestLoop((NestLoop *) node,
													estate, eflags);
203 204 205
			break;

		case T_MergeJoin:
206 207
			result = (PlanState *) ExecInitMergeJoin((MergeJoin *) node,
													 estate, eflags);
208 209 210
			break;

		case T_HashJoin:
211 212
			result = (PlanState *) ExecInitHashJoin((HashJoin *) node,
													estate, eflags);
213 214
			break;

215 216
			/*
			 * materialization nodes
217 218
			 */
		case T_Material:
219 220
			result = (PlanState *) ExecInitMaterial((Material *) node,
													estate, eflags);
221 222 223
			break;

		case T_Sort:
224 225
			result = (PlanState *) ExecInitSort((Sort *) node,
												estate, eflags);
226 227
			break;

228
		case T_Group:
229 230
			result = (PlanState *) ExecInitGroup((Group *) node,
												 estate, eflags);
231 232
			break;

233
		case T_Agg:
234 235
			result = (PlanState *) ExecInitAgg((Agg *) node,
											   estate, eflags);
236 237
			break;

238
		case T_Unique:
239 240
			result = (PlanState *) ExecInitUnique((Unique *) node,
												  estate, eflags);
241 242
			break;

243
		case T_Hash:
244 245
			result = (PlanState *) ExecInitHash((Hash *) node,
												estate, eflags);
246 247
			break;

248
		case T_SetOp:
249 250
			result = (PlanState *) ExecInitSetOp((SetOp *) node,
												 estate, eflags);
251 252 253
			break;

		case T_Limit:
254 255
			result = (PlanState *) ExecInitLimit((Limit *) node,
												 estate, eflags);
256 257 258
			break;

		default:
259
			elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
260
			result = NULL;		/* keep compiler quiet */
261
			break;
262
	}
263

264
	/*
B
Bruce Momjian 已提交
265 266
	 * Initialize any initPlans present in this node.  The planner put them in
	 * a separate list for us.
267 268
	 */
	subps = NIL;
269
	foreach(l, node->initPlan)
V
Vadim B. Mikheev 已提交
270
	{
271
		SubPlan    *subplan = (SubPlan *) lfirst(l);
272
		SubPlanState *sstate;
273

274
		Assert(IsA(subplan, SubPlan));
275
		sstate = ExecInitExprInitPlan(subplan, result);
276
		ExecInitSubPlan(sstate, estate, eflags);
277
		subps = lappend(subps, sstate);
V
Vadim B. Mikheev 已提交
278
	}
279 280 281
	result->initPlan = subps;

	/*
B
Bruce Momjian 已提交
282
	 * Initialize any subPlans present in this node.  These were found by
B
Bruce Momjian 已提交
283 284 285
	 * ExecInitExpr during initialization of the PlanState.  Note we must do
	 * this after initializing initPlans, in case their arguments contain
	 * subPlans (is that actually possible? perhaps not).
286
	 */
287
	foreach(l, result->subPlan)
288
	{
289
		SubPlanState *sstate = (SubPlanState *) lfirst(l);
290

291
		Assert(IsA(sstate, SubPlanState));
292
		ExecInitSubPlan(sstate, estate, eflags);
293 294 295 296
	}

	/* Set up instrumentation for this node if requested */
	if (estate->es_instrument)
297
		result->instrument = InstrAlloc(1);
298 299

	return result;
300 301 302 303
}


/* ----------------------------------------------------------------
304 305
 *		ExecProcNode
 *
306
 *		Execute the given node to return a(nother) tuple.
307 308 309
 * ----------------------------------------------------------------
 */
TupleTableSlot *
310
ExecProcNode(PlanState *node)
311
{
312 313
	TupleTableSlot *result;

314 315
	CHECK_FOR_INTERRUPTS();

B
Bruce Momjian 已提交
316
	if (node->chgParam != NULL) /* something changed */
317
		ExecReScan(node, NULL); /* let ReScan handle this */
318

319 320 321
	if (node->instrument)
		InstrStartNode(node->instrument);

322 323
	switch (nodeTag(node))
	{
324 325 326
			/*
			 * control nodes
			 */
327 328
		case T_ResultState:
			result = ExecResult((ResultState *) node);
329 330
			break;

331
		case T_AppendState:
332
			result = ExecAppend((AppendState *) node);
333 334
			break;

335 336 337 338
			/* BitmapAndState does not yield tuples */

			/* BitmapOrState does not yield tuples */

339 340
			/*
			 * scan nodes
341
			 */
342 343
		case T_SeqScanState:
			result = ExecSeqScan((SeqScanState *) node);
344 345
			break;

346 347
		case T_IndexScanState:
			result = ExecIndexScan((IndexScanState *) node);
348 349
			break;

350 351 352 353 354 355
			/* BitmapIndexScanState does not yield tuples */

		case T_BitmapHeapScanState:
			result = ExecBitmapHeapScan((BitmapHeapScanState *) node);
			break;

356 357
		case T_TidScanState:
			result = ExecTidScan((TidScanState *) node);
358 359
			break;

360 361
		case T_SubqueryScanState:
			result = ExecSubqueryScan((SubqueryScanState *) node);
362 363
			break;

364 365
		case T_FunctionScanState:
			result = ExecFunctionScan((FunctionScanState *) node);
366 367
			break;

368 369
			/*
			 * join nodes
370
			 */
371 372
		case T_NestLoopState:
			result = ExecNestLoop((NestLoopState *) node);
373 374
			break;

375 376
		case T_MergeJoinState:
			result = ExecMergeJoin((MergeJoinState *) node);
377 378
			break;

379 380
		case T_HashJoinState:
			result = ExecHashJoin((HashJoinState *) node);
381 382
			break;

383 384
			/*
			 * materialization nodes
385
			 */
386 387
		case T_MaterialState:
			result = ExecMaterial((MaterialState *) node);
388 389
			break;

390 391
		case T_SortState:
			result = ExecSort((SortState *) node);
392 393
			break;

394 395
		case T_GroupState:
			result = ExecGroup((GroupState *) node);
396 397
			break;

398 399
		case T_AggState:
			result = ExecAgg((AggState *) node);
400 401
			break;

402 403
		case T_UniqueState:
			result = ExecUnique((UniqueState *) node);
404 405
			break;

406 407
		case T_HashState:
			result = ExecHash((HashState *) node);
408 409
			break;

410 411 412 413 414 415
		case T_SetOpState:
			result = ExecSetOp((SetOpState *) node);
			break;

		case T_LimitState:
			result = ExecLimit((LimitState *) node);
416 417 418
			break;

		default:
419
			elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
V
Vadim B. Mikheev 已提交
420
			result = NULL;
421
			break;
422 423
	}

424
	if (node->instrument)
425
		InstrStopNode(node->instrument, TupIsNull(result) ? 0.0 : 1.0);
426

427
	return result;
428 429
}

430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446

/* ----------------------------------------------------------------
 *		MultiExecProcNode
 *
 *		Execute a node that doesn't return individual tuples
 *		(it might return a hashtable, bitmap, etc).  Caller should
 *		check it got back the expected kind of Node.
 *
 * This has essentially the same responsibilities as ExecProcNode,
 * but it does not do InstrStartNode/InstrStopNode (mainly because
 * it can't tell how many returned tuples to count).  Each per-node
 * function must provide its own instrumentation support.
 * ----------------------------------------------------------------
 */
Node *
MultiExecProcNode(PlanState *node)
{
B
Bruce Momjian 已提交
447
	Node	   *result;
448 449 450 451 452 453 454 455

	CHECK_FOR_INTERRUPTS();

	if (node->chgParam != NULL) /* something changed */
		ExecReScan(node, NULL); /* let ReScan handle this */

	switch (nodeTag(node))
	{
B
Bruce Momjian 已提交
456 457 458
			/*
			 * Only node types that actually support multiexec will be listed
			 */
459 460 461 462 463

		case T_HashState:
			result = MultiExecHash((HashState *) node);
			break;

464 465 466 467 468 469 470 471 472 473 474 475
		case T_BitmapIndexScanState:
			result = MultiExecBitmapIndexScan((BitmapIndexScanState *) node);
			break;

		case T_BitmapAndState:
			result = MultiExecBitmapAnd((BitmapAndState *) node);
			break;

		case T_BitmapOrState:
			result = MultiExecBitmapOr((BitmapOrState *) node);
			break;

476 477 478 479 480 481 482 483 484 485
		default:
			elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
			result = NULL;
			break;
	}

	return result;
}


486 487 488 489 490 491
/*
 * ExecCountSlotsNode - count up the number of tuple table slots needed
 *
 * Note that this scans a Plan tree, not a PlanState tree, because we
 * haven't built the PlanState tree yet ...
 */
492
int
493
ExecCountSlotsNode(Plan *node)
494
{
495
	if (node == NULL)
496
		return 0;
497

498 499
	switch (nodeTag(node))
	{
500 501
			/*
			 * control nodes
502 503 504 505 506 507 508
			 */
		case T_Result:
			return ExecCountSlotsResult((Result *) node);

		case T_Append:
			return ExecCountSlotsAppend((Append *) node);

509 510 511 512 513 514
		case T_BitmapAnd:
			return ExecCountSlotsBitmapAnd((BitmapAnd *) node);

		case T_BitmapOr:
			return ExecCountSlotsBitmapOr((BitmapOr *) node);

515 516
			/*
			 * scan nodes
517 518 519 520 521 522 523
			 */
		case T_SeqScan:
			return ExecCountSlotsSeqScan((SeqScan *) node);

		case T_IndexScan:
			return ExecCountSlotsIndexScan((IndexScan *) node);

524 525 526 527 528 529
		case T_BitmapIndexScan:
			return ExecCountSlotsBitmapIndexScan((BitmapIndexScan *) node);

		case T_BitmapHeapScan:
			return ExecCountSlotsBitmapHeapScan((BitmapHeapScan *) node);

530 531 532 533 534 535
		case T_TidScan:
			return ExecCountSlotsTidScan((TidScan *) node);

		case T_SubqueryScan:
			return ExecCountSlotsSubqueryScan((SubqueryScan *) node);

536 537 538
		case T_FunctionScan:
			return ExecCountSlotsFunctionScan((FunctionScan *) node);

539 540
			/*
			 * join nodes
541 542 543 544 545 546 547
			 */
		case T_NestLoop:
			return ExecCountSlotsNestLoop((NestLoop *) node);

		case T_MergeJoin:
			return ExecCountSlotsMergeJoin((MergeJoin *) node);

548 549 550
		case T_HashJoin:
			return ExecCountSlotsHashJoin((HashJoin *) node);

551 552
			/*
			 * materialization nodes
553 554 555 556 557 558 559
			 */
		case T_Material:
			return ExecCountSlotsMaterial((Material *) node);

		case T_Sort:
			return ExecCountSlotsSort((Sort *) node);

560 561 562 563 564 565
		case T_Group:
			return ExecCountSlotsGroup((Group *) node);

		case T_Agg:
			return ExecCountSlotsAgg((Agg *) node);

566 567 568
		case T_Unique:
			return ExecCountSlotsUnique((Unique *) node);

569 570 571
		case T_Hash:
			return ExecCountSlotsHash((Hash *) node);

572 573 574
		case T_SetOp:
			return ExecCountSlotsSetOp((SetOp *) node);

575 576 577
		case T_Limit:
			return ExecCountSlotsLimit((Limit *) node);

578
		default:
579
			elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
580
			break;
581
	}
582

583
	return 0;
584 585
}

586 587
/* ----------------------------------------------------------------
 *		ExecEndNode
588
 *
589 590 591 592 593 594 595
 *		Recursively cleans up all the nodes in the plan rooted
 *		at 'node'.
 *
 *		After this operation, the query plan will not be able to
 *		processed any further.	This should be called only after
 *		the query plan has been fully executed.
 * ----------------------------------------------------------------
596 597
 */
void
598
ExecEndNode(PlanState *node)
599
{
600
	ListCell   *subp;
601

602 603
	/*
	 * do nothing when we get to the end of a leaf on tree.
604
	 */
605 606
	if (node == NULL)
		return;
607

608
	/* Clean up initPlans and subPlans */
609
	foreach(subp, node->initPlan)
610
		ExecEndSubPlan((SubPlanState *) lfirst(subp));
611
	foreach(subp, node->subPlan)
612
		ExecEndSubPlan((SubPlanState *) lfirst(subp));
613

614
	if (node->chgParam != NULL)
V
Vadim B. Mikheev 已提交
615
	{
616 617
		bms_free(node->chgParam);
		node->chgParam = NULL;
V
Vadim B. Mikheev 已提交
618
	}
619 620 621

	switch (nodeTag(node))
	{
622 623 624
			/*
			 * control nodes
			 */
625 626
		case T_ResultState:
			ExecEndResult((ResultState *) node);
627 628
			break;

629 630
		case T_AppendState:
			ExecEndAppend((AppendState *) node);
631 632
			break;

633 634 635 636 637 638 639 640
		case T_BitmapAndState:
			ExecEndBitmapAnd((BitmapAndState *) node);
			break;

		case T_BitmapOrState:
			ExecEndBitmapOr((BitmapOrState *) node);
			break;

641 642
			/*
			 * scan nodes
643
			 */
644 645
		case T_SeqScanState:
			ExecEndSeqScan((SeqScanState *) node);
646 647
			break;

648 649
		case T_IndexScanState:
			ExecEndIndexScan((IndexScanState *) node);
650 651
			break;

652 653 654 655 656 657 658 659
		case T_BitmapIndexScanState:
			ExecEndBitmapIndexScan((BitmapIndexScanState *) node);
			break;

		case T_BitmapHeapScanState:
			ExecEndBitmapHeapScan((BitmapHeapScanState *) node);
			break;

660 661
		case T_TidScanState:
			ExecEndTidScan((TidScanState *) node);
662 663
			break;

664 665
		case T_SubqueryScanState:
			ExecEndSubqueryScan((SubqueryScanState *) node);
666 667
			break;

668 669
		case T_FunctionScanState:
			ExecEndFunctionScan((FunctionScanState *) node);
670 671
			break;

672 673
			/*
			 * join nodes
674
			 */
675 676
		case T_NestLoopState:
			ExecEndNestLoop((NestLoopState *) node);
677 678
			break;

679 680
		case T_MergeJoinState:
			ExecEndMergeJoin((MergeJoinState *) node);
681 682
			break;

683 684
		case T_HashJoinState:
			ExecEndHashJoin((HashJoinState *) node);
685 686
			break;

687 688
			/*
			 * materialization nodes
689
			 */
690 691
		case T_MaterialState:
			ExecEndMaterial((MaterialState *) node);
692 693
			break;

694 695
		case T_SortState:
			ExecEndSort((SortState *) node);
696 697
			break;

698 699
		case T_GroupState:
			ExecEndGroup((GroupState *) node);
700 701
			break;

702 703
		case T_AggState:
			ExecEndAgg((AggState *) node);
704 705
			break;

706 707
		case T_UniqueState:
			ExecEndUnique((UniqueState *) node);
708 709
			break;

710 711
		case T_HashState:
			ExecEndHash((HashState *) node);
712 713
			break;

714 715 716 717 718 719
		case T_SetOpState:
			ExecEndSetOp((SetOpState *) node);
			break;

		case T_LimitState:
			ExecEndLimit((LimitState *) node);
720 721 722
			break;

		default:
723
			elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
724
			break;
725
	}
726
}