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

📄 noderesult.c

📁 PostgreSQL7.4.6 for Linux
💻 C
字号:
/*------------------------------------------------------------------------- * * nodeResult.c *	  support for constant nodes needing special code. * * DESCRIPTION * *		Result nodes are used in queries where no relations are scanned. *		Examples of such queries are: * *				retrieve (x = 1) *		and *				append emp (name = "mike", salary = 15000) * *		Result nodes are also used to optimise queries with constant *		qualifications (ie, quals that do not depend on the scanned data), *		such as: * *				retrieve (emp.all) where 2 > 1 * *		In this case, the plan generated is * *						Result	(with 2 > 1 qual) *						/ *				   SeqScan (emp.all) * *		At runtime, the Result node evaluates the constant qual once. *		If it's false, we can return an empty result set without running *		the controlled plan at all.  If it's true, we run the controlled *		plan normally and pass back the results. * * * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION *	  $Header: /cvsroot/pgsql/src/backend/executor/nodeResult.c,v 1.26 2003/08/04 02:39:59 momjian Exp $ * *------------------------------------------------------------------------- */#include "postgres.h"#include "executor/executor.h"#include "executor/nodeResult.h"#include "utils/memutils.h"/* ---------------------------------------------------------------- *		ExecResult(node) * *		returns the tuples from the outer plan which satisfy the *		qualification clause.  Since result nodes with right *		subtrees are never planned, we ignore the right subtree *		entirely (for now).. -cim 10/7/89 * *		The qualification containing only constant clauses are *		checked first before any processing is done. It always returns *		'nil' if the constant qualification is not satisfied. * ---------------------------------------------------------------- */TupleTableSlot *ExecResult(ResultState *node){	TupleTableSlot *outerTupleSlot;	TupleTableSlot *resultSlot;	PlanState  *outerPlan;	ExprContext *econtext;	ExprDoneCond isDone;	econtext = node->ps.ps_ExprContext;	/*	 * check constant qualifications like (2 > 1), if not already done	 */	if (node->rs_checkqual)	{		bool		qualResult = ExecQual((List *) node->resconstantqual,										  econtext,										  false);		node->rs_checkqual = false;		if (!qualResult)		{			node->rs_done = true;			return NULL;		}	}	/*	 * Check to see if we're still projecting out tuples from a previous	 * scan tuple (because there is a function-returning-set in the	 * projection expressions).  If so, try to project another one.	 */	if (node->ps.ps_TupFromTlist)	{		resultSlot = ExecProject(node->ps.ps_ProjInfo, &isDone);		if (isDone == ExprMultipleResult)			return resultSlot;		/* Done with that source tuple... */		node->ps.ps_TupFromTlist = false;	}	/*	 * Reset per-tuple memory context to free any expression evaluation	 * storage allocated in the previous tuple cycle.  Note this can't	 * happen until we're done projecting out tuples from a scan tuple.	 */	ResetExprContext(econtext);	/*	 * if rs_done is true then it means that we were asked to return a	 * constant tuple and we already did the last time ExecResult() was	 * called, OR that we failed the constant qual check. Either way, now	 * we are through.	 */	while (!node->rs_done)	{		outerPlan = outerPlanState(node);		if (outerPlan != NULL)		{			/*			 * retrieve tuples from the outer plan until there are no			 * more.			 */			outerTupleSlot = ExecProcNode(outerPlan);			if (TupIsNull(outerTupleSlot))				return NULL;			node->ps.ps_OuterTupleSlot = outerTupleSlot;			/*			 * XXX gross hack. use outer tuple as scan tuple for			 * projection			 */			econtext->ecxt_outertuple = outerTupleSlot;			econtext->ecxt_scantuple = outerTupleSlot;		}		else		{			/*			 * if we don't have an outer plan, then we are just generating			 * the results from a constant target list.  Do it only once.			 */			node->rs_done = true;		}		/*		 * form the result tuple using ExecProject(), and return it ---		 * unless the projection produces an empty set, in which case we		 * must loop back to see if there are more outerPlan tuples.		 */		resultSlot = ExecProject(node->ps.ps_ProjInfo, &isDone);		if (isDone != ExprEndResult)		{			node->ps.ps_TupFromTlist = (isDone == ExprMultipleResult);			return resultSlot;		}	}	return NULL;}/* ---------------------------------------------------------------- *		ExecInitResult * *		Creates the run-time state information for the result node *		produced by the planner and initailizes outer relations *		(child nodes). * ---------------------------------------------------------------- */ResultState *ExecInitResult(Result *node, EState *estate){	ResultState *resstate;	/*	 * create state structure	 */	resstate = makeNode(ResultState);	resstate->ps.plan = (Plan *) node;	resstate->ps.state = estate;	resstate->rs_done = false;	resstate->rs_checkqual = (node->resconstantqual == NULL) ? false : true;	/*	 * Miscellaneous initialization	 *	 * create expression context for node	 */	ExecAssignExprContext(estate, &resstate->ps);#define RESULT_NSLOTS 1	/*	 * tuple table initialization	 */	ExecInitResultTupleSlot(estate, &resstate->ps);	/*	 * initialize child expressions	 */	resstate->ps.targetlist = (List *)		ExecInitExpr((Expr *) node->plan.targetlist,					 (PlanState *) resstate);	resstate->ps.qual = (List *)		ExecInitExpr((Expr *) node->plan.qual,					 (PlanState *) resstate);	resstate->resconstantqual = ExecInitExpr((Expr *) node->resconstantqual,											 (PlanState *) resstate);	/*	 * initialize child nodes	 */	outerPlanState(resstate) = ExecInitNode(outerPlan(node), estate);	/*	 * we don't use inner plan	 */	Assert(innerPlan(node) == NULL);	/*	 * initialize tuple type and projection info	 */	ExecAssignResultTypeFromTL(&resstate->ps);	ExecAssignProjectionInfo(&resstate->ps);	return resstate;}intExecCountSlotsResult(Result *node){	return ExecCountSlotsNode(outerPlan(node)) + RESULT_NSLOTS;}/* ---------------------------------------------------------------- *		ExecEndResult * *		frees up storage allocated through C routines * ---------------------------------------------------------------- */voidExecEndResult(ResultState *node){	/*	 * Free the exprcontext	 */	ExecFreeExprContext(&node->ps);	/*	 * clean out the tuple table	 */	ExecClearTuple(node->ps.ps_ResultTupleSlot);	/*	 * shut down subplans	 */	ExecEndNode(outerPlanState(node));}voidExecReScanResult(ResultState *node, ExprContext *exprCtxt){	node->rs_done = false;	node->ps.ps_TupFromTlist = false;	node->rs_checkqual = (node->resconstantqual == NULL) ? false : true;	/*	 * if chgParam of subnode is not null then plan will be re-scanned by	 * first ExecProcNode.	 */	if (((PlanState *) node)->lefttree &&		((PlanState *) node)->lefttree->chgParam == NULL)		ExecReScan(((PlanState *) node)->lefttree, exprCtxt);}

⌨️ 快捷键说明

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