1996-07-09 08:22:35 +02:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
1999-02-14 00:22:53 +01:00
|
|
|
* execAmi.c
|
1999-09-18 21:08:25 +02:00
|
|
|
* miscellaneous executor access method routines
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
2002-06-20 22:29:54 +02:00
|
|
|
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
2000-01-26 06:58:53 +01:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
2002-12-14 01:17:59 +01:00
|
|
|
* $Header: /cvsroot/pgsql/src/backend/executor/execAmi.c,v 1.68 2002/12/14 00:17:50 tgl Exp $
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
1996-10-31 11:12:26 +01:00
|
|
|
#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"
|
2001-09-18 03:59:07 +02:00
|
|
|
#include "executor/instrument.h"
|
1999-07-16 07:00:38 +02:00
|
|
|
#include "executor/nodeAgg.h"
|
|
|
|
#include "executor/nodeAppend.h"
|
2002-12-05 16:50:39 +01:00
|
|
|
#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"
|
1996-07-09 08:22:35 +02:00
|
|
|
#include "executor/nodeIndexscan.h"
|
2000-10-26 23:38:24 +02:00
|
|
|
#include "executor/nodeLimit.h"
|
1998-02-13 04:26:53 +01:00
|
|
|
#include "executor/nodeMaterial.h"
|
1999-07-16 07:00:38 +02:00
|
|
|
#include "executor/nodeMergejoin.h"
|
1998-02-13 04:26:53 +01:00
|
|
|
#include "executor/nodeNestloop.h"
|
|
|
|
#include "executor/nodeResult.h"
|
1999-07-16 07:00:38 +02:00
|
|
|
#include "executor/nodeSeqscan.h"
|
2000-10-05 21:11:39 +02:00
|
|
|
#include "executor/nodeSetOp.h"
|
1999-07-16 07:00:38 +02:00
|
|
|
#include "executor/nodeSort.h"
|
1998-02-13 04:26:53 +01:00
|
|
|
#include "executor/nodeSubplan.h"
|
2000-09-29 20:21:41 +02:00
|
|
|
#include "executor/nodeSubqueryscan.h"
|
2002-12-05 16:50:39 +01:00
|
|
|
#include "executor/nodeTidscan.h"
|
1999-07-16 07:00:38 +02:00
|
|
|
#include "executor/nodeUnique.h"
|
1996-07-09 08:22:35 +02:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
/* ----------------------------------------------------------------
|
1997-09-07 07:04:48 +02:00
|
|
|
* ExecReScan
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
1997-09-07 07:04:48 +02:00
|
|
|
* takes the new expression context as an argument, so that
|
|
|
|
* index scans needn't have their scan keys updated separately
|
|
|
|
* - marcel 09/20/94
|
1996-07-09 08:22:35 +02:00
|
|
|
* ----------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
void
|
2002-12-05 16:50:39 +01:00
|
|
|
ExecReScan(PlanState *node, ExprContext *exprCtxt)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
2002-12-05 16:50:39 +01:00
|
|
|
/* If collecting timing stats, update them */
|
2001-09-18 03:59:07 +02:00
|
|
|
if (node->instrument)
|
|
|
|
InstrEndLoop(node->instrument);
|
1998-02-13 04:26:53 +01:00
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
/* If we have changed parameters, propagate that info */
|
|
|
|
if (node->chgParam != NIL)
|
1998-02-13 04:26:53 +01:00
|
|
|
{
|
1998-02-26 05:46:47 +01:00
|
|
|
List *lst;
|
|
|
|
|
|
|
|
foreach(lst, node->initPlan)
|
1998-02-13 04:26:53 +01:00
|
|
|
{
|
2002-12-14 01:17:59 +01:00
|
|
|
SubPlanState *sstate = (SubPlanState *) lfirst(lst);
|
2002-12-13 20:46:01 +01:00
|
|
|
PlanState *splan = sstate->planstate;
|
1998-02-26 05:46:47 +01:00
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
if (splan->plan->extParam != NIL) /* don't care about child
|
1998-02-26 05:46:47 +01:00
|
|
|
* locParam */
|
|
|
|
SetChangedParamList(splan, node->chgParam);
|
2002-12-05 16:50:39 +01:00
|
|
|
if (splan->chgParam != NIL)
|
2002-12-13 20:46:01 +01:00
|
|
|
ExecReScanSetParamPlan(sstate, node);
|
1998-02-13 04:26:53 +01:00
|
|
|
}
|
1998-02-26 05:46:47 +01:00
|
|
|
foreach(lst, node->subPlan)
|
1998-02-13 04:26:53 +01:00
|
|
|
{
|
2002-12-14 01:17:59 +01:00
|
|
|
SubPlanState *sstate = (SubPlanState *) lfirst(lst);
|
2002-12-13 20:46:01 +01:00
|
|
|
PlanState *splan = sstate->planstate;
|
1998-02-26 05:46:47 +01:00
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
if (splan->plan->extParam != NIL)
|
1998-02-26 05:46:47 +01:00
|
|
|
SetChangedParamList(splan, node->chgParam);
|
1998-02-13 04:26:53 +01:00
|
|
|
}
|
|
|
|
/* Well. Now set chgParam for left/right trees. */
|
1998-02-26 05:46:47 +01:00
|
|
|
if (node->lefttree != NULL)
|
|
|
|
SetChangedParamList(node->lefttree, node->chgParam);
|
|
|
|
if (node->righttree != NULL)
|
|
|
|
SetChangedParamList(node->righttree, node->chgParam);
|
1998-02-13 04:26:53 +01:00
|
|
|
}
|
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
switch (nodeTag(node))
|
|
|
|
{
|
2002-12-05 16:50:39 +01:00
|
|
|
case T_ResultState:
|
|
|
|
ExecReScanResult((ResultState *) node, exprCtxt);
|
1998-02-13 04:26:53 +01:00
|
|
|
break;
|
1997-09-08 04:41:22 +02:00
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
case T_AppendState:
|
|
|
|
ExecReScanAppend((AppendState *) node, exprCtxt);
|
1998-02-13 04:26:53 +01:00
|
|
|
break;
|
1997-09-08 04:41:22 +02:00
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
case T_SeqScanState:
|
|
|
|
ExecSeqReScan((SeqScanState *) node, exprCtxt);
|
2000-09-29 20:21:41 +02:00
|
|
|
break;
|
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
case T_IndexScanState:
|
|
|
|
ExecIndexReScan((IndexScanState *) node, exprCtxt);
|
2000-09-29 20:21:41 +02:00
|
|
|
break;
|
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
case T_TidScanState:
|
|
|
|
ExecTidReScan((TidScanState *) node, exprCtxt);
|
2002-05-12 22:10:05 +02:00
|
|
|
break;
|
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
case T_SubqueryScanState:
|
|
|
|
ExecSubqueryReScan((SubqueryScanState *) node, exprCtxt);
|
1998-02-13 04:26:53 +01:00
|
|
|
break;
|
1997-09-08 04:41:22 +02:00
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
case T_FunctionScanState:
|
|
|
|
ExecFunctionReScan((FunctionScanState *) node, exprCtxt);
|
1998-02-13 04:26:53 +01:00
|
|
|
break;
|
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
case T_NestLoopState:
|
|
|
|
ExecReScanNestLoop((NestLoopState *) node, exprCtxt);
|
1998-02-13 04:26:53 +01:00
|
|
|
break;
|
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
case T_MergeJoinState:
|
|
|
|
ExecReScanMergeJoin((MergeJoinState *) node, exprCtxt);
|
1998-02-13 04:26:53 +01:00
|
|
|
break;
|
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
case T_HashJoinState:
|
|
|
|
ExecReScanHashJoin((HashJoinState *) node, exprCtxt);
|
1998-02-13 04:26:53 +01:00
|
|
|
break;
|
1997-09-08 04:41:22 +02:00
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
case T_MaterialState:
|
|
|
|
ExecMaterialReScan((MaterialState *) node, exprCtxt);
|
1998-07-16 03:49:19 +02:00
|
|
|
break;
|
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
case T_SortState:
|
|
|
|
ExecReScanSort((SortState *) node, exprCtxt);
|
1998-02-13 04:26:53 +01:00
|
|
|
break;
|
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
case T_GroupState:
|
|
|
|
ExecReScanGroup((GroupState *) node, exprCtxt);
|
1998-02-23 07:28:16 +01:00
|
|
|
break;
|
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
case T_AggState:
|
|
|
|
ExecReScanAgg((AggState *) node, exprCtxt);
|
2000-10-05 21:11:39 +02:00
|
|
|
break;
|
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
case T_UniqueState:
|
|
|
|
ExecReScanUnique((UniqueState *) node, exprCtxt);
|
2000-10-26 23:38:24 +02:00
|
|
|
break;
|
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
case T_HashState:
|
|
|
|
ExecReScanHash((HashState *) node, exprCtxt);
|
1998-02-23 07:28:16 +01:00
|
|
|
break;
|
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
case T_SetOpState:
|
|
|
|
ExecReScanSetOp((SetOpState *) node, exprCtxt);
|
1998-02-27 17:11:28 +01:00
|
|
|
break;
|
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
case T_LimitState:
|
|
|
|
ExecReScanLimit((LimitState *) node, exprCtxt);
|
1998-07-16 00:16:21 +02:00
|
|
|
break;
|
|
|
|
|
1997-09-08 04:41:22 +02:00
|
|
|
default:
|
2000-07-26 01:43:38 +02:00
|
|
|
elog(ERROR, "ExecReScan: node type %d not supported",
|
|
|
|
nodeTag(node));
|
1997-09-08 04:41:22 +02:00
|
|
|
return;
|
1997-09-07 07:04:48 +02:00
|
|
|
}
|
1998-02-26 05:46:47 +01:00
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
if (node->chgParam != NIL)
|
1998-02-13 04:26:53 +01:00
|
|
|
{
|
1998-02-26 05:46:47 +01:00
|
|
|
freeList(node->chgParam);
|
2002-12-05 16:50:39 +01:00
|
|
|
node->chgParam = NIL;
|
1998-02-13 04:26:53 +01:00
|
|
|
}
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
1997-09-07 07:04:48 +02:00
|
|
|
|
2002-11-30 06:21:03 +01:00
|
|
|
/*
|
|
|
|
* ExecMarkPos
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
2002-11-30 06:21:03 +01:00
|
|
|
* Marks the current scan position.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
|
|
|
void
|
2002-12-05 16:50:39 +01:00
|
|
|
ExecMarkPos(PlanState *node)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
switch (nodeTag(node))
|
|
|
|
{
|
2002-12-05 16:50:39 +01:00
|
|
|
case T_SeqScanState:
|
|
|
|
ExecSeqMarkPos((SeqScanState *) node);
|
1997-09-08 04:41:22 +02:00
|
|
|
break;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
case T_IndexScanState:
|
|
|
|
ExecIndexMarkPos((IndexScanState *) node);
|
1997-09-08 04:41:22 +02:00
|
|
|
break;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
case T_TidScanState:
|
|
|
|
ExecTidMarkPos((TidScanState *) node);
|
2002-11-30 06:21:03 +01:00
|
|
|
break;
|
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
case T_FunctionScanState:
|
|
|
|
ExecFunctionMarkPos((FunctionScanState *) node);
|
2002-05-12 22:10:05 +02:00
|
|
|
break;
|
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
case T_MaterialState:
|
|
|
|
ExecMaterialMarkPos((MaterialState *) node);
|
2000-06-19 00:44:35 +02:00
|
|
|
break;
|
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
case T_SortState:
|
|
|
|
ExecSortMarkPos((SortState *) node);
|
1997-09-08 04:41:22 +02:00
|
|
|
break;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
1997-09-08 04:41:22 +02:00
|
|
|
default:
|
2000-07-26 01:43:38 +02:00
|
|
|
/* don't make hard error unless caller asks to restore... */
|
2002-12-05 16:50:39 +01:00
|
|
|
elog(DEBUG1, "ExecMarkPos: node type %d not supported",
|
2000-07-26 01:43:38 +02:00
|
|
|
nodeTag(node));
|
1997-09-08 04:41:22 +02:00
|
|
|
break;
|
1997-09-07 07:04:48 +02:00
|
|
|
}
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
1997-09-07 07:04:48 +02:00
|
|
|
|
2002-11-30 06:21:03 +01:00
|
|
|
/*
|
|
|
|
* ExecRestrPos
|
2000-07-26 01:43:38 +02:00
|
|
|
*
|
2002-11-30 06:21:03 +01:00
|
|
|
* restores the scan position previously saved with ExecMarkPos()
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
|
|
|
void
|
2002-12-05 16:50:39 +01:00
|
|
|
ExecRestrPos(PlanState *node)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
switch (nodeTag(node))
|
|
|
|
{
|
2002-12-05 16:50:39 +01:00
|
|
|
case T_SeqScanState:
|
|
|
|
ExecSeqRestrPos((SeqScanState *) node);
|
2000-07-26 01:43:38 +02:00
|
|
|
break;
|
1996-07-09 08:22:35 +02:00
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
case T_IndexScanState:
|
|
|
|
ExecIndexRestrPos((IndexScanState *) node);
|
2000-07-26 01:43:38 +02:00
|
|
|
break;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
case T_TidScanState:
|
|
|
|
ExecTidRestrPos((TidScanState *) node);
|
2002-11-30 06:21:03 +01:00
|
|
|
break;
|
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
case T_FunctionScanState:
|
|
|
|
ExecFunctionRestrPos((FunctionScanState *) node);
|
2002-05-12 22:10:05 +02:00
|
|
|
break;
|
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
case T_MaterialState:
|
|
|
|
ExecMaterialRestrPos((MaterialState *) node);
|
2000-07-26 01:43:38 +02:00
|
|
|
break;
|
2000-06-19 00:44:35 +02:00
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
case T_SortState:
|
|
|
|
ExecSortRestrPos((SortState *) node);
|
2000-07-26 01:43:38 +02:00
|
|
|
break;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
1997-09-08 04:41:22 +02:00
|
|
|
default:
|
2000-07-26 01:43:38 +02:00
|
|
|
elog(ERROR, "ExecRestrPos: node type %d not supported",
|
|
|
|
nodeTag(node));
|
|
|
|
break;
|
1997-09-07 07:04:48 +02:00
|
|
|
}
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
2002-11-30 06:21:03 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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.
|
2002-12-05 16:50:39 +01:00
|
|
|
* But note the test is on Plan nodetype, not PlanState nodetype.
|
2002-11-30 06:21:03 +01:00
|
|
|
*/
|
|
|
|
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;
|
|
|
|
}
|