diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2007-02-20 17:32:18 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2007-02-20 17:32:18 +0000 |
commit | 9cbd0c155d1602aad879f510256b626c58942080 (patch) | |
tree | 6d5504a4e841313d3a29cead80067006dc408e39 /src/backend/executor/functions.c | |
parent | 71b0cf2f6bec3129f2c3f574d4e47408c2dc2516 (diff) | |
download | postgresql-9cbd0c155d1602aad879f510256b626c58942080.tar.gz postgresql-9cbd0c155d1602aad879f510256b626c58942080.zip |
Remove the Query structure from the executor's API. This allows us to stop
storing mostly-redundant Query trees in prepared statements, portals, etc.
To replace Query, a new node type called PlannedStmt is inserted by the
planner at the top of a completed plan tree; this carries just the fields of
Query that are still needed at runtime. The statement lists kept in portals
etc. now consist of intermixed PlannedStmt and bare utility-statement nodes
--- no Query. This incidentally allows us to remove some fields from Query
and Plan nodes that shouldn't have been there in the first place.
Still to do: simplify the execution-time range table; at the moment the
range table passed to the executor still contains Query trees for subqueries.
initdb forced due to change of stored rules.
Diffstat (limited to 'src/backend/executor/functions.c')
-rw-r--r-- | src/backend/executor/functions.c | 50 |
1 files changed, 29 insertions, 21 deletions
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c index 78044b2d614..596a482fa13 100644 --- a/src/backend/executor/functions.c +++ b/src/backend/executor/functions.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.110 2007/02/02 00:02:55 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.111 2007/02/20 17:32:15 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -33,8 +33,8 @@ /* * We have an execution_state record for each query in a function. Each - * record contains a querytree and plantree for its query. If the query - * is currently in F_EXEC_RUN state then there's a QueryDesc too. + * record contains a plantree for its query. If the query is currently in + * F_EXEC_RUN state then there's a QueryDesc too. */ typedef enum { @@ -45,8 +45,7 @@ typedef struct local_es { struct local_es *next; ExecStatus status; - Query *query; - Plan *plan; + Node *stmt; /* PlannedStmt or utility statement */ QueryDesc *qd; /* null unless status == RUN */ } execution_state; @@ -105,26 +104,30 @@ init_execution_state(List *queryTree_list, bool readonly_func) foreach(qtl_item, queryTree_list) { Query *queryTree = lfirst(qtl_item); - Plan *planTree; + Node *stmt; execution_state *newes; + Assert(IsA(queryTree, Query)); + + if (queryTree->commandType == CMD_UTILITY) + stmt = queryTree->utilityStmt; + else + stmt = (Node *) pg_plan_query(queryTree, NULL); + /* Precheck all commands for validity in a function */ - if (queryTree->commandType == CMD_UTILITY && - IsA(queryTree->utilityStmt, TransactionStmt)) + if (IsA(stmt, TransactionStmt)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), /* translator: %s is a SQL statement name */ errmsg("%s is not allowed in a SQL function", - CreateQueryTag(queryTree)))); + CreateCommandTag(stmt)))); - if (readonly_func && !QueryIsReadOnly(queryTree)) + if (readonly_func && !CommandIsReadOnly(stmt)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), /* translator: %s is a SQL statement name */ errmsg("%s is not allowed in a non-volatile function", - CreateQueryTag(queryTree)))); - - planTree = pg_plan_query(queryTree, NULL); + CreateCommandTag(stmt)))); newes = (execution_state *) palloc(sizeof(execution_state)); if (preves) @@ -134,8 +137,7 @@ init_execution_state(List *queryTree_list, bool readonly_func) newes->next = NULL; newes->status = F_EXEC_START; - newes->query = queryTree; - newes->plan = planTree; + newes->stmt = stmt; newes->qd = NULL; preves = newes; @@ -298,10 +300,16 @@ postquel_start(execution_state *es, SQLFunctionCachePtr fcache) snapshot = CopySnapshot(GetTransactionSnapshot()); } - es->qd = CreateQueryDesc(es->query, es->plan, - snapshot, InvalidSnapshot, - None_Receiver, - fcache->paramLI, false); + if (IsA(es->stmt, PlannedStmt)) + es->qd = CreateQueryDesc((PlannedStmt *) es->stmt, + snapshot, InvalidSnapshot, + None_Receiver, + fcache->paramLI, false); + else + es->qd = CreateUtilityQueryDesc(es->stmt, + snapshot, + None_Receiver, + fcache->paramLI); /* We assume we don't need to set up ActiveSnapshot for ExecutorStart */ @@ -337,7 +345,7 @@ postquel_getnext(execution_state *es) if (es->qd->operation == CMD_UTILITY) { - ProcessUtility(es->qd->parsetree->utilityStmt, es->qd->params, + ProcessUtility(es->qd->utilitystmt, es->qd->params, es->qd->dest, NULL); result = NULL; } @@ -351,7 +359,7 @@ postquel_getnext(execution_state *es) */ if (LAST_POSTQUEL_COMMAND(es) && es->qd->operation == CMD_SELECT && - es->qd->parsetree->into == NULL) + es->qd->plannedstmt->into == NULL) count = 1L; else count = 0L; |