execUtils.c 31.1 KB
Newer Older
1 2
/*-------------------------------------------------------------------------
 *
3
 * execUtils.c
4
 *	  miscellaneous executor utility routines
5
 *
P
 
PostgreSQL Daemon 已提交
6
 * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
B
Add:  
Bruce Momjian 已提交
7
 * Portions Copyright (c) 1994, Regents of the University of California
8 9 10
 *
 *
 * IDENTIFICATION
11
 *	  $PostgreSQL: pgsql/src/backend/executor/execUtils.c,v 1.130 2005/12/02 20:03:40 tgl Exp $
12 13 14 15 16
 *
 *-------------------------------------------------------------------------
 */
/*
 * INTERFACE ROUTINES
17 18 19 20
 *		CreateExecutorState		Create/delete executor working state
 *		FreeExecutorState
 *		CreateExprContext
 *		FreeExprContext
21
 *		ReScanExprContext
22
 *
23
 *		ExecAssignExprContext	Common code for plan node init routines.
24 25
 *		ExecAssignResultType
 *		etc
26
 *
27 28 29
 *		ExecOpenScanRelation	Common code for scan node init routines.
 *		ExecCloseScanRelation
 *
30 31
 *		ExecOpenIndices			\
 *		ExecCloseIndices		 | referenced by InitPlan, EndPlan,
32
 *		ExecInsertIndexTuples	/  ExecInsert, ExecUpdate
33
 *
34 35 36
 *		RegisterExprContextCallback    Register function shutdown callback
 *		UnregisterExprContextCallback  Deregister function shutdown callback
 *
37 38 39
 *	 NOTES
 *		This file has traditionally been the place to stick misc.
 *		executor support stuff that doesn't really go anyplace else.
40 41
 */

42 43
#include "postgres.h"

44
#include "access/genam.h"
B
Bruce Momjian 已提交
45 46
#include "access/heapam.h"
#include "catalog/index.h"
H
Hiroshi Inoue 已提交
47
#include "catalog/catalog.h"
B
Bruce Momjian 已提交
48
#include "catalog/pg_index.h"
B
Bruce Momjian 已提交
49
#include "executor/execdebug.h"
H
Hiroshi Inoue 已提交
50
#include "miscadmin.h"
51
#include "parser/parsetree.h"
52 53
#include "utils/builtins.h"
#include "utils/fmgroids.h"
54
#include "utils/memutils.h"
55 56
#include "utils/relcache.h"
#include "utils/syscache.h"
57

58

59
/* ----------------------------------------------------------------
60 61
 *		global counters for number of tuples processed, retrieved,
 *		appended, replaced, deleted.
62 63
 * ----------------------------------------------------------------
 */
64 65 66 67 68 69
int			NTupleProcessed;
int			NTupleRetrieved;
int			NTupleReplaced;
int			NTupleAppended;
int			NTupleDeleted;
int			NIndexTupleInserted;
B
Bruce Momjian 已提交
70 71
extern int	NIndexTupleProcessed;		/* have to be defined in the access
										 * method level so that the
72
										 * cinterface.a will link ok. */
73

74 75 76

static void ShutdownExprContext(ExprContext *econtext);

77

78
/* ----------------------------------------------------------------
79
 *						statistic functions
80 81 82 83
 * ----------------------------------------------------------------
 */

/* ----------------------------------------------------------------
84
 *		ResetTupleCount
85 86
 * ----------------------------------------------------------------
 */
87
#ifdef NOT_USED
88
void
89
ResetTupleCount(void)
90
{
91 92 93 94 95 96
	NTupleProcessed = 0;
	NTupleRetrieved = 0;
	NTupleAppended = 0;
	NTupleDeleted = 0;
	NTupleReplaced = 0;
	NIndexTupleProcessed = 0;
97
}
98
#endif
99 100

/* ----------------------------------------------------------------
101
 *		PrintTupleCount
102 103
 * ----------------------------------------------------------------
 */
104
#ifdef NOT_USED
105
void
106
DisplayTupleCount(FILE *statfp)
107
{
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
	if (NTupleProcessed > 0)
		fprintf(statfp, "!\t%d tuple%s processed, ", NTupleProcessed,
				(NTupleProcessed == 1) ? "" : "s");
	else
	{
		fprintf(statfp, "!\tno tuples processed.\n");
		return;
	}
	if (NIndexTupleProcessed > 0)
		fprintf(statfp, "%d indextuple%s processed, ", NIndexTupleProcessed,
				(NIndexTupleProcessed == 1) ? "" : "s");
	if (NIndexTupleInserted > 0)
		fprintf(statfp, "%d indextuple%s inserted, ", NIndexTupleInserted,
				(NIndexTupleInserted == 1) ? "" : "s");
	if (NTupleRetrieved > 0)
		fprintf(statfp, "%d tuple%s retrieved. ", NTupleRetrieved,
				(NTupleRetrieved == 1) ? "" : "s");
	if (NTupleAppended > 0)
		fprintf(statfp, "%d tuple%s appended. ", NTupleAppended,
				(NTupleAppended == 1) ? "" : "s");
	if (NTupleDeleted > 0)
		fprintf(statfp, "%d tuple%s deleted. ", NTupleDeleted,
				(NTupleDeleted == 1) ? "" : "s");
	if (NTupleReplaced > 0)
		fprintf(statfp, "%d tuple%s replaced. ", NTupleReplaced,
				(NTupleReplaced == 1) ? "" : "s");
	fprintf(statfp, "\n");
135
}
136
#endif
137

