Make get_last_attnums more generic.
authorAndres Freund <andres@anarazel.de>
Tue, 14 Mar 2017 03:22:09 +0000 (20:22 -0700)
committerAndres Freund <andres@anarazel.de>
Tue, 14 Mar 2017 06:32:49 +0000 (23:32 -0700)
This is just useful infrastructure for a later commit.

Author: Andres Freund
Discussion: https://postgr.es/m/20161206034955.bh33paeralxbtluv@alap3.anarazel.de

src/backend/executor/execUtils.c
src/include/executor/executor.h

index 3d6a3801c060179908c6d2069558db0344d4e105..d205101b89a0777bde3e105ddd6fb33130a07600 100644 (file)
 #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
  *
index 02dbe7b228023c6b30a64eceeee00c2bd17a5a2c..f722f33a667d76812d62d73dfe2e1e8bbc966edd 100644 (file)
@@ -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,