postgres/src/backend/executor/execAmi.c
Tom Lane f9e4f611a1 First pass at set-returning-functions in FROM, by Joe Conway with
some kibitzing from Tom Lane.  Not everything works yet, and there's
no documentation or regression test, but let's commit this so Joe
doesn't need to cope with tracking changes in so many files ...
2002-05-12 20:10:05 +00:00

259 lines
6.0 KiB
C

/*-------------------------------------------------------------------------
*
* execAmi.c
* miscellaneous executor access method routines
*
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: execAmi.c,v 1.63 2002/05/12 20:10:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "access/genam.h"
#include "access/heapam.h"
#include "catalog/heap.h"
#include "executor/execdebug.h"
#include "executor/instrument.h"
#include "executor/nodeAgg.h"
#include "executor/nodeAppend.h"
#include "executor/nodeGroup.h"
#include "executor/nodeGroup.h"
#include "executor/nodeHash.h"
#include "executor/nodeHashjoin.h"
#include "executor/nodeIndexscan.h"
#include "executor/nodeTidscan.h"
#include "executor/nodeLimit.h"
#include "executor/nodeMaterial.h"
#include "executor/nodeMergejoin.h"
#include "executor/nodeNestloop.h"
#include "executor/nodeResult.h"
#include "executor/nodeSeqscan.h"
#include "executor/nodeSetOp.h"
#include "executor/nodeSort.h"
#include "executor/nodeSubplan.h"
#include "executor/nodeSubqueryscan.h"
#include "executor/nodeFunctionscan.h"
#include "executor/nodeUnique.h"
/* ----------------------------------------------------------------
* ExecReScan
*
* XXX this should be extended to cope with all the node types..
*
* takes the new expression context as an argument, so that
* index scans needn't have their scan keys updated separately
* - marcel 09/20/94
* ----------------------------------------------------------------
*/
void
ExecReScan(Plan *node, ExprContext *exprCtxt, Plan *parent)
{
if (node->instrument)
InstrEndLoop(node->instrument);
if (node->chgParam != NULL) /* Wow! */
{
List *lst;
foreach(lst, node->initPlan)
{
Plan *splan = ((SubPlan *) lfirst(lst))->plan;
if (splan->extParam != NULL) /* don't care about child
* locParam */
SetChangedParamList(splan, node->chgParam);
if (splan->chgParam != NULL)
ExecReScanSetParamPlan((SubPlan *) lfirst(lst), node);
}
foreach(lst, node->subPlan)
{
Plan *splan = ((SubPlan *) lfirst(lst))->plan;
if (splan->extParam != NULL)
SetChangedParamList(splan, node->chgParam);
}
/* Well. Now set chgParam for left/right trees. */
if (node->lefttree != NULL)
SetChangedParamList(node->lefttree, node->chgParam);
if (node->righttree != NULL)
SetChangedParamList(node->righttree, node->chgParam);
}
switch (nodeTag(node))
{
case T_SeqScan:
ExecSeqReScan((SeqScan *) node, exprCtxt, parent);
break;
case T_IndexScan:
ExecIndexReScan((IndexScan *) node, exprCtxt, parent);
break;
case T_TidScan:
ExecTidReScan((TidScan *) node, exprCtxt, parent);
break;
case T_SubqueryScan:
ExecSubqueryReScan((SubqueryScan *) node, exprCtxt, parent);
break;
case T_FunctionScan:
ExecFunctionReScan((FunctionScan *) node, exprCtxt, parent);
break;
case T_Material:
ExecMaterialReScan((Material *) node, exprCtxt, parent);
break;
case T_NestLoop:
ExecReScanNestLoop((NestLoop *) node, exprCtxt, parent);
break;
case T_HashJoin:
ExecReScanHashJoin((HashJoin *) node, exprCtxt, parent);
break;
case T_Hash:
ExecReScanHash((Hash *) node, exprCtxt, parent);
break;
case T_Agg:
ExecReScanAgg((Agg *) node, exprCtxt, parent);
break;
case T_Group:
ExecReScanGroup((Group *) node, exprCtxt, parent);
break;
case T_Result:
ExecReScanResult((Result *) node, exprCtxt, parent);
break;
case T_Unique:
ExecReScanUnique((Unique *) node, exprCtxt, parent);
break;
case T_SetOp:
ExecReScanSetOp((SetOp *) node, exprCtxt, parent);
break;
case T_Limit:
ExecReScanLimit((Limit *) node, exprCtxt, parent);
break;
case T_Sort:
ExecReScanSort((Sort *) node, exprCtxt, parent);
break;
case T_MergeJoin:
ExecReScanMergeJoin((MergeJoin *) node, exprCtxt, parent);
break;
case T_Append:
ExecReScanAppend((Append *) node, exprCtxt, parent);
break;
default:
elog(ERROR, "ExecReScan: node type %d not supported",
nodeTag(node));
return;
}
if (node->chgParam != NULL)
{
freeList(node->chgParam);
node->chgParam = NULL;
}
}
/* ----------------------------------------------------------------
* ExecMarkPos
*
* Marks the current scan position.
*
* XXX Needs to be extended to include all the node types,
* or at least all the ones that can be directly below a mergejoin.
* ----------------------------------------------------------------
*/
void
ExecMarkPos(Plan *node)
{
switch (nodeTag(node))
{
case T_SeqScan:
ExecSeqMarkPos((SeqScan *) node);
break;
case T_IndexScan:
ExecIndexMarkPos((IndexScan *) node);
break;
case T_FunctionScan:
ExecFunctionMarkPos((FunctionScan *) node);
break;
case T_Material:
ExecMaterialMarkPos((Material *) node);
break;
case T_Sort:
ExecSortMarkPos((Sort *) node);
break;
case T_TidScan:
ExecTidMarkPos((TidScan *) node);
break;
default:
/* don't make hard error unless caller asks to restore... */
elog(LOG, "ExecMarkPos: node type %d not supported",
nodeTag(node));
break;
}
}
/* ----------------------------------------------------------------
* ExecRestrPos
*
* restores the scan position previously saved with ExecMarkPos()
*
* XXX Needs to be extended to include all the node types,
* or at least all the ones that can be directly below a mergejoin.
* ----------------------------------------------------------------
*/
void
ExecRestrPos(Plan *node)
{
switch (nodeTag(node))
{
case T_SeqScan:
ExecSeqRestrPos((SeqScan *) node);
break;
case T_IndexScan:
ExecIndexRestrPos((IndexScan *) node);
break;
case T_FunctionScan:
ExecFunctionRestrPos((FunctionScan *) node);
break;
case T_Material:
ExecMaterialRestrPos((Material *) node);
break;
case T_Sort:
ExecSortRestrPos((Sort *) node);
break;
default:
elog(ERROR, "ExecRestrPos: node type %d not supported",
nodeTag(node));
break;
}
}