138

139
/* ----------------------------------------------------------------
140
 *				 Executor state and memory management functions
141 142 143 144
 * ----------------------------------------------------------------
 */

/* ----------------
145
 *		CreateExecutorState
146
 *
147 148
 *		Create and initialize an EState node, which is the root of
 *		working storage for an entire Executor invocation.
149
 *
150 151 152 153
 * Principally, this creates the per-query memory context that will be
 * used to hold all working data that lives till the end of the query.
 * Note that the per-query context will become a child of the caller's
 * CurrentMemoryContext.
154 155
 * ----------------
 */
156 157
EState *
CreateExecutorState(void)
158
{
159 160 161
	EState	   *estate;
	MemoryContext qcontext;
	MemoryContext oldcontext;
162

163 164 165 166 167 168 169 170
	/*
	 * Create the per-query context for this Executor run.
	 */
	qcontext = AllocSetContextCreate(CurrentMemoryContext,
									 "ExecutorState",
									 ALLOCSET_DEFAULT_MINSIZE,
									 ALLOCSET_DEFAULT_INITSIZE,
									 ALLOCSET_DEFAULT_MAXSIZE);
B
Bruce Momjian 已提交
171

172
	/*
B
Bruce Momjian 已提交
173 174
	 * Make the EState node within the per-query context.  This way, we don't
	 * need a separate pfree() operation for it at shutdown.
175
	 */
176 177 178 179 180 181 182 183 184
	oldcontext = MemoryContextSwitchTo(qcontext);

	estate = makeNode(EState);

	/*
	 * Initialize all fields of the Executor State structure
	 */
	estate->es_direction = ForwardScanDirection;
	estate->es_snapshot = SnapshotNow;
185
	estate->es_crosscheck_snapshot = InvalidSnapshot;	/* no crosscheck */
186 187 188 189 190 191 192
	estate->es_range_table = NIL;

	estate->es_result_relations = NULL;
	estate->es_num_result_relations = 0;
	estate->es_result_relation_info = NULL;

	estate->es_junkFilter = NULL;
193

194 195
	estate->es_trig_tuple_slot = NULL;

196
	estate->es_into_relation_descriptor = NULL;
197
	estate->es_into_relation_use_wal = false;
198 199 200 201 202 203 204

	estate->es_param_list_info = NULL;
	estate->es_param_exec_vals = NULL;

	estate->es_query_cxt = qcontext;

	estate->es_tupleTable = NULL;
205

206 207
	estate->es_processed = 0;
	estate->es_lastoid = InvalidOid;
208
	estate->es_rowMarks = NIL;
209
	estate->es_forUpdate = false;
210
	estate->es_rowNoWait = false;
211 212

	estate->es_instrument = false;
213 214
	estate->es_select_into = false;
	estate->es_into_oids = false;
215 216 217 218 219

	estate->es_exprcontexts = NIL;

	estate->es_per_tuple_exprcontext = NULL;

220
	estate->es_topPlan = NULL;
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252
	estate->es_evalPlanQual = NULL;
	estate->es_evTupleNull = NULL;
	estate->es_evTuple = NULL;
	estate->es_useEvalPlan = false;

	/*
	 * Return the executor state structure
	 */
	MemoryContextSwitchTo(oldcontext);

	return estate;
}

/* ----------------
 *		FreeExecutorState
 *
 *		Release an EState along with all remaining working storage.
 *
 * Note: this is not responsible for releasing non-memory resources,
 * such as open relations or buffer pins.  But it will shut down any
 * still-active ExprContexts within the EState.  That is sufficient
 * cleanup for situations where the EState has only been used for expression
 * evaluation, and not to run a complete Plan.
 *
 * This can be called in any memory context ... so long as it's not one
 * of the ones to be freed.
 * ----------------
 */
void
FreeExecutorState(EState *estate)
{
	/*
B
Bruce Momjian 已提交
253 254 255 256
	 * Shut down and free any remaining ExprContexts.  We do this explicitly
	 * to ensure that any remaining shutdown callbacks get called (since they
	 * might need to release resources that aren't simply memory within the
	 * per-query memory context).
257 258 259
	 */
	while (estate->es_exprcontexts)
	{
B
Bruce Momjian 已提交
260
		/*
B
Bruce Momjian 已提交
261 262
		 * XXX: seems there ought to be a faster way to implement this than
		 * repeated list_delete(), no?
263 264
		 */
		FreeExprContext((ExprContext *) linitial(estate->es_exprcontexts));
265 266
		/* FreeExprContext removed the list link for us */
	}
B
Bruce Momjian 已提交
267

268 269 270 271 272
	/*
	 * Free the per-query memory context, thereby releasing all working
	 * memory, including the EState node itself.
	 */
	MemoryContextDelete(estate->es_query_cxt);
273 274 275
}

