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

📄 setrefs.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 3 页
字号:
		TargetEntry *ctle = (TargetEntry *) lfirst(lc);		Var		   *var = (Var *) ptle->expr;		if (ptle->resjunk != ctle->resjunk)			return false;		/* tlist doesn't match junk status */		if (!var || !IsA(var, Var))			return false;		/* tlist item not a Var */		Assert(var->varno == plan->scan.scanrelid);		Assert(var->varlevelsup == 0);		if (var->varattno != attrno)			return false;		/* out of order */		attrno++;	}	return true;}/* * adjust_plan_varnos *		Offset varnos and other rangetable indexes in a plan tree by rtoffset. */static voidadjust_plan_varnos(Plan *plan, int rtoffset){	ListCell   *l;	if (plan == NULL)		return;	/*	 * Plan-type-specific fixes	 */	switch (nodeTag(plan))	{		case T_SeqScan:			((SeqScan *) plan)->scanrelid += rtoffset;			adjust_expr_varnos((Node *) plan->targetlist, rtoffset);			adjust_expr_varnos((Node *) plan->qual, rtoffset);			break;		case T_IndexScan:			((IndexScan *) plan)->scan.scanrelid += rtoffset;			adjust_expr_varnos((Node *) plan->targetlist, rtoffset);			adjust_expr_varnos((Node *) plan->qual, rtoffset);			adjust_expr_varnos((Node *) ((IndexScan *) plan)->indexqual,							   rtoffset);			adjust_expr_varnos((Node *) ((IndexScan *) plan)->indexqualorig,							   rtoffset);			break;		case T_BitmapIndexScan:			((BitmapIndexScan *) plan)->scan.scanrelid += rtoffset;			/* no need to fix targetlist and qual */			Assert(plan->targetlist == NIL);			Assert(plan->qual == NIL);			adjust_expr_varnos((Node *) ((BitmapIndexScan *) plan)->indexqual,							   rtoffset);			adjust_expr_varnos((Node *) ((BitmapIndexScan *) plan)->indexqualorig,							   rtoffset);			break;		case T_BitmapHeapScan:			((BitmapHeapScan *) plan)->scan.scanrelid += rtoffset;			adjust_expr_varnos((Node *) plan->targetlist, rtoffset);			adjust_expr_varnos((Node *) plan->qual, rtoffset);			adjust_expr_varnos((Node *) ((BitmapHeapScan *) plan)->bitmapqualorig,							   rtoffset);			break;		case T_TidScan:			((TidScan *) plan)->scan.scanrelid += rtoffset;			adjust_expr_varnos((Node *) plan->targetlist, rtoffset);			adjust_expr_varnos((Node *) plan->qual, rtoffset);			adjust_expr_varnos((Node *) ((TidScan *) plan)->tideval,							   rtoffset);			break;		case T_SubqueryScan:			((SubqueryScan *) plan)->scan.scanrelid += rtoffset;			adjust_expr_varnos((Node *) plan->targetlist, rtoffset);			adjust_expr_varnos((Node *) plan->qual, rtoffset);			/* we should not recurse into the subquery! */			break;		case T_FunctionScan:			((FunctionScan *) plan)->scan.scanrelid += rtoffset;			adjust_expr_varnos((Node *) plan->targetlist, rtoffset);			adjust_expr_varnos((Node *) plan->qual, rtoffset);			/* rte was already fixed by set_subqueryscan_references */			break;		case T_NestLoop:			adjust_expr_varnos((Node *) plan->targetlist, rtoffset);			adjust_expr_varnos((Node *) plan->qual, rtoffset);			adjust_expr_varnos((Node *) ((Join *) plan)->joinqual, rtoffset);			break;		case T_MergeJoin:			adjust_expr_varnos((Node *) plan->targetlist, rtoffset);			adjust_expr_varnos((Node *) plan->qual, rtoffset);			adjust_expr_varnos((Node *) ((Join *) plan)->joinqual, rtoffset);			adjust_expr_varnos((Node *) ((MergeJoin *) plan)->mergeclauses,							   rtoffset);			break;		case T_HashJoin:			adjust_expr_varnos((Node *) plan->targetlist, rtoffset);			adjust_expr_varnos((Node *) plan->qual, rtoffset);			adjust_expr_varnos((Node *) ((Join *) plan)->joinqual, rtoffset);			adjust_expr_varnos((Node *) ((HashJoin *) plan)->hashclauses,							   rtoffset);			break;		case T_Hash:		case T_Material:		case T_Sort:		case T_Unique:		case T_SetOp:			/*			 * Even though the targetlist won't be used by the executor, we			 * fix it up for possible use by EXPLAIN (not to mention ease of			 * debugging --- wrong varnos are very confusing).			 */			adjust_expr_varnos((Node *) plan->targetlist, rtoffset);			Assert(plan->qual == NIL);			break;		case T_Limit:			/*			 * Like the plan types above, Limit doesn't evaluate its tlist or			 * quals.  It does have live expressions for limit/offset,			 * however.			 */			adjust_expr_varnos((Node *) plan->targetlist, rtoffset);			Assert(plan->qual == NIL);			adjust_expr_varnos(((Limit *) plan)->limitOffset, rtoffset);			adjust_expr_varnos(((Limit *) plan)->limitCount, rtoffset);			break;		case T_Agg:		case T_Group:			adjust_expr_varnos((Node *) plan->targetlist, rtoffset);			adjust_expr_varnos((Node *) plan->qual, rtoffset);			break;		case T_Result:			adjust_expr_varnos((Node *) plan->targetlist, rtoffset);			adjust_expr_varnos((Node *) plan->qual, rtoffset);			adjust_expr_varnos(((Result *) plan)->resconstantqual, rtoffset);			break;		case T_Append:			adjust_expr_varnos((Node *) plan->targetlist, rtoffset);			Assert(plan->qual == NIL);			foreach(l, ((Append *) plan)->appendplans)				adjust_plan_varnos((Plan *) lfirst(l), rtoffset);			break;		case T_BitmapAnd:			/* BitmapAnd works like Append, but has no tlist */			Assert(plan->targetlist == NIL);			Assert(plan->qual == NIL);			foreach(l, ((BitmapAnd *) plan)->bitmapplans)				adjust_plan_varnos((Plan *) lfirst(l), rtoffset);			break;		case T_BitmapOr:			/* BitmapOr works like Append, but has no tlist */			Assert(plan->targetlist == NIL);			Assert(plan->qual == NIL);			foreach(l, ((BitmapOr *) plan)->bitmapplans)				adjust_plan_varnos((Plan *) lfirst(l), rtoffset);			break;		default:			elog(ERROR, "unrecognized node type: %d",				 (int) nodeTag(plan));			break;	}	/*	 * Now recurse into child plans.	 *	 * We don't need to (and in fact mustn't) recurse into subqueries, so no	 * need to examine initPlan list.	 */	adjust_plan_varnos(plan->lefttree, rtoffset);	adjust_plan_varnos(plan->righttree, rtoffset);}/* * adjust_expr_varnos *		Offset varnos of Vars in an expression by rtoffset. * * This is different from the rewriter's OffsetVarNodes in that it has to * work on an already-planned expression tree; in particular, we should not * disturb INNER and OUTER references.	On the other hand, we don't have to * recurse into subqueries nor deal with outer-level Vars, so it's pretty * simple. */static voidadjust_expr_varnos(Node *node, int rtoffset){	/* This tree walk requires no special setup, so away we go... */	adjust_expr_varnos_walker(node, &rtoffset);}static booladjust_expr_varnos_walker(Node *node, int *context){	if (node == NULL)		return false;	if (IsA(node, Var))	{		Var		   *var = (Var *) node;		Assert(var->varlevelsup == 0);		if (var->varno > 0 && var->varno != INNER && var->varno != OUTER)			var->varno += *context;		if (var->varnoold > 0)			var->varnoold += *context;		return false;	}	return expression_tree_walker(node, adjust_expr_varnos_walker,								  (void *) context);}/* * fix_expr_references *	  Do final cleanup on expressions (targetlists or quals). * * This consists of looking up operator opcode info for OpExpr nodes * and recursively performing set_plan_references on subplans. * * The Plan argument is currently unused, but might be needed again someday. */static voidfix_expr_references(Plan *plan, Node *node){	/* This tree walk requires no special setup, so away we go... */	fix_expr_references_walker(node, NULL);}static boolfix_expr_references_walker(Node *node, void *context){	if (node == NULL)		return false;	if (IsA(node, OpExpr))		set_opfuncid((OpExpr *) node);	else if (IsA(node, DistinctExpr))		set_opfuncid((OpExpr *) node);	/* rely on struct equivalence */	else if (IsA(node, ScalarArrayOpExpr))		set_sa_opfuncid((ScalarArrayOpExpr *) node);	else if (IsA(node, NullIfExpr))		set_opfuncid((OpExpr *) node);	/* rely on struct equivalence */	else if (IsA(node, SubPlan))	{		SubPlan    *sp = (SubPlan *) node;		sp->plan = set_plan_references(sp->plan, sp->rtable);	}	return expression_tree_walker(node, fix_expr_references_walker, context);}/* * set_join_references *	  Modifies the target list and quals of a join node to reference its *	  subplans, by setting the varnos to OUTER or INNER and setting attno *	  values to the result domain number of either the corresponding outer *	  or inner join tuple item. * * In the case of a nestloop with inner indexscan, we will also need to * apply the same transformation to any outer vars appearing in the * quals of the child indexscan.  set_inner_join_references does that. * *	'join' is a join plan node *	'rtable' is the associated range table */static voidset_join_references(Join *join, List *rtable){	Plan	   *outer_plan = join->plan.lefttree;	Plan	   *inner_plan = join->plan.righttree;	indexed_tlist *outer_itlist;	indexed_tlist *inner_itlist;	outer_itlist = build_tlist_index(outer_plan->targetlist);	inner_itlist = build_tlist_index(inner_plan->targetlist);	/* All join plans have tlist, qual, and joinqual */	join->plan.targetlist = join_references(join->plan.targetlist,											rtable,											outer_itlist,											inner_itlist,											(Index) 0);	join->plan.qual = join_references(join->plan.qual,									  rtable,									  outer_itlist,									  inner_itlist,									  (Index) 0);	join->joinqual = join_references(join->joinqual,									 rtable,									 outer_itlist,									 inner_itlist,									 (Index) 0);	/* Now do join-type-specific stuff */	if (IsA(join, NestLoop))	{		/* This processing is split out to handle possible recursion */		set_inner_join_references(inner_plan,								  rtable,								  outer_itlist);	}	else if (IsA(join, MergeJoin))	{		MergeJoin  *mj = (MergeJoin *) join;		mj->mergeclauses = join_references(mj->mergeclauses,										   rtable,										   outer_itlist,										   inner_itlist,										   (Index) 0);	}	else if (IsA(join, HashJoin))	{		HashJoin   *hj = (HashJoin *) join;		hj->hashclauses = join_references(hj->hashclauses,										  rtable,										  outer_itlist,										  inner_itlist,										  (Index) 0);	}	pfree(outer_itlist);	pfree(inner_itlist);}/* * set_inner_join_references *		Handle join references appearing in an inner indexscan's quals * * To handle bitmap-scan plan trees, we have to be able to recurse down * to the bottom BitmapIndexScan nodes, so this is split out as a separate * function. */static voidset_inner_join_references(Plan *inner_plan,						  List *rtable,						  indexed_tlist *outer_itlist){	if (IsA(inner_plan, IndexScan))	{		/*		 * An index is being used to reduce the number of tuples scanned in		 * the inner relation.	If there are join clauses being used with the		 * index, we must update their outer-rel var nodes to refer to the		 * outer side of the join.		 */		IndexScan  *innerscan = (IndexScan *) inner_plan;		List	   *indexqualorig = innerscan->indexqualorig;		/* No work needed if indexqual refers only to its own rel... */		if (NumRelids((Node *) indexqualorig) > 1)		{			Index		innerrel = innerscan->scan.scanrelid;			/* only refs to outer vars get changed in the inner qual */			innerscan->indexqualorig = join_references(indexqualorig,													   rtable,													   outer_itlist,													   NULL,													   innerrel);			innerscan->indexqual = join_references(innerscan->indexqual,												   rtable,												   outer_itlist,												   NULL,												   innerrel);			/*			 * We must fix the inner qpqual too, if it has join clauses (this			 * could happen if special operators are involved: some indexquals			 * may get rechecked as qpquals).			 */			if (NumRelids((Node *) inner_plan->qual) > 1)				inner_plan->qual = join_references(inner_plan->qual,												   rtable,												   outer_itlist,												   NULL,												   innerrel);		}	}	else if (IsA(inner_plan, BitmapIndexScan))	{		/*		 * Same, but index is being used within a bitmap plan.		 */		BitmapIndexScan *innerscan = (BitmapIndexScan *) inner_plan;		List	   *indexqualorig = innerscan->indexqualorig;		/* No work needed if indexqual refers only to its own rel... */		if (NumRelids((Node *) indexqualorig) > 1)		{			Index		innerrel = innerscan->scan.scanrelid;			/* only refs to outer vars get changed in the inner qual */			innerscan->indexqualorig = join_references(indexqualorig,													   rtable,													   outer_itlist,													   NULL,													   innerrel);			innerscan->indexqual = join_references(innerscan->indexqual,												   rtable,												   outer_itlist,												   NULL,												   innerrel);			/* no need to fix inner qpqual */			Assert(inner_plan->qual == NIL);		}	}	else if (IsA(inner_plan, BitmapHeapScan))	{		/*		 * The inner side is a bitmap scan plan.  Fix the top node, and		 * recurse to get the lower nodes.		 *		 * Note: create_bitmap_scan_plan removes clauses from bitmapqualorig		 * if they are duplicated in qpqual, so must test these independently.		 */		BitmapHeapScan *innerscan = (BitmapHeapScan *) inner_plan;		Index		innerrel = innerscan->scan.scanrelid;		List	   *bitmapqualorig = innerscan->bitmapqualorig;		/* only refs to outer vars get changed in the inner qual */		if (NumRelids((Node *) bitmapqualorig) > 1)			innerscan->bitmapqualorig = join_references(bitmapqualorig,														rtable,														outer_itlist,														NULL,														innerrel);		/*		 * We must fix the inner qpqual too, if it has join clauses (this		 * could happen if special operators are involved: some indexquals may		 * get rechecked as qpquals).		 */		if (NumRelids((Node *) inner_plan->qual) > 1)			inner_plan->qual = join_references(inner_plan->qual,											   rtable,											   outer_itlist,											   NULL,											   innerrel);		/* Now recurse */		set_inner_join_references(inner_plan->lefttree,

⌨️ 快捷键说明

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