>From 13b77f0068ff2b5dd02f0b64a8f0f0ad2e60a4cf Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Thu, 7 Jul 2016 19:57:27 -0700 Subject: [PATCH 01/20] WIP: make get_last_attnums more generic. --- src/backend/executor/execUtils.c | 48 +++++++++++++++++++++++++++++----------- src/include/executor/executor.h | 4 ++++ 2 files changed, 39 insertions(+), 13 deletions(-) diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c index e937cf8..a3a59c0 100644 --- a/src/backend/executor/execUtils.c +++ b/src/backend/executor/execUtils.c @@ -47,7 +47,14 @@ #include "utils/rel.h" -static bool get_last_attnums(Node *node, ProjectionInfo *projInfo); +typedef struct LastLastAttnumInfo +{ + AttrNumber last_outer; + AttrNumber last_inner; + AttrNumber last_scan; +} LastAttnumInfo; + + static void ShutdownExprContext(ExprContext *econtext, bool isCommit); @@ -585,7 +592,10 @@ ExecBuildProjectionInfo(List *targetList, /* Not a simple variable, add it to generic targetlist */ exprlist = lappend(exprlist, gstate); /* Examine expr to include contained Vars in lastXXXVar counts */ - get_last_attnums((Node *) variable, projInfo); + ExecGetLastAttnums((Node *) variable, + &projInfo->pi_lastOuterVar, + &projInfo->pi_lastInnerVar, + &projInfo->pi_lastScanVar); } } projInfo->pi_targetlist = exprlist; @@ -602,13 +612,13 @@ ExecBuildProjectionInfo(List *targetList, } /* - * get_last_attnums: expression walker for ExecBuildProjectionInfo + * get_last_attnums_walker: expression walker for ExecBuildProjectionInfo * * Update the lastXXXVar counts to be at least as large as the largest * attribute numbers found in the expression */ static bool -get_last_attnums(Node *node, ProjectionInfo *projInfo) +get_last_attnums_walker(Node *node, LastAttnumInfo *info) { if (node == NULL) return false; @@ -620,21 +630,17 @@ get_last_attnums(Node *node, ProjectionInfo *projInfo) switch (variable->varno) { case INNER_VAR: - if (projInfo->pi_lastInnerVar < attnum) - projInfo->pi_lastInnerVar = attnum; + info->last_inner = Max(info->last_inner, attnum); break; case OUTER_VAR: - if (projInfo->pi_lastOuterVar < attnum) - projInfo->pi_lastOuterVar = attnum; + info->last_outer = Max(info->last_outer, attnum); break; /* INDEX_VAR is handled by default case */ default: - if (projInfo->pi_lastScanVar < attnum) - projInfo->pi_lastScanVar = attnum; - break; + info->last_scan = Max(info->last_scan, attnum); } return false; } @@ -651,10 +657,26 @@ get_last_attnums(Node *node, ProjectionInfo *projInfo) return false; if (IsA(node, GroupingFunc)) return false; - return expression_tree_walker(node, get_last_attnums, - (void *) projInfo); + return expression_tree_walker(node, get_last_attnums_walker, + (void *) info); } +void +ExecGetLastAttnums(Node *node, int *last_outer, int *last_inner, + int *last_scan) +{ + LastAttnumInfo info = {0,0,0}; + + get_last_attnums_walker(node, &info); + if (last_outer && *last_outer < info.last_outer) + *last_outer = info.last_outer; + if (last_inner && *last_inner < info.last_inner) + *last_inner = info.last_inner; + if (last_scan && *last_scan < info.last_scan) + *last_scan = info.last_scan; +} + + /* ---------------- * ExecAssignProjectionInfo * diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h index 39521ed..e5c0a56 100644 --- a/src/include/executor/executor.h +++ b/src/include/executor/executor.h @@ -338,6 +338,10 @@ extern void ExecAssignExprContext(EState *estate, PlanState *planstate); extern void ExecAssignResultType(PlanState *planstate, TupleDesc tupDesc); extern void ExecAssignResultTypeFromTL(PlanState *planstate); extern TupleDesc ExecGetResultType(PlanState *planstate); +extern void ExecGetLastAttnums(Node *node, + int *last_outer, + int *last_inner, + int *last_scan); extern ProjectionInfo *ExecBuildProjectionInfo(List *targetList, ExprContext *econtext, TupleTableSlot *slot, -- 2.8.1