aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor')
-rw-r--r--src/backend/executor/execAmi.c71
-rw-r--r--src/backend/executor/execMain.c68
-rw-r--r--src/backend/executor/execUtils.c5
3 files changed, 31 insertions, 113 deletions
diff --git a/src/backend/executor/execAmi.c b/src/backend/executor/execAmi.c
index b637b5a08f2..154301a67f9 100644
--- a/src/backend/executor/execAmi.c
+++ b/src/backend/executor/execAmi.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/executor/execAmi.c,v 1.95 2008/07/10 01:17:29 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/execAmi.c,v 1.96 2008/07/26 19:15:35 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -424,72 +424,3 @@ ExecSupportsBackwardScan(Plan *node)
return false;
}
}
-
-/*
- * ExecMayReturnRawTuples
- * Check whether a plan tree may return "raw" disk tuples (that is,
- * pointers to original data in disk buffers, as opposed to temporary
- * tuples constructed by projection steps). In the case of Append,
- * some subplans may return raw tuples and others projected tuples;
- * we return "true" if any of the returned tuples could be raw.
- *
- * This must be passed an already-initialized planstate tree, because we
- * need to look at the results of ExecAssignScanProjectionInfo().
- */
-bool
-ExecMayReturnRawTuples(PlanState *node)
-{
- /*
- * At a table scan node, we check whether ExecAssignScanProjectionInfo
- * decided to do projection or not. Most non-scan nodes always project
- * and so we can return "false" immediately. For nodes that don't project
- * but just pass up input tuples, we have to recursively examine the input
- * plan node.
- *
- * Note: Hash and Material are listed here because they sometimes return
- * an original input tuple, not a copy. But Sort and SetOp never return
- * an original tuple, so they can be treated like projecting nodes.
- */
- switch (nodeTag(node))
- {
- /* Table scan nodes */
- case T_SeqScanState:
- case T_IndexScanState:
- case T_BitmapHeapScanState:
- case T_TidScanState:
- if (node->ps_ProjInfo == NULL)
- return true;
- break;
-
- case T_SubqueryScanState:
- /* If not projecting, look at input plan */
- if (node->ps_ProjInfo == NULL)
- return ExecMayReturnRawTuples(((SubqueryScanState *) node)->subplan);
- break;
-
- /* Non-projecting nodes */
- case T_HashState:
- case T_MaterialState:
- case T_UniqueState:
- case T_LimitState:
- return ExecMayReturnRawTuples(node->lefttree);
-
- case T_AppendState:
- {
- AppendState *appendstate = (AppendState *) node;
- int j;
-
- for (j = 0; j < appendstate->as_nplans; j++)
- {
- if (ExecMayReturnRawTuples(appendstate->appendplans[j]))
- return true;
- }
- break;
- }
-
- /* All projecting node types come here */
- default:
- break;
- }
- return false;
-}
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 93f78046707..4a4c9188578 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.310 2008/07/18 18:23:46 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.311 2008/07/26 19:15:35 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -694,9 +694,7 @@ InitPlan(QueryDesc *queryDesc, int eflags)
/*
* Initialize the junk filter if needed. SELECT and INSERT queries need a
- * filter if there are any junk attrs in the tlist. INSERT and SELECT
- * INTO also need a filter if the plan may return raw disk tuples (else
- * heap_insert will be scribbling on the source relation!). UPDATE and
+ * filter if there are any junk attrs in the tlist. UPDATE and
* DELETE always need a filter, since there's always a junk 'ctid'
* attribute present --- no need to look first.
*/
@@ -718,10 +716,6 @@ InitPlan(QueryDesc *queryDesc, int eflags)
break;
}
}
- if (!junk_filter_needed &&
- (operation == CMD_INSERT || estate->es_select_into) &&
- ExecMayReturnRawTuples(planstate))
- junk_filter_needed = true;
break;
case CMD_UPDATE:
case CMD_DELETE:
@@ -2424,8 +2418,6 @@ EvalPlanQualStart(evalPlanQual *epq, EState *estate, evalPlanQual *priorepq)
epqstate->es_result_relation_info = estate->es_result_relation_info;
epqstate->es_junkFilter = estate->es_junkFilter;
/* es_trig_target_relations must NOT be copied */
- epqstate->es_into_relation_descriptor = estate->es_into_relation_descriptor;
- epqstate->es_into_relation_use_wal = estate->es_into_relation_use_wal;
epqstate->es_param_list_info = estate->es_param_list_info;
if (estate->es_plannedstmt->nParamExec > 0)
epqstate->es_param_exec_vals = (ParamExecData *)
@@ -2559,15 +2551,14 @@ ExecGetActivePlanTree(QueryDesc *queryDesc)
*
* We implement SELECT INTO by diverting SELECT's normal output with
* a specialized DestReceiver type.
- *
- * TODO: remove some of the INTO-specific cruft from EState, and keep
- * it in the DestReceiver instead.
*/
typedef struct
{
DestReceiver pub; /* publicly-known function pointers */
EState *estate; /* EState we are working with */
+ Relation rel; /* Relation to write to */
+ bool use_wal; /* do we need to WAL-log our writes? */
} DR_intorel;
/*
@@ -2692,15 +2683,6 @@ OpenIntoRel(QueryDesc *queryDesc)
*/
intoRelationDesc = heap_open(intoRelationId, AccessExclusiveLock);
- /* use_wal off requires rd_targblock be initially invalid */
- Assert(intoRelationDesc->rd_targblock == InvalidBlockNumber);
-
- /*
- * We can skip WAL-logging the insertions, unless PITR is in use.
- */
- estate->es_into_relation_use_wal = XLogArchivingActive();
- estate->es_into_relation_descriptor = intoRelationDesc;
-
/*
* Now replace the query's DestReceiver with one for SELECT INTO
*/
@@ -2708,6 +2690,15 @@ OpenIntoRel(QueryDesc *queryDesc)
myState = (DR_intorel *) queryDesc->dest;
Assert(myState->pub.mydest == DestIntoRel);
myState->estate = estate;
+
+ /*
+ * We can skip WAL-logging the insertions, unless PITR is in use.
+ */
+ myState->use_wal = XLogArchivingActive();
+ myState->rel = intoRelationDesc;
+
+ /* use_wal off requires rd_targblock be initially invalid */
+ Assert(intoRelationDesc->rd_targblock == InvalidBlockNumber);
}
/*
@@ -2716,19 +2707,19 @@ OpenIntoRel(QueryDesc *queryDesc)
static void
CloseIntoRel(QueryDesc *queryDesc)
{
- EState *estate = queryDesc->estate;
+ DR_intorel *myState = (DR_intorel *) queryDesc->dest;
/* OpenIntoRel might never have gotten called */
- if (estate->es_into_relation_descriptor)
+ if (myState && myState->pub.mydest == DestIntoRel && myState->rel)
{
/* If we skipped using WAL, must heap_sync before commit */
- if (!estate->es_into_relation_use_wal)
- heap_sync(estate->es_into_relation_descriptor);
+ if (!myState->use_wal)
+ heap_sync(myState->rel);
/* close rel, but keep lock until commit */
- heap_close(estate->es_into_relation_descriptor, NoLock);
+ heap_close(myState->rel, NoLock);
- estate->es_into_relation_descriptor = NULL;
+ myState->rel = NULL;
}
}
@@ -2736,13 +2727,13 @@ CloseIntoRel(QueryDesc *queryDesc)
* CreateIntoRelDestReceiver -- create a suitable DestReceiver object
*
* Since CreateDestReceiver doesn't accept the parameters we'd need,
- * we just leave the private fields empty here. OpenIntoRel will
+ * we just leave the private fields zeroed here. OpenIntoRel will
* fill them in.
*/
DestReceiver *
CreateIntoRelDestReceiver(void)
{
- DR_intorel *self = (DR_intorel *) palloc(sizeof(DR_intorel));
+ DR_intorel *self = (DR_intorel *) palloc0(sizeof(DR_intorel));
self->pub.receiveSlot = intorel_receive;
self->pub.rStartup = intorel_startup;
@@ -2750,8 +2741,6 @@ CreateIntoRelDestReceiver(void)
self->pub.rDestroy = intorel_destroy;
self->pub.mydest = DestIntoRel;
- self->estate = NULL;
-
return (DestReceiver *) self;
}
@@ -2771,21 +2760,22 @@ static void
intorel_receive(TupleTableSlot *slot, DestReceiver *self)
{
DR_intorel *myState = (DR_intorel *) self;
- EState *estate = myState->estate;
HeapTuple tuple;
- tuple = ExecCopySlotTuple(slot);
+ /*
+ * get the heap tuple out of the tuple table slot, making sure we have a
+ * writable copy
+ */
+ tuple = ExecMaterializeSlot(slot);
- heap_insert(estate->es_into_relation_descriptor,
+ heap_insert(myState->rel,
tuple,
- estate->es_output_cid,
- estate->es_into_relation_use_wal,
+ myState->estate->es_output_cid,
+ myState->use_wal,
false); /* never any point in using FSM */
/* We know this is a newly created relation, so there are no indexes */
- heap_freetuple(tuple);
-
IncrAppended();
}
diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c
index 6dad21e3067..f53f9d12e95 100644
--- a/src/backend/executor/execUtils.c
+++ b/src/backend/executor/execUtils.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/execUtils.c,v 1.155 2008/03/26 21:10:38 alvherre Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/execUtils.c,v 1.156 2008/07/26 19:15:35 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -190,9 +190,6 @@ CreateExecutorState(void)
estate->es_trig_target_relations = NIL;
estate->es_trig_tuple_slot = NULL;
- estate->es_into_relation_descriptor = NULL;
- estate->es_into_relation_use_wal = false;
-
estate->es_param_list_info = NULL;
estate->es_param_exec_vals = NULL;