aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor')
-rw-r--r--src/backend/executor/execMain.c16
-rw-r--r--src/backend/executor/execScan.c13
-rw-r--r--src/backend/executor/nodeAppend.c79
-rw-r--r--src/backend/executor/nodeFunctionscan.c7
-rw-r--r--src/backend/executor/nodeSubqueryscan.c25
5 files changed, 70 insertions, 70 deletions
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index b45850bd2b4..a390829bb8e 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -26,7 +26,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.248 2005/05/06 17:24:53 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.249 2005/05/22 22:30:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -353,16 +353,10 @@ ExecCheckRTEPerms(RangeTblEntry *rte)
AclId userid;
/*
- * If it's a subquery, recursively examine its rangetable.
- */
- if (rte->rtekind == RTE_SUBQUERY)
- {
- ExecCheckRTPerms(rte->subquery->rtable);
- return;
- }
-
- /*
- * Otherwise, only plain-relation RTEs need to be checked here.
+ * Only plain-relation RTEs need to be checked here. Subquery RTEs
+ * are checked by ExecInitSubqueryScan if the subquery is still a
+ * separate subquery --- if it's been pulled up into our query level
+ * then the RTEs are in our rangetable and will be checked here.
* Function RTEs are checked by init_fcache when the function is
* prepared for execution. Join and special RTEs need no checks.
*/
diff --git a/src/backend/executor/execScan.c b/src/backend/executor/execScan.c
index 1e80fa7be06..843aa15101c 100644
--- a/src/backend/executor/execScan.c
+++ b/src/backend/executor/execScan.c
@@ -12,7 +12,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/execScan.c,v 1.35 2005/03/16 21:38:06 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/execScan.c,v 1.36 2005/05/22 22:30:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -48,7 +48,6 @@ TupleTableSlot *
ExecScan(ScanState *node,
ExecScanAccessMtd accessMtd) /* function returning a tuple */
{
- EState *estate;
ExprContext *econtext;
List *qual;
ProjectionInfo *projInfo;
@@ -58,12 +57,17 @@ ExecScan(ScanState *node,
/*
* Fetch data from node
*/
- estate = node->ps.state;
- econtext = node->ps.ps_ExprContext;
qual = node->ps.qual;
projInfo = node->ps.ps_ProjInfo;
/*
+ * If we have neither a qual to check nor a projection to do,
+ * just skip all the overhead and return the raw scan tuple.
+ */
+ if (!qual && !projInfo)
+ return (*accessMtd) (node);
+
+ /*
* Check to see if we're still projecting out tuples from a previous
* scan tuple (because there is a function-returning-set in the
* projection expressions). If so, try to project another one.
@@ -83,6 +87,7 @@ ExecScan(ScanState *node,
* storage allocated in the previous tuple cycle. Note this can't
* happen until we're done projecting out tuples from a scan tuple.
*/
+ econtext = node->ps.ps_ExprContext;
ResetExprContext(econtext);
/*
diff --git a/src/backend/executor/nodeAppend.c b/src/backend/executor/nodeAppend.c
index 0f77741a825..b88eec46a40 100644
--- a/src/backend/executor/nodeAppend.c
+++ b/src/backend/executor/nodeAppend.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/nodeAppend.c,v 1.63 2005/04/24 11:46:20 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/nodeAppend.c,v 1.64 2005/05/22 22:30:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -251,67 +251,52 @@ ExecCountSlotsAppend(Append *node)
/* ----------------------------------------------------------------
* ExecAppend
*
- * Handles the iteration over the multiple scans.
+ * Handles iteration over multiple subplans.
* ----------------------------------------------------------------
*/
TupleTableSlot *
ExecAppend(AppendState *node)
{
- EState *estate;
- int whichplan;
- PlanState *subnode;
- TupleTableSlot *result;
- TupleTableSlot *result_slot;
- ScanDirection direction;
-
- /*
- * get information from the node
- */
- estate = node->ps.state;
- direction = estate->es_direction;
- whichplan = node->as_whichplan;
- result_slot = node->ps.ps_ResultTupleSlot;
-
- /*
- * figure out which subplan we are currently processing
- */
- subnode = node->appendplans[whichplan];
-
- /*
- * get a tuple from the subplan
- */
- result = ExecProcNode(subnode);
-
- if (!TupIsNull(result))
+ for (;;)
{
+ PlanState *subnode;
+ TupleTableSlot *result;
+
/*
- * if the subplan gave us something then return it as-is. We do
- * NOT make use of the result slot that was set up in ExecInitAppend,
- * first because there's no reason to and second because it may have
- * the wrong tuple descriptor in inherited-UPDATE cases.
+ * figure out which subplan we are currently processing
*/
- return result;
- }
- else
- {
+ subnode = node->appendplans[node->as_whichplan];
+
/*
- * .. go on to the "next" subplan in the appropriate direction and
- * try processing again (recursively)
+ * get a tuple from the subplan
*/
- if (ScanDirectionIsForward(direction))
- node->as_whichplan++;
- else
- node->as_whichplan--;
+ result = ExecProcNode(subnode);
+
+ if (!TupIsNull(result))
+ {
+ /*
+ * If the subplan gave us something then return it as-is.
+ * We do NOT make use of the result slot that was set up in
+ * ExecInitAppend, first because there's no reason to and
+ * second because it may have the wrong tuple descriptor in
+ * inherited-UPDATE cases.
+ */
+ return result;
+ }
/*
- * return something from next node or an empty slot if all of our
- * subplans have been exhausted. The empty slot is the one set up
+ * Go on to the "next" subplan in the appropriate direction.
+ * If no more subplans, return the empty slot set up for us
* by ExecInitAppend.
*/
- if (exec_append_initialize_next(node))
- return ExecAppend(node);
+ if (ScanDirectionIsForward(node->ps.state->es_direction))
+ node->as_whichplan++;
else
- return ExecClearTuple(result_slot);
+ node->as_whichplan--;
+ if (!exec_append_initialize_next(node))
+ return ExecClearTuple(node->ps.ps_ResultTupleSlot);
+
+ /* Else loop back and try to get a tuple from the new subplan */
}
}
diff --git a/src/backend/executor/nodeFunctionscan.c b/src/backend/executor/nodeFunctionscan.c
index f8f13f1c786..5cd6de45fda 100644
--- a/src/backend/executor/nodeFunctionscan.c
+++ b/src/backend/executor/nodeFunctionscan.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/nodeFunctionscan.c,v 1.33 2005/04/14 22:09:40 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/nodeFunctionscan.c,v 1.34 2005/05/22 22:30:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -219,8 +219,7 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate)
BlessTupleDesc(tupdesc);
scanstate->tupdesc = tupdesc;
- ExecSetSlotDescriptor(scanstate->ss.ss_ScanTupleSlot,
- tupdesc, false);
+ ExecAssignScanType(&scanstate->ss, tupdesc, false);
/*
* Other node-specific setup
@@ -235,7 +234,7 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate)
* Initialize result tuple type and projection info.
*/
ExecAssignResultTypeFromTL(&scanstate->ss.ps);
- ExecAssignProjectionInfo(&scanstate->ss.ps);
+ ExecAssignScanProjectionInfo(&scanstate->ss);
return scanstate;
}
diff --git a/src/backend/executor/nodeSubqueryscan.c b/src/backend/executor/nodeSubqueryscan.c
index 9bc5a6294d0..90e59f90f4d 100644
--- a/src/backend/executor/nodeSubqueryscan.c
+++ b/src/backend/executor/nodeSubqueryscan.c
@@ -12,7 +12,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/nodeSubqueryscan.c,v 1.25 2004/12/31 21:59:45 pgsql Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/nodeSubqueryscan.c,v 1.26 2005/05/22 22:30:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -78,6 +78,10 @@ SubqueryNext(SubqueryScanState *node)
MemoryContextSwitchTo(oldcontext);
+ /*
+ * We just overwrite our ScanTupleSlot with the subplan's result slot,
+ * rather than expending the cycles for ExecCopySlot().
+ */
node->ss.ss_ScanTupleSlot = slot;
return slot;
@@ -144,12 +148,13 @@ ExecInitSubqueryScan(SubqueryScan *node, EState *estate)
ExecInitExpr((Expr *) node->scan.plan.qual,
(PlanState *) subquerystate);
-#define SUBQUERYSCAN_NSLOTS 1
+#define SUBQUERYSCAN_NSLOTS 2
/*
* tuple table initialization
*/
ExecInitResultTupleSlot(estate, &subquerystate->ss.ps);
+ ExecInitScanTupleSlot(estate, &subquerystate->ss);
/*
* initialize subquery
@@ -160,6 +165,11 @@ ExecInitSubqueryScan(SubqueryScan *node, EState *estate)
Assert(rte->rtekind == RTE_SUBQUERY);
/*
+ * Do access checking on the rangetable entries in the subquery.
+ */
+ ExecCheckRTPerms(rte->subquery->rtable);
+
+ /*
* The subquery needs its own EState because it has its own
* rangetable. It shares our Param ID space, however. XXX if
* rangetable access were done differently, the subquery could share
@@ -187,14 +197,20 @@ ExecInitSubqueryScan(SubqueryScan *node, EState *estate)
MemoryContextSwitchTo(oldcontext);
- subquerystate->ss.ss_ScanTupleSlot = NULL;
subquerystate->ss.ps.ps_TupFromTlist = false;
/*
+ * Initialize scan tuple type (needed by ExecAssignScanProjectionInfo)
+ */
+ ExecAssignScanType(&subquerystate->ss,
+ ExecGetResultType(subquerystate->subplan),
+ false);
+
+ /*
* Initialize result tuple type and projection info.
*/
ExecAssignResultTypeFromTL(&subquerystate->ss.ps);
- ExecAssignProjectionInfo(&subquerystate->ss.ps);
+ ExecAssignScanProjectionInfo(&subquerystate->ss);
return subquerystate;
}
@@ -230,6 +246,7 @@ ExecEndSubqueryScan(SubqueryScanState *node)
* clean out the upper tuple table
*/
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
+ node->ss.ss_ScanTupleSlot = NULL; /* not ours to clear */
/*
* close down subquery