1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-12 05:01:15 +03:00

Phase 1 of read-only-plans project: cause executor state nodes to point

to plan nodes, not vice-versa.  All executor state nodes now inherit from
struct PlanState.  Copying of plan trees has been simplified by not
storing a list of SubPlans in Plan nodes (eliminating duplicate links).
The executor still needs such a list, but it can build it during
ExecutorStart since it has to scan the plan tree anyway.
No initdb forced since no stored-on-disk structures changed, but you
will need a full recompile because of node-numbering changes.
This commit is contained in:
Tom Lane
2002-12-05 15:50:39 +00:00
parent 0f3b83edfa
commit 1fd0c59e25
71 changed files with 3032 additions and 3758 deletions

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/pquery.c,v 1.56 2002/11/18 01:17:39 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/tcop/pquery.c,v 1.57 2002/12/05 15:50:35 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,15 +23,16 @@
#include "utils/ps_status.h"
/* ----------------------------------------------------------------
* CreateQueryDesc
* ----------------------------------------------------------------
/*
* CreateQueryDesc
*/
QueryDesc *
CreateQueryDesc(Query *parsetree,
Plan *plantree,
CommandDest dest,
const char *portalName)
const char *portalName,
ParamListInfo params,
bool doInstrument)
{
QueryDesc *qd = (QueryDesc *) palloc(sizeof(QueryDesc));
@@ -40,56 +41,17 @@ CreateQueryDesc(Query *parsetree,
qd->plantree = plantree; /* plan */
qd->dest = dest; /* output dest */
qd->portalName = portalName; /* name, if dest is a portal */
qd->tupDesc = NULL; /* until set by ExecutorStart */
qd->params = params; /* parameter values passed into query */
qd->doInstrument = doInstrument; /* instrumentation wanted? */
/* null these fields until set by ExecutorStart */
qd->tupDesc = NULL;
qd->estate = NULL;
qd->planstate = NULL;
return qd;
}
/* ----------------------------------------------------------------
* CreateExecutorState
*
* Note: this may someday take parameters -cim 9/18/89
* ----------------------------------------------------------------
*/
EState *
CreateExecutorState(void)
{
EState *state;
/*
* create a new executor state
*/
state = makeNode(EState);
/*
* initialize the Executor State structure
*/
state->es_direction = ForwardScanDirection;
state->es_range_table = NIL;
state->es_result_relations = NULL;
state->es_num_result_relations = 0;
state->es_result_relation_info = NULL;
state->es_junkFilter = NULL;
state->es_into_relation_descriptor = NULL;
state->es_param_list_info = NULL;
state->es_param_exec_vals = NULL;
state->es_tupleTable = NULL;
state->es_query_cxt = CurrentMemoryContext;
state->es_per_tuple_exprcontext = NULL;
/*
* return the executor state structure
*/
return state;
}
/* ----------------
* PreparePortal
* ----------------
@@ -147,8 +109,6 @@ ProcessQuery(Query *parsetree,
Portal portal = NULL;
MemoryContext oldContext = NULL;
QueryDesc *queryDesc;
EState *state;
TupleDesc attinfo;
/*
* Check for special-case destinations
@@ -193,7 +153,7 @@ ProcessQuery(Query *parsetree,
/*
* We stay in portal's memory context for now, so that query desc,
* EState, and plan startup info are also allocated in the portal
* exec state, and plan startup info are also allocated in the portal
* context.
*/
}
@@ -201,17 +161,12 @@ ProcessQuery(Query *parsetree,
/*
* Now we can create the QueryDesc object.
*/
queryDesc = CreateQueryDesc(parsetree, plan, dest, intoName);
/*
* create a default executor state.
*/
state = CreateExecutorState();
queryDesc = CreateQueryDesc(parsetree, plan, dest, intoName, NULL, false);
/*
* call ExecStart to prepare the plan for execution
*/
attinfo = ExecutorStart(queryDesc, state);
ExecutorStart(queryDesc);
/*
* If retrieve into portal, stop now; we do not run the plan until a
@@ -219,11 +174,8 @@ ProcessQuery(Query *parsetree,
*/
if (isRetrieveIntoPortal)
{
PortalSetQuery(portal,
queryDesc,
attinfo,
state,
PortalCleanup);
/* Arrange to shut down the executor if portal is dropped */
PortalSetQuery(portal, queryDesc, PortalCleanup);
/* Now we can return to caller's memory context. */
MemoryContextSwitchTo(oldContext);
@@ -239,7 +191,7 @@ ProcessQuery(Query *parsetree,
* Now we get to the important call to ExecutorRun() where we actually
* run the plan..
*/
ExecutorRun(queryDesc, state, ForwardScanDirection, 0L);
ExecutorRun(queryDesc, ForwardScanDirection, 0L);
/*
* Build command completion status string, if caller wants one.
@@ -254,20 +206,20 @@ ProcessQuery(Query *parsetree,
strcpy(completionTag, "SELECT");
break;
case CMD_INSERT:
if (state->es_processed == 1)
lastOid = state->es_lastoid;
if (queryDesc->estate->es_processed == 1)
lastOid = queryDesc->estate->es_lastoid;
else
lastOid = InvalidOid;
snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
"INSERT %u %u", lastOid, state->es_processed);
"INSERT %u %u", lastOid, queryDesc->estate->es_processed);
break;
case CMD_UPDATE:
snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
"UPDATE %u", state->es_processed);
"UPDATE %u", queryDesc->estate->es_processed);
break;
case CMD_DELETE:
snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
"DELETE %u", state->es_processed);
"DELETE %u", queryDesc->estate->es_processed);
break;
default:
strcpy(completionTag, "???");
@@ -278,5 +230,5 @@ ProcessQuery(Query *parsetree,
/*
* Now, we close down all the scans and free allocated resources.
*/
ExecutorEnd(queryDesc, state);
ExecutorEnd(queryDesc);
}