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

📄 subselect.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 3 页
字号:
		List	   *newargs = NIL;		ListCell   *l;		foreach(l, ((BoolExpr *) node)->args)		{			Node	   *newarg;			newarg = process_sublinks_mutator(lfirst(l),											  (void *) &locTopQual);			if (or_clause(newarg))				newargs = list_concat(newargs, ((BoolExpr *) newarg)->args);			else				newargs = lappend(newargs, newarg);		}		return (Node *) make_orclause(newargs);	}	return expression_tree_mutator(node,								   process_sublinks_mutator,								   (void *) &locTopQual);}/* * SS_finalize_plan - do final sublink processing for a completed Plan. * * This recursively computes the extParam and allParam sets for every Plan * node in the given plan tree.  It also attaches any generated InitPlans * to the top plan node. */voidSS_finalize_plan(Plan *plan, List *rtable){	Bitmapset  *outer_params,			   *valid_params,			   *initExtParam,			   *initSetParam;	Cost		initplan_cost;	int			paramid;	ListCell   *l;	/*	 * First, scan the param list to discover the sets of params that are	 * available from outer query levels and my own query level. We do this	 * once to save time in the per-plan recursion steps.	 */	outer_params = valid_params = NULL;	paramid = 0;	foreach(l, PlannerParamList)	{		PlannerParamItem *pitem = (PlannerParamItem *) lfirst(l);		if (pitem->abslevel < PlannerQueryLevel)		{			/* valid outer-level parameter */			outer_params = bms_add_member(outer_params, paramid);			valid_params = bms_add_member(valid_params, paramid);		}		else if (pitem->abslevel == PlannerQueryLevel &&				 IsA(pitem->item, Param))		{			/* valid local parameter (i.e., a setParam of my child) */			valid_params = bms_add_member(valid_params, paramid);		}		paramid++;	}	/*	 * Now recurse through plan tree.	 */	(void) finalize_plan(plan, rtable, outer_params, valid_params);	bms_free(outer_params);	bms_free(valid_params);	/*	 * Finally, attach any initPlans to the topmost plan node, and add their	 * extParams to the topmost node's, too.  However, any setParams of the	 * initPlans should not be present in the topmost node's extParams, only	 * in its allParams.  (As of PG 8.1, it's possible that some initPlans	 * have extParams that are setParams of other initPlans, so we have to	 * take care of this situation explicitly.)	 *	 * We also add the total_cost of each initPlan to the startup cost of the	 * top node.  This is a conservative overestimate, since in fact each	 * initPlan might be executed later than plan startup, or even not at all.	 */	plan->initPlan = PlannerInitPlan;	PlannerInitPlan = NIL;		/* make sure they're not attached twice */	initExtParam = initSetParam = NULL;	initplan_cost = 0;	foreach(l, plan->initPlan)	{		SubPlan    *initplan = (SubPlan *) lfirst(l);		ListCell   *l2;		initExtParam = bms_add_members(initExtParam,									   initplan->plan->extParam);		foreach(l2, initplan->setParam)		{			initSetParam = bms_add_member(initSetParam, lfirst_int(l2));		}		initplan_cost += initplan->plan->total_cost;	}	/* allParam must include all these params */	plan->allParam = bms_add_members(plan->allParam, initExtParam);	plan->allParam = bms_add_members(plan->allParam, initSetParam);	/* but extParam shouldn't include any setParams */	initExtParam = bms_del_members(initExtParam, initSetParam);	/* empty test ensures extParam is exactly NULL if it's empty */	if (!bms_is_empty(initExtParam))		plan->extParam = bms_join(plan->extParam, initExtParam);	plan->startup_cost += initplan_cost;	plan->total_cost += initplan_cost;}/* * Recursive processing of all nodes in the plan tree * * The return value is the computed allParam set for the given Plan node. * This is just an internal notational convenience. */static Bitmapset *finalize_plan(Plan *plan, List *rtable,			  Bitmapset *outer_params, Bitmapset *valid_params){	finalize_primnode_context context;	if (plan == NULL)		return NULL;	context.paramids = NULL;	/* initialize set to empty */	context.outer_params = outer_params;	/*	 * When we call finalize_primnode, context.paramids sets are automatically	 * merged together.  But when recursing to self, we have to do it the hard	 * way.  We want the paramids set to include params in subplans as well as	 * at this level.	 */	/* Find params in targetlist and qual */	finalize_primnode((Node *) plan->targetlist, &context);	finalize_primnode((Node *) plan->qual, &context);	/* Check additional node-type-specific fields */	switch (nodeTag(plan))	{		case T_Result:			finalize_primnode(((Result *) plan)->resconstantqual,							  &context);			break;		case T_IndexScan:			finalize_primnode((Node *) ((IndexScan *) plan)->indexqual,							  &context);			/*			 * we need not look at indexqualorig, since it will have the same			 * param references as indexqual.			 */			break;		case T_BitmapIndexScan:			finalize_primnode((Node *) ((BitmapIndexScan *) plan)->indexqual,							  &context);			/*			 * we need not look at indexqualorig, since it will have the same			 * param references as indexqual.			 */			break;		case T_BitmapHeapScan:			finalize_primnode((Node *) ((BitmapHeapScan *) plan)->bitmapqualorig,							  &context);			break;		case T_TidScan:			finalize_primnode((Node *) ((TidScan *) plan)->tideval,							  &context);			break;		case T_SubqueryScan:			/*			 * In a SubqueryScan, SS_finalize_plan has already been run on the			 * subplan by the inner invocation of subquery_planner, so there's			 * no need to do it again.	Instead, just pull out the subplan's			 * extParams list, which represents the params it needs from my			 * level and higher levels.			 */			context.paramids = bms_add_members(context.paramids,								 ((SubqueryScan *) plan)->subplan->extParam);			break;		case T_FunctionScan:			{				RangeTblEntry *rte;				rte = rt_fetch(((FunctionScan *) plan)->scan.scanrelid,							   rtable);				Assert(rte->rtekind == RTE_FUNCTION);				finalize_primnode(rte->funcexpr, &context);			}			break;		case T_Append:			{				ListCell   *l;				foreach(l, ((Append *) plan)->appendplans)				{					context.paramids =						bms_add_members(context.paramids,										finalize_plan((Plan *) lfirst(l),													  rtable,													  outer_params,													  valid_params));				}			}			break;		case T_BitmapAnd:			{				ListCell   *l;				foreach(l, ((BitmapAnd *) plan)->bitmapplans)				{					context.paramids =						bms_add_members(context.paramids,										finalize_plan((Plan *) lfirst(l),													  rtable,													  outer_params,													  valid_params));				}			}			break;		case T_BitmapOr:			{				ListCell   *l;				foreach(l, ((BitmapOr *) plan)->bitmapplans)				{					context.paramids =						bms_add_members(context.paramids,										finalize_plan((Plan *) lfirst(l),													  rtable,													  outer_params,													  valid_params));				}			}			break;		case T_NestLoop:			finalize_primnode((Node *) ((Join *) plan)->joinqual,							  &context);			break;		case T_MergeJoin:			finalize_primnode((Node *) ((Join *) plan)->joinqual,							  &context);			finalize_primnode((Node *) ((MergeJoin *) plan)->mergeclauses,							  &context);			break;		case T_HashJoin:			finalize_primnode((Node *) ((Join *) plan)->joinqual,							  &context);			finalize_primnode((Node *) ((HashJoin *) plan)->hashclauses,							  &context);			break;		case T_Limit:			finalize_primnode(((Limit *) plan)->limitOffset,							  &context);			finalize_primnode(((Limit *) plan)->limitCount,							  &context);			break;		case T_Hash:		case T_Agg:		case T_SeqScan:		case T_Material:		case T_Sort:		case T_Unique:		case T_SetOp:		case T_Group:			break;		default:			elog(ERROR, "unrecognized node type: %d",				 (int) nodeTag(plan));	}	/* Process left and right child plans, if any */	context.paramids = bms_add_members(context.paramids,									   finalize_plan(plan->lefttree,													 rtable,													 outer_params,													 valid_params));	context.paramids = bms_add_members(context.paramids,									   finalize_plan(plan->righttree,													 rtable,													 outer_params,													 valid_params));	/* Now we have all the paramids */	if (!bms_is_subset(context.paramids, valid_params))		elog(ERROR, "plan should not reference subplan's variable");	plan->extParam = bms_intersect(context.paramids, outer_params);	plan->allParam = context.paramids;	/*	 * For speed at execution time, make sure extParam/allParam are actually	 * NULL if they are empty sets.	 */	if (bms_is_empty(plan->extParam))	{		bms_free(plan->extParam);		plan->extParam = NULL;	}	if (bms_is_empty(plan->allParam))	{		bms_free(plan->allParam);		plan->allParam = NULL;	}	return plan->allParam;}/* * finalize_primnode: add IDs of all PARAM_EXEC params appearing in the given * expression tree to the result set. */static boolfinalize_primnode(Node *node, finalize_primnode_context *context){	if (node == NULL)		return false;	if (IsA(node, Param))	{		if (((Param *) node)->paramkind == PARAM_EXEC)		{			int			paramid = (int) ((Param *) node)->paramid;			context->paramids = bms_add_member(context->paramids, paramid);		}		return false;			/* no more to do here */	}	if (is_subplan(node))	{		SubPlan    *subplan = (SubPlan *) node;		/* Add outer-level params needed by the subplan to paramids */		context->paramids = bms_join(context->paramids,									 bms_intersect(subplan->plan->extParam,												   context->outer_params));		/* fall through to recurse into subplan args */	}	return expression_tree_walker(node, finalize_primnode,								  (void *) context);}/* * SS_make_initplan_from_plan - given a plan tree, make it an InitPlan * * The plan is expected to return a scalar value of the indicated type. * We build an EXPR_SUBLINK SubPlan node and put it into the initplan * list for the current query level.  A Param that represents the initplan's * output is returned. * * We assume the plan hasn't been put through SS_finalize_plan. */Param *SS_make_initplan_from_plan(PlannerInfo *root, Plan *plan,						   Oid resulttype, int32 resulttypmod){	List	   *saved_initplan = PlannerInitPlan;	SubPlan    *node;	Param	   *prm;	/*	 * Set up for a new level of subquery.	This is just to keep	 * SS_finalize_plan from becoming confused.	 */	PlannerQueryLevel++;	PlannerInitPlan = NIL;	/*	 * Build extParam/allParam sets for plan nodes.	 */	SS_finalize_plan(plan, root->parse->rtable);	/* Return to outer subquery context */	PlannerQueryLevel--;	PlannerInitPlan = saved_initplan;	/*	 * Create a SubPlan node and add it to the outer list of InitPlans.	 */	node = makeNode(SubPlan);	node->subLinkType = EXPR_SUBLINK;	node->plan = plan;	node->plan_id = PlannerPlanId++;	/* Assign unique ID to this SubPlan */	node->rtable = root->parse->rtable;	PlannerInitPlan = lappend(PlannerInitPlan, node);	/*	 * The node can't have any inputs (since it's an initplan), so the	 * parParam and args lists remain empty.	 */	/*	 * Make a Param that will be the subplan's output.	 */	prm = generate_new_param(resulttype, resulttypmod);	node->setParam = list_make1_int(prm->paramid);	return prm;}

⌨️ 快捷键说明

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