mirror of
https://github.com/postgres/postgres.git
synced 2025-07-02 09:02:37 +03:00
Massive commit to run PGINDENT on all *.c and *.h files.
This commit is contained in:
@ -1,33 +1,33 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* nodeResult.c--
|
||||
* support for constant nodes needing special code.
|
||||
* support for constant nodes needing special code.
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
*
|
||||
* DESCRIPTION
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Example: in constant queries where no relations are scanned,
|
||||
* the planner generates result nodes. Examples of such queries are:
|
||||
* Example: in constant queries where no relations are scanned,
|
||||
* the planner generates result nodes. Examples of such queries are:
|
||||
*
|
||||
* retrieve (x = 1)
|
||||
* and
|
||||
* append emp (name = "mike", salary = 15000)
|
||||
* retrieve (x = 1)
|
||||
* and
|
||||
* append emp (name = "mike", salary = 15000)
|
||||
*
|
||||
* Result nodes are also used to optimise queries
|
||||
* with tautological qualifications like:
|
||||
* Result nodes are also used to optimise queries
|
||||
* with tautological qualifications like:
|
||||
*
|
||||
* retrieve (emp.all) where 2 > 1
|
||||
* retrieve (emp.all) where 2 > 1
|
||||
*
|
||||
* In this case, the plan generated is
|
||||
* In this case, the plan generated is
|
||||
*
|
||||
* Result (with 2 > 1 qual)
|
||||
* /
|
||||
* SeqScan (emp.all)
|
||||
* Result (with 2 > 1 qual)
|
||||
* /
|
||||
* SeqScan (emp.all)
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeResult.c,v 1.2 1996/10/31 10:12:18 scrappy Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeResult.c,v 1.3 1997/09/07 04:41:42 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -38,253 +38,259 @@
|
||||
#include "executor/nodeResult.h"
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* ExecResult(node)
|
||||
* ExecResult(node)
|
||||
*
|
||||
* returns the tuples from the outer plan which satisify the
|
||||
* qualification clause. Since result nodes with right
|
||||
* subtrees are never planned, we ignore the right subtree
|
||||
* entirely (for now).. -cim 10/7/89
|
||||
* returns the tuples from the outer plan which satisify 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.
|
||||
* 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(Result *node)
|
||||
ExecResult(Result * node)
|
||||
{
|
||||
ResultState *resstate;
|
||||
TupleTableSlot *outerTupleSlot;
|
||||
TupleTableSlot *resultSlot;
|
||||
Plan *outerPlan;
|
||||
ExprContext *econtext;
|
||||
Node *qual;
|
||||
bool qualResult;
|
||||
bool isDone;
|
||||
ProjectionInfo *projInfo;
|
||||
|
||||
/* ----------------
|
||||
* initialize the result node's state
|
||||
* ----------------
|
||||
*/
|
||||
resstate = node->resstate;
|
||||
|
||||
/* ----------------
|
||||
* get the expression context
|
||||
* ----------------
|
||||
*/
|
||||
econtext = resstate->cstate.cs_ExprContext;
|
||||
|
||||
/* ----------------
|
||||
* check tautological qualifications like (2 > 1)
|
||||
* ----------------
|
||||
*/
|
||||
qual = node->resconstantqual;
|
||||
if (qual != NULL) {
|
||||
qualResult = ExecQual((List*)qual, econtext);
|
||||
/* ----------------
|
||||
* if we failed the constant qual, then there
|
||||
* is no need to continue processing because regardless of
|
||||
* what happens, the constant qual will be false..
|
||||
* ----------------
|
||||
*/
|
||||
if (qualResult == false)
|
||||
return NULL;
|
||||
|
||||
/* ----------------
|
||||
* our constant qualification succeeded so now we
|
||||
* throw away the qual because we know it will always
|
||||
* succeed.
|
||||
* ----------------
|
||||
*/
|
||||
node->resconstantqual = NULL;
|
||||
}
|
||||
|
||||
if (resstate->cstate.cs_TupFromTlist) {
|
||||
ResultState *resstate;
|
||||
TupleTableSlot *outerTupleSlot;
|
||||
TupleTableSlot *resultSlot;
|
||||
Plan *outerPlan;
|
||||
ExprContext *econtext;
|
||||
Node *qual;
|
||||
bool qualResult;
|
||||
bool isDone;
|
||||
ProjectionInfo *projInfo;
|
||||
|
||||
projInfo = resstate->cstate.cs_ProjInfo;
|
||||
resultSlot = ExecProject(projInfo, &isDone);
|
||||
if (!isDone)
|
||||
return resultSlot;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* retrieve a tuple that satisfy the qual from the outer plan until
|
||||
* there are no more.
|
||||
*
|
||||
* if rs_done is 1 then it means that we were asked to return
|
||||
* a constant tuple and we alread did the last time ExecResult()
|
||||
* was called, so now we are through.
|
||||
* ----------------
|
||||
*/
|
||||
outerPlan = outerPlan(node);
|
||||
|
||||
while (!resstate->rs_done) {
|
||||
|
||||
/* ----------------
|
||||
* get next outer tuple if necessary.
|
||||
* initialize the result node's state
|
||||
* ----------------
|
||||
*/
|
||||
if (outerPlan != NULL) {
|
||||
outerTupleSlot = ExecProcNode(outerPlan, (Plan*)node);
|
||||
|
||||
if (TupIsNull(outerTupleSlot))
|
||||
return NULL;
|
||||
|
||||
resstate->cstate.cs_OuterTupleSlot = outerTupleSlot;
|
||||
} else {
|
||||
resstate = node->resstate;
|
||||
|
||||
/* ----------------
|
||||
* if we don't have an outer plan, then it's probably
|
||||
* the case that we are doing a retrieve or an append
|
||||
* with a constant target list, so we should only return
|
||||
* the constant tuple once or never if we fail the qual.
|
||||
* ----------------
|
||||
*/
|
||||
resstate->rs_done = 1;
|
||||
/* ----------------
|
||||
* get the expression context
|
||||
* ----------------
|
||||
*/
|
||||
econtext = resstate->cstate.cs_ExprContext;
|
||||
|
||||
/* ----------------
|
||||
* check tautological qualifications like (2 > 1)
|
||||
* ----------------
|
||||
*/
|
||||
qual = node->resconstantqual;
|
||||
if (qual != NULL)
|
||||
{
|
||||
qualResult = ExecQual((List *) qual, econtext);
|
||||
/* ----------------
|
||||
* if we failed the constant qual, then there
|
||||
* is no need to continue processing because regardless of
|
||||
* what happens, the constant qual will be false..
|
||||
* ----------------
|
||||
*/
|
||||
if (qualResult == false)
|
||||
return NULL;
|
||||
|
||||
/* ----------------
|
||||
* our constant qualification succeeded so now we
|
||||
* throw away the qual because we know it will always
|
||||
* succeed.
|
||||
* ----------------
|
||||
*/
|
||||
node->resconstantqual = NULL;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* get the information to place into the expr context
|
||||
* ----------------
|
||||
*/
|
||||
resstate = node->resstate;
|
||||
|
||||
outerTupleSlot = resstate->cstate.cs_OuterTupleSlot;
|
||||
|
||||
/* ----------------
|
||||
* fill in the information in the expression context
|
||||
* XXX gross hack. use outer tuple as scan tuple
|
||||
* ----------------
|
||||
*/
|
||||
econtext->ecxt_outertuple = outerTupleSlot;
|
||||
econtext->ecxt_scantuple = outerTupleSlot;
|
||||
|
||||
/* ----------------
|
||||
* form the result tuple and pass it back using ExecProject()
|
||||
* ----------------
|
||||
*/
|
||||
projInfo = resstate->cstate.cs_ProjInfo;
|
||||
resultSlot = ExecProject(projInfo, &isDone);
|
||||
resstate->cstate.cs_TupFromTlist = !isDone;
|
||||
return resultSlot;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
if (resstate->cstate.cs_TupFromTlist)
|
||||
{
|
||||
ProjectionInfo *projInfo;
|
||||
|
||||
projInfo = resstate->cstate.cs_ProjInfo;
|
||||
resultSlot = ExecProject(projInfo, &isDone);
|
||||
if (!isDone)
|
||||
return resultSlot;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* retrieve a tuple that satisfy the qual from the outer plan until
|
||||
* there are no more.
|
||||
*
|
||||
* if rs_done is 1 then it means that we were asked to return
|
||||
* a constant tuple and we alread did the last time ExecResult()
|
||||
* was called, so now we are through.
|
||||
* ----------------
|
||||
*/
|
||||
outerPlan = outerPlan(node);
|
||||
|
||||
while (!resstate->rs_done)
|
||||
{
|
||||
|
||||
/* ----------------
|
||||
* get next outer tuple if necessary.
|
||||
* ----------------
|
||||
*/
|
||||
if (outerPlan != NULL)
|
||||
{
|
||||
outerTupleSlot = ExecProcNode(outerPlan, (Plan *) node);
|
||||
|
||||
if (TupIsNull(outerTupleSlot))
|
||||
return NULL;
|
||||
|
||||
resstate->cstate.cs_OuterTupleSlot = outerTupleSlot;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* ----------------
|
||||
* if we don't have an outer plan, then it's probably
|
||||
* the case that we are doing a retrieve or an append
|
||||
* with a constant target list, so we should only return
|
||||
* the constant tuple once or never if we fail the qual.
|
||||
* ----------------
|
||||
*/
|
||||
resstate->rs_done = 1;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* get the information to place into the expr context
|
||||
* ----------------
|
||||
*/
|
||||
resstate = node->resstate;
|
||||
|
||||
outerTupleSlot = resstate->cstate.cs_OuterTupleSlot;
|
||||
|
||||
/* ----------------
|
||||
* fill in the information in the expression context
|
||||
* XXX gross hack. use outer tuple as scan tuple
|
||||
* ----------------
|
||||
*/
|
||||
econtext->ecxt_outertuple = outerTupleSlot;
|
||||
econtext->ecxt_scantuple = outerTupleSlot;
|
||||
|
||||
/* ----------------
|
||||
* form the result tuple and pass it back using ExecProject()
|
||||
* ----------------
|
||||
*/
|
||||
projInfo = resstate->cstate.cs_ProjInfo;
|
||||
resultSlot = ExecProject(projInfo, &isDone);
|
||||
resstate->cstate.cs_TupFromTlist = !isDone;
|
||||
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).
|
||||
* ExecInitResult
|
||||
*
|
||||
* Creates the run-time state information for the result node
|
||||
* produced by the planner and initailizes outer relations
|
||||
* (child nodes).
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
bool
|
||||
ExecInitResult(Result *node, EState *estate, Plan *parent)
|
||||
ExecInitResult(Result * node, EState * estate, Plan * parent)
|
||||
{
|
||||
ResultState *resstate;
|
||||
|
||||
/* ----------------
|
||||
* assign execution state to node
|
||||
* ----------------
|
||||
*/
|
||||
node->plan.state = estate;
|
||||
|
||||
/* ----------------
|
||||
* create new ResultState for node
|
||||
* ----------------
|
||||
*/
|
||||
resstate = makeNode(ResultState);
|
||||
resstate->rs_done = 0;
|
||||
node->resstate = resstate;
|
||||
|
||||
/* ----------------
|
||||
* Miscellanious initialization
|
||||
*
|
||||
* + assign node's base_id
|
||||
* + assign debugging hooks and
|
||||
* + create expression context for node
|
||||
* ----------------
|
||||
*/
|
||||
ExecAssignNodeBaseInfo(estate, &resstate->cstate, parent);
|
||||
ExecAssignExprContext(estate, &resstate->cstate);
|
||||
|
||||
#define RESULT_NSLOTS 1
|
||||
/* ----------------
|
||||
* tuple table initialization
|
||||
* ----------------
|
||||
*/
|
||||
ExecInitResultTupleSlot(estate, &resstate->cstate);
|
||||
|
||||
/* ----------------
|
||||
* then initialize children
|
||||
* ----------------
|
||||
*/
|
||||
ExecInitNode(outerPlan(node), estate, (Plan*)node);
|
||||
ResultState *resstate;
|
||||
|
||||
/*
|
||||
* we don't use inner plan
|
||||
*/
|
||||
Assert(innerPlan(node)==NULL);
|
||||
|
||||
/* ----------------
|
||||
* initialize tuple type and projection info
|
||||
* ----------------
|
||||
*/
|
||||
ExecAssignResultTypeFromTL((Plan*)node, &resstate->cstate);
|
||||
ExecAssignProjectionInfo((Plan*)node, &resstate->cstate);
|
||||
|
||||
/* ----------------
|
||||
* set "are we done yet" to false
|
||||
* ----------------
|
||||
*/
|
||||
resstate->rs_done = 0;
|
||||
|
||||
return TRUE;
|
||||
/* ----------------
|
||||
* assign execution state to node
|
||||
* ----------------
|
||||
*/
|
||||
node->plan.state = estate;
|
||||
|
||||
/* ----------------
|
||||
* create new ResultState for node
|
||||
* ----------------
|
||||
*/
|
||||
resstate = makeNode(ResultState);
|
||||
resstate->rs_done = 0;
|
||||
node->resstate = resstate;
|
||||
|
||||
/* ----------------
|
||||
* Miscellanious initialization
|
||||
*
|
||||
* + assign node's base_id
|
||||
* + assign debugging hooks and
|
||||
* + create expression context for node
|
||||
* ----------------
|
||||
*/
|
||||
ExecAssignNodeBaseInfo(estate, &resstate->cstate, parent);
|
||||
ExecAssignExprContext(estate, &resstate->cstate);
|
||||
|
||||
#define RESULT_NSLOTS 1
|
||||
/* ----------------
|
||||
* tuple table initialization
|
||||
* ----------------
|
||||
*/
|
||||
ExecInitResultTupleSlot(estate, &resstate->cstate);
|
||||
|
||||
/* ----------------
|
||||
* then initialize children
|
||||
* ----------------
|
||||
*/
|
||||
ExecInitNode(outerPlan(node), estate, (Plan *) node);
|
||||
|
||||
/*
|
||||
* we don't use inner plan
|
||||
*/
|
||||
Assert(innerPlan(node) == NULL);
|
||||
|
||||
/* ----------------
|
||||
* initialize tuple type and projection info
|
||||
* ----------------
|
||||
*/
|
||||
ExecAssignResultTypeFromTL((Plan *) node, &resstate->cstate);
|
||||
ExecAssignProjectionInfo((Plan *) node, &resstate->cstate);
|
||||
|
||||
/* ----------------
|
||||
* set "are we done yet" to false
|
||||
* ----------------
|
||||
*/
|
||||
resstate->rs_done = 0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
ExecCountSlotsResult(Result *node)
|
||||
ExecCountSlotsResult(Result * node)
|
||||
{
|
||||
return ExecCountSlotsNode(outerPlan(node)) + RESULT_NSLOTS;
|
||||
return ExecCountSlotsNode(outerPlan(node)) + RESULT_NSLOTS;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* ExecEndResult
|
||||
*
|
||||
* fees up storage allocated through C routines
|
||||
* ExecEndResult
|
||||
*
|
||||
* fees up storage allocated through C routines
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
ExecEndResult(Result *node)
|
||||
ExecEndResult(Result * node)
|
||||
{
|
||||
ResultState *resstate;
|
||||
|
||||
resstate = node->resstate;
|
||||
|
||||
/* ----------------
|
||||
* Free the projection info
|
||||
*
|
||||
* Note: we don't ExecFreeResultType(resstate)
|
||||
* because the rule manager depends on the tupType
|
||||
* returned by ExecMain(). So for now, this
|
||||
* is freed at end-transaction time. -cim 6/2/91
|
||||
* ----------------
|
||||
*/
|
||||
ExecFreeProjectionInfo(&resstate->cstate);
|
||||
|
||||
/* ----------------
|
||||
* shut down subplans
|
||||
* ----------------
|
||||
*/
|
||||
ExecEndNode(outerPlan(node), (Plan*)node);
|
||||
ResultState *resstate;
|
||||
|
||||
/* ----------------
|
||||
* clean out the tuple table
|
||||
* ----------------
|
||||
*/
|
||||
ExecClearTuple(resstate->cstate.cs_ResultTupleSlot);
|
||||
resstate = node->resstate;
|
||||
|
||||
/* ----------------
|
||||
* Free the projection info
|
||||
*
|
||||
* Note: we don't ExecFreeResultType(resstate)
|
||||
* because the rule manager depends on the tupType
|
||||
* returned by ExecMain(). So for now, this
|
||||
* is freed at end-transaction time. -cim 6/2/91
|
||||
* ----------------
|
||||
*/
|
||||
ExecFreeProjectionInfo(&resstate->cstate);
|
||||
|
||||
/* ----------------
|
||||
* shut down subplans
|
||||
* ----------------
|
||||
*/
|
||||
ExecEndNode(outerPlan(node), (Plan *) node);
|
||||
|
||||
/* ----------------
|
||||
* clean out the tuple table
|
||||
* ----------------
|
||||
*/
|
||||
ExecClearTuple(resstate->cstate.cs_ResultTupleSlot);
|
||||
}
|
||||
|
Reference in New Issue
Block a user