/* ----------------
276 277 278 279 280 281 282 283
 *		CreateExprContext
 *
 *		Create a context for expression evaluation within an EState.
 *
 * An executor run may require multiple ExprContexts (we usually make one
 * for each Plan node, and a separate one for per-output-tuple processing
 * such as constraint checking).  Each ExprContext has its own "per-tuple"
 * memory context.
284
 *
285
 * Note we make no assumption about the caller's memory context.
286 287
 * ----------------
 */
288
ExprContext *
289
CreateExprContext(EState *estate)
290
{
291 292
	ExprContext *econtext;
	MemoryContext oldcontext;
293

294 295 296 297 298 299 300
	/* Create the ExprContext node within the per-query memory context */
	oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);

	econtext = makeNode(ExprContext);

	/* Initialize fields of ExprContext */
	econtext->ecxt_scantuple = NULL;
301 302
	econtext->ecxt_innertuple = NULL;
	econtext->ecxt_outertuple = NULL;
303 304

	econtext->ecxt_per_query_memory = estate->es_query_cxt;
B
Bruce Momjian 已提交
305

306
	/*
307
	 * Create working memory for expression evaluation in this context.
308 309
	 */
	econtext->ecxt_per_tuple_memory =
310 311 312
		AllocSetContextCreate(estate->es_query_cxt,
							  "ExprContext",
							  ALLOCSET_DEFAULT_MINSIZE,
313 314
							  ALLOCSET_DEFAULT_INITSIZE,
							  ALLOCSET_DEFAULT_MAXSIZE);
315 316 317 318

	econtext->ecxt_param_exec_vals = estate->es_param_exec_vals;
	econtext->ecxt_param_list_info = estate->es_param_list_info;

319 320
	econtext->ecxt_aggvalues = NULL;
	econtext->ecxt_aggnulls = NULL;
321

322 323 324
	econtext->caseValue_datum = (Datum) 0;
	econtext->caseValue_isNull = true;

325 326 327 328 329
	econtext->domainValue_datum = (Datum) 0;
	econtext->domainValue_isNull = true;

	econtext->ecxt_estate = estate;

330
	econtext->ecxt_callbacks = NULL;
331

332
	/*
B
Bruce Momjian 已提交
333 334 335
	 * Link the ExprContext into the EState to ensure it is shut down when the
	 * EState is freed.  Because we use lcons(), shutdowns will occur in
	 * reverse order of creation, which may not be essential but can't hurt.
336 337 338 339 340
	 */
	estate->es_exprcontexts = lcons(econtext, estate->es_exprcontexts);

	MemoryContextSwitchTo(oldcontext);

341 342
	return econtext;
}
343

344 345 346 347 348 349 350 351 352 353 354
/* ----------------
 *		FreeExprContext
 *
 *		Free an expression context, including calling any remaining
 *		shutdown callbacks.
 *
 * Since we free the temporary context used for expression evaluation,
 * any previously computed pass-by-reference expression result will go away!
 *
 * Note we make no assumption about the caller's memory context.
 * ----------------
355 356 357 358
 */
void
FreeExprContext(ExprContext *econtext)
{
359 360
	EState	   *estate;

361 362 363
	/* Call any registered callbacks */
	ShutdownExprContext(econtext);
	/* And clean up the memory used */
364
	MemoryContextDelete(econtext->ecxt_per_tuple_memory);
365 366
	/* Unlink self from owning EState */
	estate = econtext->ecxt_estate;
367
	estate->es_exprcontexts = list_delete_ptr(estate->es_exprcontexts, econtext);
368
	/* And delete the ExprContext node */
369
	pfree(econtext);
370 371
}

372 373 374 375
/*
 * ReScanExprContext
 *
 *		Reset an expression context in preparation for a rescan of its
B
Bruce Momjian 已提交
376
 *		plan node.	This requires calling any registered shutdown callbacks,
377 378 379 380 381 382 383 384 385 386 387 388 389
 *		since any partially complete set-returning-functions must be canceled.
 *
 * Note we make no assumption about the caller's memory context.
 */
void
ReScanExprContext(ExprContext *econtext)
{
	/* Call any registered callbacks */
	ShutdownExprContext(econtext);
	/* And clean up the memory used */
	MemoryContextReset(econtext->ecxt_per_tuple_memory);
}

390 391 392
/*
 * Build a per-output-tuple ExprContext for an EState.
 *
393 394
 * This is normally invoked via GetPerTupleExprContext() macro,
 * not directly.
395 396 397 398 399
 */
ExprContext *
MakePerTupleExprContext(EState *estate)
{
	if (estate->es_per_tuple_exprcontext == NULL)
400
		estate->es_per_tuple_exprcontext = CreateExprContext(estate);
401 402 403 404

	return estate->es_per_tuple_exprcontext;
}

405

406
/* ----------------------------------------------------------------
407 408 409 410
 *				 miscellaneous node-init support functions
 *
 * Note: all of these are expected to be called with CurrentMemoryContext
 * equal to the per-query memory context.
411 412 413
 * ----------------------------------------------------------------
 */

