postgresql/src/backend/executor/execAmi.c

284 lines
6.4 KiB
C
Raw Normal View History

/*-------------------------------------------------------------------------
*
* execAmi.c
* miscellaneous executor access method routines
*
2002-06-20 22:29:54 +02:00
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Header: /cvsroot/pgsql/src/backend/executor/execAmi.c,v 1.69 2003/02/09 00:30:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
1999-07-16 07:00:38 +02:00
#include "access/genam.h"
#include "access/heapam.h"
#include "catalog/heap.h"
#include "executor/execdebug.h"
#include "executor/instrument.h"
1999-07-16 07:00:38 +02:00
#include "executor/nodeAgg.h"
#include "executor/nodeAppend.h"
#include "executor/nodeFunctionscan.h"
1999-07-16 07:00:38 +02:00
#include "executor/nodeGroup.h"
#include "executor/nodeGroup.h"
#include "executor/nodeHash.h"
#include "executor/nodeHashjoin.h"
#include "executor/nodeIndexscan.h"
#include "executor/nodeLimit.h"
#include "executor/nodeMaterial.h"
1999-07-16 07:00:38 +02:00
#include "executor/nodeMergejoin.h"
#include "executor/nodeNestloop.h"
#include "executor/nodeResult.h"
1999-07-16 07:00:38 +02:00
#include "executor/nodeSeqscan.h"
#include "executor/nodeSetOp.h"
1999-07-16 07:00:38 +02:00
#include "executor/nodeSort.h"
#include "executor/nodeSubplan.h"
#include "executor/nodeSubqueryscan.h"
#include "executor/nodeTidscan.h"
1999-07-16 07:00:38 +02:00
#include "executor/nodeUnique.h"
/* ----------------------------------------------------------------
* ExecReScan
*
* 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(PlanState *node, ExprContext *exprCtxt)
{
/* If collecting timing stats, update them */
if (node->instrument)
InstrEndLoop(node->instrument);
/* If we have changed parameters, propagate that info */
if (node->chgParam != NULL)
{
List *lst;
foreach(lst, node->initPlan)
{
SubPlanState *sstate = (SubPlanState *) lfirst(lst);
PlanState *splan = sstate->planstate;
if (splan->plan->extParam != NULL) /* don't care about child
* local Params */
UpdateChangedParamSet(splan, node->chgParam);
if (splan->chgParam != NULL)
ExecReScanSetParamPlan(sstate, node);
}
foreach(lst, node->subPlan)
{
SubPlanState *sstate = (SubPlanState *) lfirst(lst);
PlanState *splan = sstate->planstate;
if (splan->plan->extParam != NULL)
UpdateChangedParamSet(splan, node->chgParam);
}
/* Well. Now set chgParam for left/right trees. */
if (node->lefttree != NULL)
UpdateChangedParamSet(node->lefttree, node->chgParam);
if (node->righttree != NULL)
UpdateChangedParamSet(node->righttree, node->chgParam);
}
switch (nodeTag(node))
{
case T_ResultState:
ExecReScanResult((ResultState *) node, exprCtxt);
break;
case T_AppendState:
ExecReScanAppend((AppendState *) node, exprCtxt);
break;
case T_SeqScanState:
ExecSeqReScan((SeqScanState *) node, exprCtxt);
break;
case T_IndexScanState:
ExecIndexReScan((IndexScanState *) node, exprCtxt);
break;
case T_TidScanState:
ExecTidReScan((TidScanState *) node, exprCtxt);
break;
case T_SubqueryScanState:
ExecSubqueryReScan((SubqueryScanState *) node, exprCtxt);
break;
case T_FunctionScanState:
ExecFunctionReScan((FunctionScanState *) node, exprCtxt);
break;
case T_NestLoopState:
ExecReScanNestLoop((NestLoopState *) node, exprCtxt);
break;
case T_MergeJoinState:
ExecReScanMergeJoin((MergeJoinState *) node, exprCtxt);
break;
case T_HashJoinState:
ExecReScanHashJoin((HashJoinState *) node, exprCtxt);
break;
case T_MaterialState:
ExecMaterialReScan((MaterialState *) node, exprCtxt);
1998-07-16 03:49:19 +02:00
break;
case T_SortState:
ExecReScanSort((SortState *) node, exprCtxt);
break;
case T_GroupState:
ExecReScanGroup((GroupState *) node, exprCtxt);
1998-02-23 07:28:16 +01:00
break;
case T_AggState:
ExecReScanAgg((AggState *) node, exprCtxt);
break;
case T_UniqueState:
ExecReScanUnique((UniqueState *) node, exprCtxt);
break;
case T_HashState:
ExecReScanHash((HashState *) node, exprCtxt);
1998-02-23 07:28:16 +01:00
break;
case T_SetOpState:
ExecReScanSetOp((SetOpState *) node, exprCtxt);
break;
case T_LimitState:
ExecReScanLimit((LimitState *) node, exprCtxt);
1998-07-16 00:16:21 +02:00
break;
default:
elog(ERROR, "ExecReScan: node type %d not supported",
nodeTag(node));
return;
}
if (node->chgParam != NULL)
{
bms_free(node->chgParam);
node->chgParam = NULL;
}
}
/*
* ExecMarkPos
*
* Marks the current scan position.
*/
void
ExecMarkPos(PlanState *node)
{
switch (nodeTag(node))
{
case T_SeqScanState:
ExecSeqMarkPos((SeqScanState *) node);
break;
case T_IndexScanState:
ExecIndexMarkPos((IndexScanState *) node);
break;
case T_TidScanState:
ExecTidMarkPos((TidScanState *) node);
break;
case T_FunctionScanState:
ExecFunctionMarkPos((FunctionScanState *) node);
break;
case T_MaterialState:
ExecMaterialMarkPos((MaterialState *) node);
break;
case T_SortState:
ExecSortMarkPos((SortState *) node);
break;
default:
/* don't make hard error unless caller asks to restore... */
elog(DEBUG1, "ExecMarkPos: node type %d not supported",
nodeTag(node));
break;
}
}
/*
* ExecRestrPos
*
* restores the scan position previously saved with ExecMarkPos()
*/
void
ExecRestrPos(PlanState *node)
{
switch (nodeTag(node))
{
case T_SeqScanState:
ExecSeqRestrPos((SeqScanState *) node);
break;
case T_IndexScanState:
ExecIndexRestrPos((IndexScanState *) node);
break;
case T_TidScanState:
ExecTidRestrPos((TidScanState *) node);
break;
case T_FunctionScanState:
ExecFunctionRestrPos((FunctionScanState *) node);
break;
case T_MaterialState:
ExecMaterialRestrPos((MaterialState *) node);
break;
case T_SortState:
ExecSortRestrPos((SortState *) node);
break;
default:
elog(ERROR, "ExecRestrPos: node type %d not supported",
nodeTag(node));
break;
}
}
/*
* ExecSupportsMarkRestore - does a plan type support mark/restore?
*
* XXX Ideally, all plan node types would support mark/restore, and this
* wouldn't be needed. For now, this had better match the routines above.
* But note the test is on Plan nodetype, not PlanState nodetype.
*/
bool
ExecSupportsMarkRestore(NodeTag plantype)
{
switch (plantype)
{
case T_SeqScan:
case T_IndexScan:
case T_TidScan:
case T_FunctionScan:
case T_Material:
case T_Sort:
return true;
default:
break;
}
return false;
}