From d1c9de360792fae0c33e53c9d94f6dbd2b072be0 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@enterprisedb.com>
Date: Sat, 12 Jan 2019 17:28:45 +1300
Subject: [PATCH 5/5] Convert p_joinexprs from a List to a nodep_vector.

---
 src/backend/parser/analyze.c        |  2 +-
 src/backend/parser/parse_clause.c   |  8 ++++----
 src/backend/parser/parse_relation.c |  4 ++--
 src/include/parser/parse_node.h     |  3 ++-
 src/include/utils/builtins.h        | 18 ++++++++++++++++++
 5 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index 5ff6964d51..d22400debb 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -594,7 +594,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
 		 * the target column's type, which we handle below.
 		 */
 		sub_pstate->p_rtable = sub_rtable;
-		sub_pstate->p_joinexprs = NIL;	/* sub_rtable has no joins */
+		nodep_vector_clear(&sub_pstate->p_joinexprs);	/* sub_rtable has no joins */
 		sub_pstate->p_namespace = sub_namespace;
 		sub_pstate->p_resolve_unknowns = false;
 
diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c
index 6963922b0e..fd2e4f88a0 100644
--- a/src/backend/parser/parse_clause.c
+++ b/src/backend/parser/parse_clause.c
@@ -1460,10 +1460,10 @@ transformFromClauseItem(ParseState *pstate, Node *n,
 		*top_rti = j->rtindex;
 
 		/* make a matching link to the JoinExpr for later use */
-		for (k = list_length(pstate->p_joinexprs) + 1; k < j->rtindex; k++)
-			pstate->p_joinexprs = lappend(pstate->p_joinexprs, NULL);
-		pstate->p_joinexprs = lappend(pstate->p_joinexprs, j);
-		Assert(list_length(pstate->p_joinexprs) == j->rtindex);
+		for (k = nodep_vector_size(&pstate->p_joinexprs) + 1; k < j->rtindex; k++)
+			nodep_vector_push_back(&pstate->p_joinexprs, NULL);
+		nodep_vector_push_back(&pstate->p_joinexprs, j);
+		Assert(nodep_vector_size(&pstate->p_joinexprs) == j->rtindex);
 
 		/*
 		 * Prepare returned namespace list.  If the JOIN has an alias then it
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c
index dfbc1cc499..c94a9b7f73 100644
--- a/src/backend/parser/parse_relation.c
+++ b/src/backend/parser/parse_relation.c
@@ -931,8 +931,8 @@ markRTEForSelectPriv(ParseState *pstate, RangeTblEntry *rte,
 			 */
 			JoinExpr   *j;
 
-			if (rtindex > 0 && rtindex <= list_length(pstate->p_joinexprs))
-				j = list_nth_node(JoinExpr, pstate->p_joinexprs, rtindex - 1);
+			if (rtindex > 0 && rtindex <= nodep_vector_size(&pstate->p_joinexprs))
+				j = nodep_vector_nth(JoinExpr, &pstate->p_joinexprs, rtindex - 1);
 			else
 				j = NULL;
 			if (j == NULL)
diff --git a/src/include/parser/parse_node.h b/src/include/parser/parse_node.h
index f4e1cdd85b..c437bcf9f2 100644
--- a/src/include/parser/parse_node.h
+++ b/src/include/parser/parse_node.h
@@ -15,6 +15,7 @@
 #define PARSE_NODE_H
 
 #include "nodes/parsenodes.h"
+#include "utils/builtins.h"
 #include "utils/queryenvironment.h"
 #include "utils/relcache.h"
 
@@ -172,7 +173,7 @@ struct ParseState
 	struct ParseState *parentParseState;	/* stack link */
 	const char *p_sourcetext;	/* source text, or NULL if not available */
 	List	   *p_rtable;		/* range table so far */
-	List	   *p_joinexprs;	/* JoinExprs for RTE_JOIN p_rtable entries */
+	nodep_vector p_joinexprs;	/* JoinExprs for RTE_JOIN p_rtable entries */
 	List	   *p_joinlist;		/* join items so far (will become FromExpr
 								 * node's fromlist) */
 	List	   *p_namespace;	/* currently-referenceable RTEs (List of
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index 2a8b8b808e..342a616224 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -26,6 +26,24 @@
 #define SV_DEFINE
 #include "lib/simplevector.h"
 
+#define SV_PREFIX nodep_vector
+#define SV_ELEMENT_TYPE Node *
+#define SV_SCOPE static inline
+#define SV_EQ(a, b) ((*a) == (*b))
+#define SV_DECLARE
+#define SV_DEFINE
+#include "lib/simplevector.h"
+
+/* Convenience accessors for arrays of Node pointers. */
+#define nodep_vector_nth(type, vec, n) \
+	(castNode(type, *nodep_vector_at(vec, n)))
+#define nodep_vector_push_back(vec, p) \
+	do \
+	{ \
+		Node *p2 = (Node *) p; \
+		nodep_vector_append(vec, &p2); \
+	} while (0)
+
 /* bool.c */
 extern bool parse_bool(const char *value, bool *result);
 extern bool parse_bool_with_len(const char *value, size_t len, bool *result);
-- 
2.20.1

