1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-30 11:03:19 +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/executor/execQual.c,v 1.112 2002/12/01 20:27:32 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.113 2002/12/05 15:50:31 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -1766,7 +1766,8 @@ ExecEvalExpr(Node *expression,
isNull, isDone);
break;
case SUBPLAN_EXPR:
retDatum = ExecSubPlan((SubPlan *) expr->oper,
/* XXX temporary hack to find exec state node */
retDatum = ExecSubPlan(((SubPlan *) expr->oper)->pstate,
expr->args, econtext,
isNull);
break;
@ -1850,6 +1851,169 @@ ExecEvalExprSwitchContext(Node *expression,
}
/*
* ExecInitExpr: prepare an expression tree for execution
*
* 'node' is the root of the expression tree to examine
* 'parent' is the PlanState node that owns the expression,
* or NULL if we are preparing an expression that is not associated
* with a plan. (If so, it can't have Aggrefs or SubPlans.)
*
* Soon this will generate an expression state tree paralleling the given
* expression tree. Right now, it just searches the expression tree for
* Aggref and SubPlan nodes.
*/
Node *
ExecInitExpr(Node *node, PlanState *parent)
{
List *temp;
if (node == NULL)
return NULL;
switch (nodeTag(node))
{
case T_Var:
break;
case T_Const:
break;
case T_Param:
break;
case T_Aggref:
if (parent && IsA(parent, AggState))
{
AggState *aggstate = (AggState *) parent;
int naggs;
aggstate->aggs = lcons(node, aggstate->aggs);
naggs = ++aggstate->numaggs;
ExecInitExpr(((Aggref *) node)->target, parent);
/*
* Complain if the aggregate's argument contains any
* aggregates; nested agg functions are semantically
* nonsensical. (This probably was caught earlier,
* but we defend against it here anyway.)
*/
if (naggs != aggstate->numaggs)
elog(ERROR, "Aggregate function calls may not be nested");
}
else
elog(ERROR, "ExecInitExpr: Aggref not expected here");
break;
case T_ArrayRef:
{
ArrayRef *aref = (ArrayRef *) node;
ExecInitExpr((Node *) aref->refupperindexpr, parent);
ExecInitExpr((Node *) aref->reflowerindexpr, parent);
ExecInitExpr(aref->refexpr, parent);
ExecInitExpr(aref->refassgnexpr, parent);
}
break;
case T_Expr:
{
Expr *expr = (Expr *) node;
switch (expr->opType)
{
case OP_EXPR:
break;
case FUNC_EXPR:
break;
case OR_EXPR:
break;
case AND_EXPR:
break;
case NOT_EXPR:
break;
case DISTINCT_EXPR:
break;
case SUBPLAN_EXPR:
if (parent)
{
SubLink *sublink = ((SubPlan *) expr->oper)->sublink;
/*
* Here we just add the SubPlan nodes to
* parent->subPlan. Later they will be expanded
* to SubPlanState nodes.
*/
parent->subPlan = lcons(expr->oper,
parent->subPlan);
/* Must recurse into oper list too */
Assert(IsA(sublink, SubLink));
if (sublink->lefthand)
elog(ERROR, "ExecInitExpr: sublink has not been transformed");
ExecInitExpr((Node *) sublink->oper, parent);
}
else
elog(ERROR, "ExecInitExpr: SubPlan not expected here");
break;
default:
elog(ERROR, "ExecInitExpr: unknown expression type %d",
expr->opType);
break;
}
/* for all Expr node types, examine args list */
ExecInitExpr((Node *) expr->args, parent);
}
break;
case T_FieldSelect:
ExecInitExpr(((FieldSelect *) node)->arg, parent);
break;
case T_RelabelType:
ExecInitExpr(((RelabelType *) node)->arg, parent);
break;
case T_CaseExpr:
{
CaseExpr *caseexpr = (CaseExpr *) node;
foreach(temp, caseexpr->args)
{
CaseWhen *when = (CaseWhen *) lfirst(temp);
Assert(IsA(when, CaseWhen));
ExecInitExpr(when->expr, parent);
ExecInitExpr(when->result, parent);
}
/* caseexpr->arg should be null, but we'll check it anyway */
ExecInitExpr(caseexpr->arg, parent);
ExecInitExpr(caseexpr->defresult, parent);
}
break;
case T_NullTest:
ExecInitExpr(((NullTest *) node)->arg, parent);
break;
case T_BooleanTest:
ExecInitExpr(((BooleanTest *) node)->arg, parent);
break;
case T_ConstraintTest:
ExecInitExpr(((ConstraintTest *) node)->arg, parent);
ExecInitExpr(((ConstraintTest *) node)->check_expr, parent);
break;
case T_ConstraintTestValue:
break;
case T_List:
foreach(temp, (List *) node)
{
ExecInitExpr((Node *) lfirst(temp), parent);
}
break;
case T_TargetEntry:
ExecInitExpr(((TargetEntry *) node)->expr, parent);
break;
default:
elog(ERROR, "ExecInitExpr: unknown expression type %d",
nodeTag(node));
break;
}
return node;
}
/* ----------------------------------------------------------------
* ExecQual / ExecTargetList / ExecProject
* ----------------------------------------------------------------