⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nodeindexscan.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 2 页
字号:
}/* ---------------------------------------------------------------- *		ExecIndexRestrPos * ---------------------------------------------------------------- */voidExecIndexRestrPos(IndexScanState *node){	index_restrpos(node->iss_ScanDesc);}/* ---------------------------------------------------------------- *		ExecInitIndexScan * *		Initializes the index scan's state information, creates *		scan keys, and opens the base and index relations. * *		Note: index scans have 2 sets of state information because *			  we have to keep track of the base relation and the *			  index relation. * ---------------------------------------------------------------- */IndexScanState *ExecInitIndexScan(IndexScan *node, EState *estate){	IndexScanState *indexstate;	ScanKey		scanKeys;	int			numScanKeys;	ExprState **runtimeKeyInfo;	bool		have_runtime_keys;	RangeTblEntry *rtentry;	Index		relid;	Oid			reloid;	Relation	currentRelation;	/*	 * create state structure	 */	indexstate = makeNode(IndexScanState);	indexstate->ss.ps.plan = (Plan *) node;	indexstate->ss.ps.state = estate;	/*	 * Miscellaneous initialization	 *	 * create expression context for node	 */	ExecAssignExprContext(estate, &indexstate->ss.ps);	/*	 * initialize child expressions	 *	 * Note: we don't initialize all of the indexqual expression, only the	 * sub-parts corresponding to runtime keys (see below).  The indexqualorig	 * expression is always initialized even though it will only be used in	 * some uncommon cases --- would be nice to improve that.  (Problem is	 * that any SubPlans present in the expression must be found now...)	 */	indexstate->ss.ps.targetlist = (List *)		ExecInitExpr((Expr *) node->scan.plan.targetlist,					 (PlanState *) indexstate);	indexstate->ss.ps.qual = (List *)		ExecInitExpr((Expr *) node->scan.plan.qual,					 (PlanState *) indexstate);	indexstate->indexqualorig = (List *)		ExecInitExpr((Expr *) node->indexqualorig,					 (PlanState *) indexstate);#define INDEXSCAN_NSLOTS 2	/*	 * tuple table initialization	 */	ExecInitResultTupleSlot(estate, &indexstate->ss.ps);	ExecInitScanTupleSlot(estate, &indexstate->ss);	/*	 * Initialize index-specific scan state	 */	indexstate->iss_RuntimeKeysReady = false;	CXT1_printf("ExecInitIndexScan: context is %d\n", CurrentMemoryContext);	/*	 * build the index scan keys from the index qualification	 */	have_runtime_keys =		ExecIndexBuildScanKeys((PlanState *) indexstate,							   node->indexqual,							   node->indexstrategy,							   node->indexsubtype,							   &runtimeKeyInfo,							   &scanKeys,							   &numScanKeys);	indexstate->iss_RuntimeKeyInfo = runtimeKeyInfo;	indexstate->iss_ScanKeys = scanKeys;	indexstate->iss_NumScanKeys = numScanKeys;	/*	 * If we have runtime keys, we need an ExprContext to evaluate them. The	 * node's standard context won't do because we want to reset that context	 * for every tuple.  So, build another context just like the other one...	 * -tgl 7/11/00	 */	if (have_runtime_keys)	{		ExprContext *stdecontext = indexstate->ss.ps.ps_ExprContext;		ExecAssignExprContext(estate, &indexstate->ss.ps);		indexstate->iss_RuntimeContext = indexstate->ss.ps.ps_ExprContext;		indexstate->ss.ps.ps_ExprContext = stdecontext;	}	else	{		indexstate->iss_RuntimeContext = NULL;	}	/*	 * open the base relation and acquire AccessShareLock on it.	 */	relid = node->scan.scanrelid;	rtentry = rt_fetch(relid, estate->es_range_table);	reloid = rtentry->relid;	currentRelation = heap_open(reloid, AccessShareLock);	indexstate->ss.ss_currentRelation = currentRelation;	indexstate->ss.ss_currentScanDesc = NULL;	/* no heap scan here */	/*	 * get the scan type from the relation descriptor.	 */	ExecAssignScanType(&indexstate->ss, RelationGetDescr(currentRelation), false);	/*	 * open the index relation and initialize relation and scan descriptors.	 * Note we acquire no locks here; the index machinery does its own locks	 * and unlocks.  (We rely on having AccessShareLock on the parent table to	 * ensure the index won't go away!)	 */	indexstate->iss_RelationDesc = index_open(node->indexid);	indexstate->iss_ScanDesc = index_beginscan(currentRelation,											   indexstate->iss_RelationDesc,											   estate->es_snapshot,											   numScanKeys,											   scanKeys);	/*	 * Initialize result tuple type and projection info.	 */	ExecAssignResultTypeFromTL(&indexstate->ss.ps);	ExecAssignScanProjectionInfo(&indexstate->ss);	/*	 * all done.	 */	return indexstate;}/* * ExecIndexBuildScanKeys *		Build the index scan keys from the index qualification * * Input params are: * * planstate: executor state node we are working for * quals: indexquals expressions * strategies: associated operator strategy numbers * subtypes: associated operator subtype OIDs * * Output params are: * * *runtimeKeyInfo: receives ptr to array of runtime key exprstates *		(NULL if no runtime keys) * *scanKeys: receives ptr to array of ScanKeys * *numScanKeys: receives number of scankeys/runtime keys * * Return value is TRUE if any runtime key expressions were found, else FALSE. */boolExecIndexBuildScanKeys(PlanState *planstate, List *quals,					   List *strategies, List *subtypes,					   ExprState ***runtimeKeyInfo,					   ScanKey *scanKeys, int *numScanKeys){	bool		have_runtime_keys = false;	ListCell   *qual_cell;	ListCell   *strategy_cell;	ListCell   *subtype_cell;	int			n_keys;	ScanKey		scan_keys;	ExprState **run_keys;	int			j;	n_keys = list_length(quals);	scan_keys = (n_keys <= 0) ? NULL :		(ScanKey) palloc(n_keys * sizeof(ScanKeyData));	run_keys = (n_keys <= 0) ? NULL :		(ExprState **) palloc(n_keys * sizeof(ExprState *));	/*	 * for each opclause in the given qual, convert each qual's opclause into	 * a single scan key	 */	qual_cell = list_head(quals);	strategy_cell = list_head(strategies);	subtype_cell = list_head(subtypes);	for (j = 0; j < n_keys; j++)	{		OpExpr	   *clause;		/* one clause of index qual */		Expr	   *leftop;		/* expr on lhs of operator */		Expr	   *rightop;	/* expr on rhs ... */		int			flags = 0;		AttrNumber	varattno;	/* att number used in scan */		StrategyNumber strategy;	/* op's strategy number */		Oid			subtype;	/* op's strategy subtype */		RegProcedure opfuncid;	/* operator proc id used in scan */		Datum		scanvalue;	/* value used in scan (if const) */		/*		 * extract clause information from the qualification		 */		clause = (OpExpr *) lfirst(qual_cell);		qual_cell = lnext(qual_cell);		strategy = lfirst_int(strategy_cell);		strategy_cell = lnext(strategy_cell);		subtype = lfirst_oid(subtype_cell);		subtype_cell = lnext(subtype_cell);		if (!IsA(clause, OpExpr))			elog(ERROR, "indexqual is not an OpExpr");		opfuncid = clause->opfuncid;		/*		 * Here we figure out the contents of the index qual. The usual case		 * is (var op const) which means we form a scan key for the attribute		 * listed in the var node and use the value of the const as comparison		 * data.		 *		 * If we don't have a const node, it means our scan key is a function		 * of information obtained during the execution of the plan, in which		 * case we need to recalculate the index scan key at run time.	Hence,		 * we set have_runtime_keys to true and place the appropriate		 * subexpression in run_keys. The corresponding scan key values are		 * recomputed at run time.		 */		run_keys[j] = NULL;		/*		 * determine information in leftop		 */		leftop = (Expr *) get_leftop((Expr *) clause);		if (leftop && IsA(leftop, RelabelType))			leftop = ((RelabelType *) leftop)->arg;		Assert(leftop != NULL);		if (!(IsA(leftop, Var) &&			  var_is_rel((Var *) leftop)))			elog(ERROR, "indexqual doesn't have key on left side");		varattno = ((Var *) leftop)->varattno;		/*		 * now determine information in rightop		 */		rightop = (Expr *) get_rightop((Expr *) clause);		if (rightop && IsA(rightop, RelabelType))			rightop = ((RelabelType *) rightop)->arg;		Assert(rightop != NULL);		if (IsA(rightop, Const))		{			/*			 * if the rightop is a const node then it means it identifies the			 * value to place in our scan key.			 */			scanvalue = ((Const *) rightop)->constvalue;			if (((Const *) rightop)->constisnull)				flags |= SK_ISNULL;		}		else		{			/*			 * otherwise, the rightop contains an expression evaluable at			 * runtime to figure out the value to place in our scan key.			 */			have_runtime_keys = true;			run_keys[j] = ExecInitExpr(rightop, planstate);			scanvalue = (Datum) 0;		}		/*		 * initialize the scan key's fields appropriately		 */		ScanKeyEntryInitialize(&scan_keys[j],							   flags,							   varattno,		/* attribute number to scan */							   strategy,		/* op's strategy */							   subtype, /* strategy subtype */							   opfuncid,		/* reg proc to use */							   scanvalue);		/* constant */	}	/* If no runtime keys, get rid of speculatively-allocated array */	if (run_keys && !have_runtime_keys)	{		pfree(run_keys);		run_keys = NULL;	}	/*	 * Return the info to our caller.	 */	*numScanKeys = n_keys;	*scanKeys = scan_keys;	*runtimeKeyInfo = run_keys;	return have_runtime_keys;}intExecCountSlotsIndexScan(IndexScan *node){	return ExecCountSlotsNode(outerPlan((Plan *) node)) +		ExecCountSlotsNode(innerPlan((Plan *) node)) + INDEXSCAN_NSLOTS;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -