From: Andres Freund Date: Tue, 14 Mar 2017 03:22:09 +0000 (-0700) Subject: Make get_last_attnums more generic. X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js?a=commitdiff_plain;h=6b0f413c2050ff92a14060039c98ffffd2d7778e;p=users%2Fandresfreund%2Fpostgres.git Make get_last_attnums more generic. This is just useful infrastructure for a later commit. Author: Andres Freund Discussion: https://postgr.es/m/20161206034955.bh33paeralxbtluv@alap3.anarazel.de --- diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c index 3d6a3801c0..d205101b89 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); @@ -580,7 +587,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; @@ -591,13 +601,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; @@ -609,21 +619,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; } @@ -640,10 +646,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 02dbe7b228..f722f33a66 100644 --- a/src/include/executor/executor.h +++ b/src/include/executor/executor.h @@ -354,6 +354,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,