414 415 416
/* ----------------
 *		ExecAssignExprContext
 *
B
Bruce Momjian 已提交
417
 *		This initializes the ps_ExprContext field.	It is only necessary
418
 *		to do this for nodes which use ExecQual or ExecProject
B
Bruce Momjian 已提交
419
 *		because those routines require an econtext. Other nodes that
420 421 422 423
 *		don't have to evaluate expressions don't need to do this.
 * ----------------
 */
void
424
ExecAssignExprContext(EState *estate, PlanState *planstate)
425 426 427 428
{
	planstate->ps_ExprContext = CreateExprContext(estate);
}

429
/* ----------------
430
 *		ExecAssignResultType
431 432 433
 * ----------------
 */
void
434
ExecAssignResultType(PlanState *planstate,
435
					 TupleDesc tupDesc, bool shouldFree)
436
{
437
	TupleTableSlot *slot = planstate->ps_ResultTupleSlot;
438

439
	ExecSetSlotDescriptor(slot, tupDesc, shouldFree);
440 441 442
}

/* ----------------
443
 *		ExecAssignResultTypeFromTL
444 445 446
 * ----------------
 */
void
447
ExecAssignResultTypeFromTL(PlanState *planstate)
448
{
449
	bool		hasoid;
450
	TupleDesc	tupDesc;
451

452 453 454 455
	if (ExecContextForcesOids(planstate, &hasoid))
	{
		/* context forces OID choice; hasoid is now set correctly */
	}
456
	else
457
	{
458 459
		/* given free choice, don't leave space for OIDs in result tuples */
		hasoid = false;
460
	}
B
Bruce Momjian 已提交
461

462
	/*
B
Bruce Momjian 已提交
463 464 465
	 * ExecTypeFromTL needs the parse-time representation of the tlist, not a
	 * list of ExprStates.	This is good because some plan nodes don't bother
	 * to set up planstate->targetlist ...
466 467 468
	 */
	tupDesc = ExecTypeFromTL(planstate->plan->targetlist, hasoid);
	ExecAssignResultType(planstate, tupDesc, true);
469 470 471
}

/* ----------------
472
 *		ExecGetResultType
473 474 475
 * ----------------
 */
TupleDesc
476
ExecGetResultType(PlanState *planstate)
477
{
478
	TupleTableSlot *slot = planstate->ps_ResultTupleSlot;
479

480
	return slot->tts_tupleDescriptor;
481 482 483
}

/* ----------------
484 485 486 487 488 489
 *		ExecBuildProjectionInfo
 *
 * Build a ProjectionInfo node for evaluating the given tlist in the given
 * econtext, and storing the result into the tuple slot.  (Caller must have
 * ensured that tuple slot has a descriptor matching the tlist!)  Note that
 * the given tlist should be a list of ExprState nodes, not Expr nodes.
490 491
 * ----------------
 */
492 493 494 495
ProjectionInfo *
ExecBuildProjectionInfo(List *targetList,
						ExprContext *econtext,
						TupleTableSlot *slot)
496
{
497
	ProjectionInfo *projInfo = makeNode(ProjectionInfo);
498
	int			len;
499 500
	bool		isVarList;
	ListCell   *tl;
501 502 503 504

	len = ExecTargetListLength(targetList);

	projInfo->pi_targetlist = targetList;
505 506
	projInfo->pi_exprContext = econtext;
	projInfo->pi_slot = slot;
507 508 509

	/*
	 * Determine whether the target list consists entirely of simple Var
B
Bruce Momjian 已提交
510 511
	 * references (ie, references to non-system attributes).  If so, we can
	 * use the simpler ExecVariableList instead of ExecTargetList.
512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536
	 */
	isVarList = true;
	foreach(tl, targetList)
	{
		GenericExprState *gstate = (GenericExprState *) lfirst(tl);
		Var		   *variable = (Var *) gstate->arg->expr;

		if (variable == NULL ||
			!IsA(variable, Var) ||
			variable->varattno <= 0)
		{
			isVarList = false;
			break;
		}
	}
	projInfo->pi_isVarList = isVarList;

	if (isVarList)
	{
		int		   *varSlotOffsets;
		int		   *varNumbers;
		AttrNumber	lastInnerVar = 0;
		AttrNumber	lastOuterVar = 0;
		AttrNumber	lastScanVar = 0;

B
Bruce Momjian 已提交
537
		projInfo->pi_itemIsDone = NULL; /* not needed */
538 539 540 541 542 543
		projInfo->pi_varSlotOffsets = varSlotOffsets = (int *)
			palloc0(len * sizeof(int));
		projInfo->pi_varNumbers = varNumbers = (int *)
			palloc0(len * sizeof(int));

		/*
B
Bruce Momjian 已提交
544 545 546 547 548
		 * Set up the data needed by ExecVariableList.	The slots in which the
		 * variables can be found at runtime are denoted by the offsets of
		 * their slot pointers within the econtext.  This rather grotty
		 * representation is needed because the caller may not have given us
		 * the real econtext yet (see hacks in nodeSubplan.c).
549 550 551 552 553 554 555
		 */
		foreach(tl, targetList)
		{
			GenericExprState *gstate = (GenericExprState *) lfirst(tl);
			Var		   *variable = (Var *) gstate->arg->expr;
			AttrNumber	attnum = variable->varattno;
			TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
556
			AttrNumber	resind = tle->resno - 1;
557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586

			Assert(resind >= 0 && resind < len);
			varNumbers[resind] = attnum;

			switch (variable->varno)
			{
				case INNER:
					varSlotOffsets[resind] = offsetof(ExprContext,
													  ecxt_innertuple);
					lastInnerVar = Max(lastInnerVar, attnum);
					break;

				case OUTER:
					varSlotOffsets[resind] = offsetof(ExprContext,
													  ecxt_outertuple);
					lastOuterVar = Max(lastOuterVar, attnum);
					break;

				default:
					varSlotOffsets[resind] = offsetof(ExprContext,
													  ecxt_scantuple);
					lastScanVar = Max(lastScanVar, attnum);
					break;
			}
		}
		projInfo->pi_lastInnerVar = lastInnerVar;
		projInfo->pi_lastOuterVar = lastOuterVar;
		projInfo->pi_lastScanVar = lastScanVar;
	}
	else
587
	{
588 589 590 591
		projInfo->pi_itemIsDone = (ExprDoneCond *)
			palloc(len * sizeof(ExprDoneCond));
		projInfo->pi_varSlotOffsets = NULL;
		projInfo->pi_varNumbers = NULL;
592 593 594 595
	}

	return projInfo;
}
596

