mirror of
https://github.com/zebrajr/postgres.git
synced 2025-12-06 12:20:15 +01:00
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 ...
259 lines
6.0 KiB
C
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;
|
|
}
|
|
}
|