aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/functions.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2007-02-20 17:32:18 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2007-02-20 17:32:18 +0000
commit9cbd0c155d1602aad879f510256b626c58942080 (patch)
tree6d5504a4e841313d3a29cead80067006dc408e39 /src/backend/executor/functions.c
parent71b0cf2f6bec3129f2c3f574d4e47408c2dc2516 (diff)
downloadpostgresql-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.c50
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;