597 598 599 600 601 602 603
/* ----------------
 *		ExecAssignProjectionInfo
 *
 * forms the projection information from the node's targetlist
 * ----------------
 */
void
604
ExecAssignProjectionInfo(PlanState *planstate)
605 606 607 608 609
{
	planstate->ps_ProjInfo =
		ExecBuildProjectionInfo(planstate->targetlist,
								planstate->ps_ExprContext,
								planstate->ps_ResultTupleSlot);
610 611 612
}


613 614
/* ----------------
 *		ExecFreeExprContext
615
 *
616 617 618
 * A plan node's ExprContext should be freed explicitly during executor
 * shutdown because there may be shutdown callbacks to call.  (Other resources
 * made by the above routines, such as projection info, don't need to be freed
619
 * explicitly because they're just memory in the per-query memory context.)
620 621 622
 *
 * However ... there is no particular need to do it during ExecEndNode,
 * because FreeExecutorState will free any remaining ExprContexts within
B
Bruce Momjian 已提交
623
 * the EState.	Letting FreeExecutorState do it allows the ExprContexts to
624 625 626
 * be freed in reverse order of creation, rather than order of creation as
 * will happen if we delete them here, which saves O(N^2) work in the list
 * cleanup inside FreeExprContext.
627 628 629
 * ----------------
 */
void
630
ExecFreeExprContext(PlanState *planstate)
631
{
632
	/*
B
Bruce Momjian 已提交
633 634
	 * Per above discussion, don't actually delete the ExprContext. We do
	 * unlink it from the plan node, though.
635
	 */
636
	planstate->ps_ExprContext = NULL;
637 638
}

639
/* ----------------------------------------------------------------
640 641 642 643 644 645
 *		the following scan type support functions are for
 *		those nodes which are stubborn and return tuples in
 *		their Scan tuple slot instead of their Result tuple
 *		slot..	luck fur us, these nodes do not do projections
 *		so we don't have to worry about getting the ProjectionInfo
 *		right for them...  -cim 6/3/91
646 647 648 649
 * ----------------------------------------------------------------
 */

/* ----------------
650
 *		ExecGetScanType
651 652 653
 * ----------------
 */
TupleDesc
654
ExecGetScanType(ScanState *scanstate)
655
{
656
	TupleTableSlot *slot = scanstate->ss_ScanTupleSlot;
657

658
	return slot->tts_tupleDescriptor;
659 660 661
}

/* ----------------
662
 *		ExecAssignScanType
663 664 665
 * ----------------
 */
void
666
ExecAssignScanType(ScanState *scanstate,
667
				   TupleDesc tupDesc, bool shouldFree)
668
{
669
	TupleTableSlot *slot = scanstate->ss_ScanTupleSlot;
670

671
	ExecSetSlotDescriptor(slot, tupDesc, shouldFree);
672 673 674
}

/* ----------------
675
 *		ExecAssignScanTypeFromOuterPlan
676 677 678
 * ----------------
 */
void
679
ExecAssignScanTypeFromOuterPlan(ScanState *scanstate)
680
{
681
	PlanState  *outerPlan;
682
	TupleDesc	tupDesc;
683

684
	outerPlan = outerPlanState(scanstate);
685
	tupDesc = ExecGetResultType(outerPlan);
686

687
	ExecAssignScanType(scanstate, tupDesc, false);
688 689 690
}


691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774
/* ----------------------------------------------------------------
 *				  Scan node support
 * ----------------------------------------------------------------
 */

/* ----------------------------------------------------------------
 *		ExecOpenScanRelation
 *
 *		Open the heap relation to be scanned by a base-level scan plan node.
 *		This should be called during the node's ExecInit routine.
 *
 * By default, this acquires AccessShareLock on the relation.  However,
 * if the relation was already locked by InitPlan, we don't need to acquire
 * any additional lock.  This saves trips to the shared lock manager.
 * ----------------------------------------------------------------
 */
