mirror of
https://github.com/postgres/postgres.git
synced 2025-12-01 12:18:01 +03:00
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.
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/mmgr/portalmem.c,v 1.98 2007/01/05 22:19:47 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/mmgr/portalmem.c,v 1.99 2007/02/20 17:32:17 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -141,29 +141,45 @@ GetPortalByName(const char *name)
|
||||
}
|
||||
|
||||
/*
|
||||
* PortalListGetPrimaryQuery
|
||||
* Get the "primary" Query within a portal, ie, the one marked canSetTag.
|
||||
* PortalListGetPrimaryStmt
|
||||
* Get the "primary" stmt within a portal, ie, the one marked canSetTag.
|
||||
*
|
||||
* Returns NULL if no such Query. If multiple Query structs within the
|
||||
* Returns NULL if no such stmt. If multiple PlannedStmt structs within the
|
||||
* portal are marked canSetTag, returns the first one. Neither of these
|
||||
* cases should occur in present usages of this function.
|
||||
*
|
||||
* Copes if given a list of Querys --- can't happen in a portal, but this
|
||||
* code also supports prepared statements, which need both cases.
|
||||
*
|
||||
* Note: the reason this is just handed a List is so that prepared statements
|
||||
* can share the code. For use with a portal, use PortalGetPrimaryQuery
|
||||
* can share the code. For use with a portal, use PortalGetPrimaryStmt
|
||||
* rather than calling this directly.
|
||||
*/
|
||||
Query *
|
||||
PortalListGetPrimaryQuery(List *parseTrees)
|
||||
Node *
|
||||
PortalListGetPrimaryStmt(List *stmts)
|
||||
{
|
||||
ListCell *lc;
|
||||
|
||||
foreach(lc, parseTrees)
|
||||
foreach(lc, stmts)
|
||||
{
|
||||
Query *query = (Query *) lfirst(lc);
|
||||
Node *stmt = (Node *) lfirst(lc);
|
||||
|
||||
Assert(IsA(query, Query));
|
||||
if (query->canSetTag)
|
||||
return query;
|
||||
if (IsA(stmt, PlannedStmt))
|
||||
{
|
||||
if (((PlannedStmt *) stmt)->canSetTag)
|
||||
return stmt;
|
||||
}
|
||||
else if (IsA(stmt, Query))
|
||||
{
|
||||
if (((Query *) stmt)->canSetTag)
|
||||
return stmt;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Utility stmts are assumed canSetTag if they're the only stmt */
|
||||
if (list_length(stmts) == 1)
|
||||
return stmt;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -261,30 +277,25 @@ CreateNewPortal(void)
|
||||
* (before rewriting) was an empty string. Also, the passed commandTag must
|
||||
* be a pointer to a constant string, since it is not copied. The caller is
|
||||
* responsible for ensuring that the passed prepStmtName (if any), sourceText
|
||||
* (if any), parse and plan trees have adequate lifetime. Also, queryContext
|
||||
* must accurately describe the location of the parse trees.
|
||||
* (if any), and plan trees have adequate lifetime.
|
||||
*/
|
||||
void
|
||||
PortalDefineQuery(Portal portal,
|
||||
const char *prepStmtName,
|
||||
const char *sourceText,
|
||||
const char *commandTag,
|
||||
List *parseTrees,
|
||||
List *planTrees,
|
||||
List *stmts,
|
||||
MemoryContext queryContext)
|
||||
{
|
||||
AssertArg(PortalIsValid(portal));
|
||||
AssertState(portal->queryContext == NULL); /* else defined already */
|
||||
|
||||
Assert(list_length(parseTrees) == list_length(planTrees));
|
||||
|
||||
Assert(commandTag != NULL || parseTrees == NIL);
|
||||
Assert(commandTag != NULL || stmts == NIL);
|
||||
|
||||
portal->prepStmtName = prepStmtName;
|
||||
portal->sourceText = sourceText;
|
||||
portal->commandTag = commandTag;
|
||||
portal->parseTrees = parseTrees;
|
||||
portal->planTrees = planTrees;
|
||||
portal->stmts = stmts;
|
||||
portal->queryContext = queryContext;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user