Relation
ExecOpenScanRelation(EState *estate, Index scanrelid)
{
	RangeTblEntry *rtentry;
	Oid			reloid;
	LOCKMODE	lockmode;
	ResultRelInfo *resultRelInfos;
	int			i;

	/*
	 * First determine the lock type we need.  Scan to see if target relation
	 * is either a result relation or a FOR UPDATE/FOR SHARE relation.
	 */
	lockmode = AccessShareLock;
	resultRelInfos = estate->es_result_relations;
	for (i = 0; i < estate->es_num_result_relations; i++)
	{
		if (resultRelInfos[i].ri_RangeTableIndex == scanrelid)
		{
			lockmode = NoLock;
			break;
		}
	}

	if (lockmode == AccessShareLock)
	{
		ListCell   *l;

		foreach(l, estate->es_rowMarks)
		{
			ExecRowMark *erm = lfirst(l);

			if (erm->rti == scanrelid)
			{
				lockmode = NoLock;
				break;
			}
		}
	}

	/* OK, open the relation and acquire lock as needed */
	rtentry = rt_fetch(scanrelid, estate->es_range_table);
	reloid = rtentry->relid;

	return heap_open(reloid, lockmode);
}

/* ----------------------------------------------------------------
 *		ExecCloseScanRelation
 *
 *		Close the heap relation scanned by a base-level scan plan node.
 *		This should be called during the node's ExecEnd routine.
 *
 * Currently, we do not release the lock acquired by ExecOpenScanRelation.
 * This lock should be held till end of transaction.  (There is a faction
 * that considers this too much locking, however.)
 *
 * If we did want to release the lock, we'd have to repeat the logic in
 * ExecOpenScanRelation in order to figure out what to release.
 * ----------------------------------------------------------------
 */
void
ExecCloseScanRelation(Relation scanrel)
{
	heap_close(scanrel, NoLock);
}


775
/* ----------------------------------------------------------------
776
 *				  ExecInsertIndexTuples support
777 778
 * ----------------------------------------------------------------
 */
779 780 781 782

/* ----------------------------------------------------------------
 *		ExecOpenIndices
 *
783
 *		Find the indices associated with a result relation, open them,
784
 *		and save information about them in the result ResultRelInfo.
785
 *
786
 *		At entry, caller has already opened and locked
787
 *		resultRelInfo->ri_RelationDesc.
788
 *
789
 *		This used to be horribly ugly code, and slow too because it
B
Bruce Momjian 已提交
790
 *		did a sequential scan of pg_index.	Now we rely on the relcache
791 792 793
 *		to cache a list of the OIDs of the indices associated with any
 *		specific relation, and we use the pg_index syscache to get the
 *		entries we need from pg_index.
794 795 796
 * ----------------------------------------------------------------
 */
void
797
ExecOpenIndices(ResultRelInfo *resultRelInfo)
798
{
799
	Relation	resultRelation = resultRelInfo->ri_RelationDesc;
800 801
	List	   *indexoidlist;
	ListCell   *l;
802 803
	int			len,
				i;
804 805
	RelationPtr relationDescs;
	IndexInfo **indexInfoArray;
806

807
	resultRelInfo->ri_NumIndices = 0;
808

809
	/* fast path if no indexes */
B
Bruce Momjian 已提交
810
	if (!RelationGetForm(resultRelation)->relhasindex)
H
Hiroshi Inoue 已提交
811
		return;
812

813 814
	/*
	 * Get cached list of index OIDs
815
	 */
816
	indexoidlist = RelationGetIndexList(resultRelation);
817
	len = list_length(indexoidlist);
818 819
	if (len == 0)
		return;
820

821 822
	/*
	 * allocate space for result arrays
823
	 */
824 825 826
	relationDescs = (RelationPtr) palloc(len * sizeof(Relation));
	indexInfoArray = (IndexInfo **) palloc(len * sizeof(IndexInfo *));

827 828 829
	resultRelInfo->ri_NumIndices = len;
	resultRelInfo->ri_IndexRelationDescs = relationDescs;
	resultRelInfo->ri_IndexRelationInfo = indexInfoArray;
830

831 832
	/*
	 * For each index, open the index relation and save pg_index info.
833
	 */
834
	i = 0;
835
	foreach(l, indexoidlist)
836
	{
837
		Oid			indexOid = lfirst_oid(l);
838 839
		Relation	indexDesc;
		IndexInfo  *ii;
840

841
		/*
842 843
		 * Open and lock the index relation
		 *
844 845 846 847
		 * If the index AM supports concurrent updates, obtain
		 * RowExclusiveLock to signify that we are updating the index.	This
		 * locks out only operations that need exclusive access, such as
		 * relocating the index to a new tablespace.
848
		 *
849
		 * If the index AM is not safe for concurrent updates, obtain an
B
Bruce Momjian 已提交
850
		 * exclusive lock on the index to lock out other updaters as well as
851
		 * readers (index_beginscan places AccessShareLock on the index).
852
		 *
853 854 855 856
		 * If there are multiple not-concurrent-safe indexes, all backends
		 * must lock the indexes in the same order or we will get deadlocks
		 * here. This is guaranteed by RelationGetIndexList(), which promises
		 * to return the index list in OID order.
857 858
		 *
		 * The locks will be released in ExecCloseIndices.
859
		 */
860 861
		indexDesc = index_open(indexOid);

862 863 864
		if (indexDesc->rd_am->amconcurrent)
			LockRelation(indexDesc, RowExclusiveLock);
		else
865
			LockRelation(indexDesc, AccessExclusiveLock);
866

867 868
		/* extract index key information from the index's pg_index info */
		ii = BuildIndexInfo(indexDesc);
869

870 871 872
		relationDescs[i] = indexDesc;
		indexInfoArray[i] = ii;
		i++;
873
	}
874

875
	list_free(indexoidlist);
876 877 878
}

/* ----------------------------------------------------------------
879
 *		ExecCloseIndices
880
 *
881
 *		Close the index relations stored in resultRelInfo
882 883 884
 * ----------------------------------------------------------------
 */
void
885
ExecCloseIndices(ResultRelInfo *resultRelInfo)
886
{
887 888
	int			i;
	int			numIndices;
889
	RelationPtr indexDescs;
890

891
	numIndices = resultRelInfo->ri_NumIndices;
892
	indexDescs = resultRelInfo->ri_IndexRelationDescs;
893 894

	for (i = 0; i < numIndices; i++)
V
Vadim B. Mikheev 已提交
895
	{
896
		if (indexDescs[i] == NULL)
897
			continue;			/* shouldn't happen? */
B
Bruce Momjian 已提交
898

899 900 901 902
		/* Drop lock acquired by ExecOpenIndices */
		if (indexDescs[i]->rd_am->amconcurrent)
			UnlockRelation(indexDescs[i], RowExclusiveLock);
		else
903
			UnlockRelation(indexDescs[i], AccessExclusiveLock);
904

905
		index_close(indexDescs[i]);
V
Vadim B. Mikheev 已提交
906
	}
B
Bruce Momjian 已提交
907

908
	/*
909 910
	 * XXX should free indexInfo array here too?  Currently we assume that
	 * such stuff will be cleaned up automatically in FreeExecutorState.
911
	 */
912 913 914
}

/* ----------------------------------------------------------------
915
 *		ExecInsertIndexTuples
916
 *
917 918 919 920 921 922 923
 *		This routine takes care of inserting index tuples
 *		into all the relations indexing the result relation
 *		when a heap tuple is inserted into the result relation.
 *		Much of this code should be moved into the genam
 *		stuff as it only exists here because the genam stuff
 *		doesn't provide the functionality needed by the
 *		executor.. -cim 9/27/89
924 925 926
 * ----------------------------------------------------------------
 */
void
927
ExecInsertIndexTuples(TupleTableSlot *slot,
928
					  ItemPointer tupleid,
929
					  EState *estate,
930
					  bool is_vacuum)
931
{
932
	ResultRelInfo *resultRelInfo;
933 934 935 936 937 938
	int			i;
	int			numIndices;
	RelationPtr relationDescs;
	Relation	heapRelation;
	IndexInfo **indexInfoArray;
	ExprContext *econtext;
939 940
	Datum		values[INDEX_MAX_KEYS];
	bool		isnull[INDEX_MAX_KEYS];
941

942 943
	/*
	 * Get information from the result relation info structure.
944
	 */
945 946 947 948 949
	resultRelInfo = estate->es_result_relation_info;
	numIndices = resultRelInfo->ri_NumIndices;
	relationDescs = resultRelInfo->ri_IndexRelationDescs;
	indexInfoArray = resultRelInfo->ri_IndexRelationInfo;
	heapRelation = resultRelInfo->ri_RelationDesc;
950

951
	/*
B
Bruce Momjian 已提交
952 953
	 * We will use the EState's per-tuple context for evaluating predicates
	 * and index expressions (creating it if it's not already there).
954
	 */
955
	econtext = GetPerTupleExprContext(estate);
956 957 958

	/* Arrange for econtext's scan tuple to be the tuple under test */
	econtext->ecxt_scantuple = slot;
959

960 961
	/*
	 * for each index, form and insert the index tuple
962
	 */
963 964
	for (i = 0; i < numIndices; i++)
	{
965 966
		IndexInfo  *indexInfo;

967 968 969 970
		if (relationDescs[i] == NULL)
			continue;

		indexInfo = indexInfoArray[i];
971 972 973

		/* Check for partial index */
		if (indexInfo->ii_Predicate != NIL)
974
		{
975 976 977
			List	   *predicate;

			/*
B
Bruce Momjian 已提交
978 979
			 * If predicate state not set up yet, create it (in the estate's
			 * per-query context)
980 981 982 983 984 985 986 987 988 989
			 */
			predicate = indexInfo->ii_PredicateState;
			if (predicate == NIL)
			{
				predicate = (List *)
					ExecPrepareExpr((Expr *) indexInfo->ii_Predicate,
									estate);
				indexInfo->ii_PredicateState = predicate;
			}

990
			/* Skip this index-update if the predicate isn't satisfied */
991
			if (!ExecQual(predicate, econtext, false))
992 993 994
				continue;
		}

995
		/*
B
Bruce Momjian 已提交
996 997
		 * FormIndexDatum fills in its values and isnull parameters with the
		 * appropriate values for the column(s) of the index.
998
		 */
999
		FormIndexDatum(indexInfo,
1000
					   slot,
1001
					   estate,
1002 1003
					   values,
					   isnull);
1004

1005
		/*
B
Bruce Momjian 已提交
1006 1007 1008
		 * The index AM does the rest.	Note we suppress unique-index checks
		 * if we are being called from VACUUM, since VACUUM may need to move
		 * dead tuples that have the same keys as live ones.
1009
		 */
1010
		index_insert(relationDescs[i],	/* index relation */
B
Bruce Momjian 已提交
1011 1012 1013
					 values,	/* array of index Datums */
					 isnull,	/* null flags */
					 tupleid,	/* tid of heap tuple */
1014 1015
					 heapRelation,
					 relationDescs[i]->rd_index->indisunique && !is_vacuum);
1016

1017 1018
		/*
		 * keep track of index inserts for debugging
1019 1020 1021
		 */
		IncrIndexInserted();
	}
1022
}
V
Vadim B. Mikheev 已提交
1023

1024 1025 1026 1027
/*
 * UpdateChangedParamSet
 *		Add changed parameters to a plan node's chgParam set
 */
1028
void
1029
UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
V
Vadim B. Mikheev 已提交
1030
{
1031
	Bitmapset  *parmset;
1032

1033
	/*
B
Bruce Momjian 已提交
1034 1035
	 * The plan node only depends on params listed in its allParam set. Don't
	 * include anything else into its chgParam set.
1036 1037
	 */
	parmset = bms_intersect(node->plan->allParam, newchg);
B
Bruce Momjian 已提交
1038

1039
	/*
B
Bruce Momjian 已提交
1040 1041
	 * Keep node->chgParam == NULL if there's not actually any members; this
	 * allows the simplest possible tests in executor node files.
1042 1043 1044 1045 1046
	 */
	if (!bms_is_empty(parmset))
		node->chgParam = bms_join(node->chgParam, parmset);
	else
		bms_free(parmset);
V
Vadim B. Mikheev 已提交
1047
}
1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063

/*
 * Register a shutdown callback in an ExprContext.
 *
 * Shutdown callbacks will be called (in reverse order of registration)
 * when the ExprContext is deleted or rescanned.  This provides a hook
 * for functions called in the context to do any cleanup needed --- it's
 * particularly useful for functions returning sets.  Note that the
 * callback will *not* be called in the event that execution is aborted
 * by an error.
 */
void
RegisterExprContextCallback(ExprContext *econtext,
							ExprContextCallbackFunction function,
							Datum arg)
{
B
Bruce Momjian 已提交
1064
	ExprContext_CB *ecxt_callback;
1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089

	/* Save the info in appropriate memory context */
	ecxt_callback = (ExprContext_CB *)
		MemoryContextAlloc(econtext->ecxt_per_query_memory,
						   sizeof(ExprContext_CB));

	ecxt_callback->function = function;
	ecxt_callback->arg = arg;

	/* link to front of list for appropriate execution order */
	ecxt_callback->next = econtext->ecxt_callbacks;
	econtext->ecxt_callbacks = ecxt_callback;
}

/*
 * Deregister a shutdown callback in an ExprContext.
 *
 * Any list entries matching the function and arg will be removed.
 * This can be used if it's no longer necessary to call the callback.
 */
void
UnregisterExprContextCallback(ExprContext *econtext,
							  ExprContextCallbackFunction function,
							  Datum arg)
{
B
Bruce Momjian 已提交
1090 1091
	ExprContext_CB **prev_callback;
	ExprContext_CB *ecxt_callback;
1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115

	prev_callback = &econtext->ecxt_callbacks;

	while ((ecxt_callback = *prev_callback) != NULL)
	{
		if (ecxt_callback->function == function && ecxt_callback->arg == arg)
		{
			*prev_callback = ecxt_callback->next;
			pfree(ecxt_callback);
		}
		else
			prev_callback = &ecxt_callback->next;
	}
}

/*
 * Call all the shutdown callbacks registered in an ExprContext.
 *
 * The callback list is emptied (important in case this is only a rescan
 * reset, and not deletion of the ExprContext).
 */
static void
ShutdownExprContext(ExprContext *econtext)
{
B
Bruce Momjian 已提交
1116
	ExprContext_CB *ecxt_callback;
1117 1118 1119 1120 1121 1122 1123
	MemoryContext oldcontext;

	/* Fast path in normal case where there's nothing to do. */
	if (econtext->ecxt_callbacks == NULL)
		return;

	/*
B
Bruce Momjian 已提交
1124 1125
	 * Call the callbacks in econtext's per-tuple context.  This ensures that
	 * any memory they might leak will get cleaned up.
1126 1127
	 */
	oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
1128 1129 1130 1131 1132 1133 1134 1135 1136 1137

	/*
	 * Call each callback function in reverse registration order.
	 */
	while ((ecxt_callback = econtext->ecxt_callbacks) != NULL)
	{
		econtext->ecxt_callbacks = ecxt_callback->next;
		(*ecxt_callback->function) (ecxt_callback->arg);
		pfree(ecxt_callback);
	}
1138 1139

	MemoryContextSwitchTo(oldcontext);
1140
}