Proposed refactoring of planner header files - Mailing list pgsql-hackers

From Tom Lane
Subject Proposed refactoring of planner header files
Date
Msg-id 11460.1548706639@sss.pgh.pa.us
Whole thread Raw
Responses Re: Proposed refactoring of planner header files  (Andres Freund <andres@anarazel.de>)
Re: Proposed refactoring of planner header files  (Robert Haas <robertmhaas@gmail.com>)
Re: Proposed refactoring of planner header files  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-hackers
In <6044.1548524131@sss.pgh.pa.us> I worried about how much planner
stuff that patch might end up dragging into files that contain
planner support functions, and suggested that we could refactor the
planner's header files to reduce the inclusion footprint.  Attached
are some proposed patches to improve the situation.  The work isn't
fully done yet, but I was hoping to get buy-in on this approach
before going further.

The basic idea here is to create a new header file, which I chose
to call optimizer/optimizer.h, and put into it just the stuff that
"outside" callers of the planner might need.  For this purpose
"outside" can be approximated as "doesn't really need to know what
is in relation.h", ie Paths and related data structures.  I expect
that planner support functions will mostly be working with parsetree
data structures for their functions, so they should fit that
restriction.  In some cases they need to be able to pass a PlannerInfo
pointer through to some planner function they want to call, but they
can treat the pointer as an opaque type.  This worked out pretty well,
as I was able to eliminate uses of all other optimizer/ headers (and,
therefore, relation.h) from all but four or five files outside
backend/optimizer/.  The holdouts are mostly places that are pretty
much in bed with the planner anyway, such as statistics/dependencies.c.

I did not attempt to narrow the API used by FDWs, so file_fdw and
postgres_fdw are two of the main places that still need other
optimizer/ headers.  It might be useful to do a similar exercise
focusing on the API seen by FDWs, but that's for another time.

Also, I didn't work on tightening selfuncs.c's dependencies.
While I don't have a big problem with considering selfuncs.c to be
in bed with the planner, that's risky in that whatever dependencies
selfuncs.c has may well apply to extensions' selectivity estimators too.
What I'm thinking about doing there is trying to split selfuncs.c into
two parts, one being infrastructure that can be tightly tied to the
core planner (and, likely, get moved under backend/optimizer/) and the
other being estimators that use a limited API and can serve as models
for extension code.  But I haven't tried to do that yet, and would like
to get the attached committed first.

There are three patches attached:

0001 takes some very trivial support functions out of clauses.c and
puts them into the generic node support headers (nodeFuncs.h and
makefuncs.h) where they arguably should have been all along.  I also
took the opportunity to rename and_clause() and friends into
is_andclause() etc, to make it clearer that they are node-type-testing
functions not node-construction functions, and improved the style a
bit by using "static inline" where practical.

0002 adjusts the API of flatten_join_alias_vars() and some subsidiary
functions so that they take a Query not a PlannerInfo to define the
context they're using for Var transformation.  This makes it greatly
less ugly for parse_agg.c to call that function.  Without this change
it's impossible for parse_agg.c to be decoupled from relation.h.
It likely also saves some tiny number of cycles, by removing one level
of pointer indirection within that processing.

0003 then creates optimizer.h, moves relevant declarations there, and
adjusts #includes as needed.

Since I was intentionally trying to limit what optimizer.h pulls in,
and in particular not let it include relation.h, I needed an opaque
typedef for PlannerInfo.  On the other hand relation.h also needs to
typedef that.  I fixed that with a method that we've not used in our
code AFAIK, but is really common in system headers: there's a #define
symbol to remember whether we've created the typedef, and including
both headers in either order will work fine.

optimizer.h exposes a few of the planner's GUCs, but just the basic
cost parameters, which are likely to be useful to planner support
functions.  Another choice is to expose all of them, but I'm not
sure that's a great idea --- see gripe below for an example of why
that can encourage broken coding.

I intentionally limited 0003 to just do header refactoring, not code
motion, so there are some other follow-on tasks I'm thinking about.
Notably:

I'm really unhappy that force_parallel_mode and
parallel_leader_participation are being treated as planner GUCs.
They are not that, IMO, because they also affect the behavior of
the executor, cf HandleParallelMessage, ExecGather, ExecGatherMerge.
This is somewhere between ill-considered and outright broken: what
happens if the values change between planning and execution?  I think
we probably need to fix things so that those variables do not need to
be looked at by the executor, carrying them forward in the plan
tree if necessary.  Then they'd not need to be exposed by
optimizer.h, and indeed I think the mentioned modules wouldn't
need any optimizer inclusions anymore.

Most everything that's being exposed from tlist.c and var.c could be
argued to be generic parsetree-manipulation support that should be
somewhere else, perhaps backend/nodes/ or backend/parser/.  If we
moved those functions, I think we could get to a place where
backend/parser/ doesn't use any optimizer headers at all, which seems
like a good idea from a modularity standpoint.

Likewise, maybe expand_function_arguments() should be elsewhere.

It seems like evaluate_expr() probably doesn't belong in the planner
at all; it looks like an executor function doesn't it?

It seems possible that cost_qual_eval() should be exposed by
optimizer.h, but to do so we'd need to expose struct QualCost,
which is a creature of relation.h ATM.  Seeing that typedef Cost
is already in nodes.h, maybe it wouldn't be too awful to put
QualCost there too?

I would have exposed estimate_rel_size, which is needed by 
access/hash/hash.c, except that it requires Relation and
BlockNumber typedefs.  The incremental value from keeping
hash.c from using plancat.h probably isn't worth widening
optimizer.h's #include footprint further.  Also, I wonder
whether that whole area needs a rethink for pluggable storage.

Comments?

            regards, tom lane

diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index ae7f038..5d859b7 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -22,6 +22,7 @@
 #include "foreign/fdwapi.h"
 #include "jit/jit.h"
 #include "nodes/extensible.h"
+#include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
 #include "optimizer/clauses.h"
 #include "optimizer/planmain.h"
diff --git a/src/backend/executor/nodeSubplan.c b/src/backend/executor/nodeSubplan.c
index 574e7bc..1526960 100644
--- a/src/backend/executor/nodeSubplan.c
+++ b/src/backend/executor/nodeSubplan.c
@@ -33,8 +33,8 @@
 #include "executor/executor.h"
 #include "executor/nodeSubplan.h"
 #include "nodes/makefuncs.h"
+#include "nodes/nodeFuncs.h"
 #include "miscadmin.h"
-#include "optimizer/clauses.h"
 #include "utils/array.h"
 #include "utils/lsyscache.h"
 #include "utils/memutils.h"
@@ -888,7 +888,7 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent)
             /* single combining operator */
             oplist = list_make1(subplan->testexpr);
         }
-        else if (and_clause((Node *) subplan->testexpr))
+        else if (is_andclause(subplan->testexpr))
         {
             /* multiple combining operators */
             oplist = castNode(BoolExpr, subplan->testexpr)->args;
diff --git a/src/backend/executor/nodeTidscan.c b/src/backend/executor/nodeTidscan.c
index b7a8725..8daf09c 100644
--- a/src/backend/executor/nodeTidscan.c
+++ b/src/backend/executor/nodeTidscan.c
@@ -28,7 +28,7 @@
 #include "executor/execdebug.h"
 #include "executor/nodeTidscan.h"
 #include "miscadmin.h"
-#include "optimizer/clauses.h"
+#include "nodes/nodeFuncs.h"
 #include "storage/bufmgr.h"
 #include "utils/array.h"
 #include "utils/rel.h"
diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c
index 079d016..7085ed2 100644
--- a/src/backend/nodes/makefuncs.c
+++ b/src/backend/nodes/makefuncs.c
@@ -599,6 +599,141 @@ makeFuncCall(List *name, List *args, int location)
 }

 /*
+ * make_opclause
+ *      Creates an operator clause given its operator info, left operand
+ *      and right operand (pass NULL to create single-operand clause),
+ *      and collation info.
+ */
+Expr *
+make_opclause(Oid opno, Oid opresulttype, bool opretset,
+              Expr *leftop, Expr *rightop,
+              Oid opcollid, Oid inputcollid)
+{
+    OpExpr       *expr = makeNode(OpExpr);
+
+    expr->opno = opno;
+    expr->opfuncid = InvalidOid;
+    expr->opresulttype = opresulttype;
+    expr->opretset = opretset;
+    expr->opcollid = opcollid;
+    expr->inputcollid = inputcollid;
+    if (rightop)
+        expr->args = list_make2(leftop, rightop);
+    else
+        expr->args = list_make1(leftop);
+    expr->location = -1;
+    return (Expr *) expr;
+}
+
+/*
+ * make_andclause
+ *
+ * Creates an 'and' clause given a list of its subclauses.
+ */
+Expr *
+make_andclause(List *andclauses)
+{
+    BoolExpr   *expr = makeNode(BoolExpr);
+
+    expr->boolop = AND_EXPR;
+    expr->args = andclauses;
+    expr->location = -1;
+    return (Expr *) expr;
+}
+
+/*
+ * make_orclause
+ *
+ * Creates an 'or' clause given a list of its subclauses.
+ */
+Expr *
+make_orclause(List *orclauses)
+{
+    BoolExpr   *expr = makeNode(BoolExpr);
+
+    expr->boolop = OR_EXPR;
+    expr->args = orclauses;
+    expr->location = -1;
+    return (Expr *) expr;
+}
+
+/*
+ * make_notclause
+ *
+ * Create a 'not' clause given the expression to be negated.
+ */
+Expr *
+make_notclause(Expr *notclause)
+{
+    BoolExpr   *expr = makeNode(BoolExpr);
+
+    expr->boolop = NOT_EXPR;
+    expr->args = list_make1(notclause);
+    expr->location = -1;
+    return (Expr *) expr;
+}
+
+/*
+ * make_and_qual
+ *
+ * Variant of make_andclause for ANDing two qual conditions together.
+ * Qual conditions have the property that a NULL nodetree is interpreted
+ * as 'true'.
+ *
+ * NB: this makes no attempt to preserve AND/OR flatness; so it should not
+ * be used on a qual that has already been run through prepqual.c.
+ */
+Node *
+make_and_qual(Node *qual1, Node *qual2)
+{
+    if (qual1 == NULL)
+        return qual2;
+    if (qual2 == NULL)
+        return qual1;
+    return (Node *) make_andclause(list_make2(qual1, qual2));
+}
+
+/*
+ * The planner and executor usually represent qualification expressions
+ * as lists of boolean expressions with implicit AND semantics.
+ *
+ * These functions convert between an AND-semantics expression list and the
+ * ordinary representation of a boolean expression.
+ *
+ * Note that an empty list is considered equivalent to TRUE.
+ */
+Expr *
+make_ands_explicit(List *andclauses)
+{
+    if (andclauses == NIL)
+        return (Expr *) makeBoolConst(true, false);
+    else if (list_length(andclauses) == 1)
+        return (Expr *) linitial(andclauses);
+    else
+        return make_andclause(andclauses);
+}
+
+List *
+make_ands_implicit(Expr *clause)
+{
+    /*
+     * NB: because the parser sets the qual field to NULL in a query that has
+     * no WHERE clause, we must consider a NULL input clause as TRUE, even
+     * though one might more reasonably think it FALSE.
+     */
+    if (clause == NULL)
+        return NIL;                /* NULL -> NIL list == TRUE */
+    else if (is_andclause(clause))
+        return ((BoolExpr *) clause)->args;
+    else if (IsA(clause, Const) &&
+             !((Const *) clause)->constisnull &&
+             DatumGetBool(((Const *) clause)->constvalue))
+        return NIL;                /* constant TRUE input -> NIL list */
+    else
+        return list_make1(clause);
+}
+
+/*
  * makeGroupingSet
  *
  */
diff --git a/src/backend/nodes/print.c b/src/backend/nodes/print.c
index 0278108..c5b6a0b 100644
--- a/src/backend/nodes/print.c
+++ b/src/backend/nodes/print.c
@@ -21,8 +21,9 @@

 #include "access/printtup.h"
 #include "lib/stringinfo.h"
+#include "nodes/nodeFuncs.h"
 #include "nodes/print.h"
-#include "optimizer/clauses.h"
+#include "nodes/relation.h"
 #include "parser/parsetree.h"
 #include "utils/lsyscache.h"

diff --git a/src/backend/optimizer/path/clausesel.c b/src/backend/optimizer/path/clausesel.c
index 3739b98..5045270 100644
--- a/src/backend/optimizer/path/clausesel.c
+++ b/src/backend/optimizer/path/clausesel.c
@@ -15,6 +15,7 @@
 #include "postgres.h"

 #include "nodes/makefuncs.h"
+#include "nodes/nodeFuncs.h"
 #include "optimizer/clauses.h"
 #include "optimizer/cost.h"
 #include "optimizer/pathnode.h"
@@ -688,7 +689,7 @@ clause_selectivity(PlannerInfo *root,
             /* XXX any way to do better than default? */
         }
     }
-    else if (not_clause(clause))
+    else if (is_notclause(clause))
     {
         /* inverse of the selectivity of the underlying clause */
         s1 = 1.0 - clause_selectivity(root,
@@ -697,7 +698,7 @@ clause_selectivity(PlannerInfo *root,
                                       jointype,
                                       sjinfo);
     }
-    else if (and_clause(clause))
+    else if (is_andclause(clause))
     {
         /* share code with clauselist_selectivity() */
         s1 = clauselist_selectivity(root,
@@ -706,7 +707,7 @@ clause_selectivity(PlannerInfo *root,
                                     jointype,
                                     sjinfo);
     }
-    else if (or_clause(clause))
+    else if (is_orclause(clause))
     {
         /*
          * Selectivities for an OR clause are computed as s1+s2 - s1*s2 to
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index 99c5ad9..e288804 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -79,6 +79,7 @@
 #include "executor/executor.h"
 #include "executor/nodeHash.h"
 #include "miscadmin.h"
+#include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
 #include "optimizer/clauses.h"
 #include "optimizer/cost.h"
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index f8e674c..be50d56 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -1297,7 +1297,7 @@ generate_bitmap_or_paths(PlannerInfo *root, RelOptInfo *rel,
             List       *indlist;

             /* OR arguments should be ANDs or sub-RestrictInfos */
-            if (and_clause(orarg))
+            if (is_andclause(orarg))
             {
                 List       *andargs = ((BoolExpr *) orarg)->args;

@@ -3368,7 +3368,7 @@ match_boolean_index_clause(Node *clause,
     if (match_index_to_operand(clause, indexcol, index))
         return true;
     /* NOT clause? */
-    if (not_clause(clause))
+    if (is_notclause(clause))
     {
         if (match_index_to_operand((Node *) get_notclausearg((Expr *) clause),
                                    indexcol, index))
@@ -3680,7 +3680,7 @@ expand_boolean_index_clause(Node *clause,
                              InvalidOid, InvalidOid);
     }
     /* NOT clause? */
-    if (not_clause(clause))
+    if (is_notclause(clause))
     {
         Node       *arg = (Node *) get_notclausearg((Expr *) clause);

diff --git a/src/backend/optimizer/path/joinrels.c b/src/backend/optimizer/path/joinrels.c
index 8bfe9c3..dfbbfda 100644
--- a/src/backend/optimizer/path/joinrels.c
+++ b/src/backend/optimizer/path/joinrels.c
@@ -15,6 +15,7 @@
 #include "postgres.h"

 #include "miscadmin.h"
+#include "nodes/nodeFuncs.h"
 #include "optimizer/appendinfo.h"
 #include "optimizer/clauses.h"
 #include "optimizer/joininfo.h"
@@ -1554,8 +1555,7 @@ have_partkey_equi_join(RelOptInfo *joinrel,
         if (!rinfo->mergeopfamilies && !OidIsValid(rinfo->hashjoinoperator))
             continue;

-        opexpr = (OpExpr *) rinfo->clause;
-        Assert(is_opclause(opexpr));
+        opexpr = castNode(OpExpr, rinfo->clause);

         /*
          * The equi-join between partition keys is strict if equi-join between
diff --git a/src/backend/optimizer/path/tidpath.c b/src/backend/optimizer/path/tidpath.c
index 74b5a15..94c88bd 100644
--- a/src/backend/optimizer/path/tidpath.c
+++ b/src/backend/optimizer/path/tidpath.c
@@ -250,7 +250,7 @@ TidQualFromRestrictInfoList(List *rlist, RelOptInfo *rel)
                 List       *sublist;

                 /* OR arguments should be ANDs or sub-RestrictInfos */
-                if (and_clause(orarg))
+                if (is_andclause(orarg))
                 {
                     List       *andargs = ((BoolExpr *) orarg)->args;

diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c
index a663740..06ed32a 100644
--- a/src/backend/optimizer/plan/initsplan.c
+++ b/src/backend/optimizer/plan/initsplan.c
@@ -16,6 +16,7 @@

 #include "catalog/pg_type.h"
 #include "catalog/pg_class.h"
+#include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
 #include "optimizer/clauses.h"
 #include "optimizer/cost.h"
diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c
index 64272dd..da65d04 100644
--- a/src/backend/optimizer/plan/subselect.c
+++ b/src/backend/optimizer/plan/subselect.c
@@ -739,7 +739,7 @@ testexpr_is_hashable(Node *testexpr)
         if (hash_ok_operator((OpExpr *) testexpr))
             return true;
     }
-    else if (and_clause(testexpr))
+    else if (is_andclause(testexpr))
     {
         ListCell   *l;

@@ -1694,7 +1694,7 @@ process_sublinks_mutator(Node *node, process_sublinks_context *context)
      * propagates down in both cases.  (Note that this is unlike the meaning
      * of "top level qual" used in most other places in Postgres.)
      */
-    if (and_clause(node))
+    if (is_andclause(node))
     {
         List       *newargs = NIL;
         ListCell   *l;
@@ -1707,7 +1707,7 @@ process_sublinks_mutator(Node *node, process_sublinks_context *context)
             Node       *newarg;

             newarg = process_sublinks_mutator(lfirst(l), &locContext);
-            if (and_clause(newarg))
+            if (is_andclause(newarg))
                 newargs = list_concat(newargs, ((BoolExpr *) newarg)->args);
             else
                 newargs = lappend(newargs, newarg);
@@ -1715,7 +1715,7 @@ process_sublinks_mutator(Node *node, process_sublinks_context *context)
         return (Node *) make_andclause(newargs);
     }

-    if (or_clause(node))
+    if (is_orclause(node))
     {
         List       *newargs = NIL;
         ListCell   *l;
@@ -1728,7 +1728,7 @@ process_sublinks_mutator(Node *node, process_sublinks_context *context)
             Node       *newarg;

             newarg = process_sublinks_mutator(lfirst(l), &locContext);
-            if (or_clause(newarg))
+            if (is_orclause(newarg))
                 newargs = list_concat(newargs, ((BoolExpr *) newarg)->args);
             else
                 newargs = lappend(newargs, newarg);
diff --git a/src/backend/optimizer/prep/prepjointree.c b/src/backend/optimizer/prep/prepjointree.c
index 77dbf4e..3bef60a 100644
--- a/src/backend/optimizer/prep/prepjointree.c
+++ b/src/backend/optimizer/prep/prepjointree.c
@@ -452,7 +452,7 @@ pull_up_sublinks_qual_recurse(PlannerInfo *root, Node *node,
         /* Else return it unmodified */
         return node;
     }
-    if (not_clause(node))
+    if (is_notclause(node))
     {
         /* If the immediate argument of NOT is EXISTS, try to convert */
         SubLink    *sublink = (SubLink *) get_notclausearg((Expr *) node);
@@ -519,7 +519,7 @@ pull_up_sublinks_qual_recurse(PlannerInfo *root, Node *node,
         /* Else return it unmodified */
         return node;
     }
-    if (and_clause(node))
+    if (is_andclause(node))
     {
         /* Recurse into AND clause */
         List       *newclauses = NIL;
diff --git a/src/backend/optimizer/prep/prepqual.c b/src/backend/optimizer/prep/prepqual.c
index 234dc5b..2bd6c20 100644
--- a/src/backend/optimizer/prep/prepqual.c
+++ b/src/backend/optimizer/prep/prepqual.c
@@ -32,6 +32,7 @@
 #include "postgres.h"

 #include "nodes/makefuncs.h"
+#include "nodes/nodeFuncs.h"
 #include "optimizer/clauses.h"
 #include "optimizer/prep.h"
 #include "utils/lsyscache.h"
@@ -333,7 +334,7 @@ pull_ands(List *andlist)
          * built a new arglist not shared with any other expr. Otherwise we'd
          * need a list_copy here.
          */
-        if (and_clause(subexpr))
+        if (is_andclause(subexpr))
             out_list = list_concat(out_list,
                                    pull_ands(((BoolExpr *) subexpr)->args));
         else
@@ -365,7 +366,7 @@ pull_ors(List *orlist)
          * built a new arglist not shared with any other expr. Otherwise we'd
          * need a list_copy here.
          */
-        if (or_clause(subexpr))
+        if (is_orclause(subexpr))
             out_list = list_concat(out_list,
                                    pull_ors(((BoolExpr *) subexpr)->args));
         else
@@ -415,7 +416,7 @@ pull_ors(List *orlist)
 static Expr *
 find_duplicate_ors(Expr *qual, bool is_check)
 {
-    if (or_clause((Node *) qual))
+    if (is_orclause(qual))
     {
         List       *orlist = NIL;
         ListCell   *temp;
@@ -459,7 +460,7 @@ find_duplicate_ors(Expr *qual, bool is_check)
         /* Now we can look for duplicate ORs */
         return process_duplicate_ors(orlist);
     }
-    else if (and_clause((Node *) qual))
+    else if (is_andclause(qual))
     {
         List       *andlist = NIL;
         ListCell   *temp;
@@ -550,7 +551,7 @@ process_duplicate_ors(List *orlist)
     {
         Expr       *clause = (Expr *) lfirst(temp);

-        if (and_clause((Node *) clause))
+        if (is_andclause(clause))
         {
             List       *subclauses = ((BoolExpr *) clause)->args;
             int            nclauses = list_length(subclauses);
@@ -588,7 +589,7 @@ process_duplicate_ors(List *orlist)
         {
             Expr       *clause = (Expr *) lfirst(temp2);

-            if (and_clause((Node *) clause))
+            if (is_andclause(clause))
             {
                 if (!list_member(((BoolExpr *) clause)->args, refclause))
                 {
@@ -631,7 +632,7 @@ process_duplicate_ors(List *orlist)
     {
         Expr       *clause = (Expr *) lfirst(temp);

-        if (and_clause((Node *) clause))
+        if (is_andclause(clause))
         {
             List       *subclauses = ((BoolExpr *) clause)->args;

diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 94b8fa0..816aa86 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -158,244 +158,6 @@ static bool tlist_matches_coltypelist(List *tlist, List *coltypelist);


 /*****************************************************************************
- *        OPERATOR clause functions
- *****************************************************************************/
-
-/*
- * make_opclause
- *      Creates an operator clause given its operator info, left operand
- *      and right operand (pass NULL to create single-operand clause),
- *      and collation info.
- */
-Expr *
-make_opclause(Oid opno, Oid opresulttype, bool opretset,
-              Expr *leftop, Expr *rightop,
-              Oid opcollid, Oid inputcollid)
-{
-    OpExpr       *expr = makeNode(OpExpr);
-
-    expr->opno = opno;
-    expr->opfuncid = InvalidOid;
-    expr->opresulttype = opresulttype;
-    expr->opretset = opretset;
-    expr->opcollid = opcollid;
-    expr->inputcollid = inputcollid;
-    if (rightop)
-        expr->args = list_make2(leftop, rightop);
-    else
-        expr->args = list_make1(leftop);
-    expr->location = -1;
-    return (Expr *) expr;
-}
-
-/*
- * get_leftop
- *
- * Returns the left operand of a clause of the form (op expr expr)
- *        or (op expr)
- */
-Node *
-get_leftop(const Expr *clause)
-{
-    const OpExpr *expr = (const OpExpr *) clause;
-
-    if (expr->args != NIL)
-        return linitial(expr->args);
-    else
-        return NULL;
-}
-
-/*
- * get_rightop
- *
- * Returns the right operand in a clause of the form (op expr expr).
- * NB: result will be NULL if applied to a unary op clause.
- */
-Node *
-get_rightop(const Expr *clause)
-{
-    const OpExpr *expr = (const OpExpr *) clause;
-
-    if (list_length(expr->args) >= 2)
-        return lsecond(expr->args);
-    else
-        return NULL;
-}
-
-/*****************************************************************************
- *        NOT clause functions
- *****************************************************************************/
-
-/*
- * not_clause
- *
- * Returns t iff this is a 'not' clause: (NOT expr).
- */
-bool
-not_clause(Node *clause)
-{
-    return (clause != NULL &&
-            IsA(clause, BoolExpr) &&
-            ((BoolExpr *) clause)->boolop == NOT_EXPR);
-}
-
-/*
- * make_notclause
- *
- * Create a 'not' clause given the expression to be negated.
- */
-Expr *
-make_notclause(Expr *notclause)
-{
-    BoolExpr   *expr = makeNode(BoolExpr);
-
-    expr->boolop = NOT_EXPR;
-    expr->args = list_make1(notclause);
-    expr->location = -1;
-    return (Expr *) expr;
-}
-
-/*
- * get_notclausearg
- *
- * Retrieve the clause within a 'not' clause
- */
-Expr *
-get_notclausearg(Expr *notclause)
-{
-    return linitial(((BoolExpr *) notclause)->args);
-}
-
-/*****************************************************************************
- *        OR clause functions
- *****************************************************************************/
-
-/*
- * or_clause
- *
- * Returns t iff the clause is an 'or' clause: (OR { expr }).
- */
-bool
-or_clause(Node *clause)
-{
-    return (clause != NULL &&
-            IsA(clause, BoolExpr) &&
-            ((BoolExpr *) clause)->boolop == OR_EXPR);
-}
-
-/*
- * make_orclause
- *
- * Creates an 'or' clause given a list of its subclauses.
- */
-Expr *
-make_orclause(List *orclauses)
-{
-    BoolExpr   *expr = makeNode(BoolExpr);
-
-    expr->boolop = OR_EXPR;
-    expr->args = orclauses;
-    expr->location = -1;
-    return (Expr *) expr;
-}
-
-/*****************************************************************************
- *        AND clause functions
- *****************************************************************************/
-
-
-/*
- * and_clause
- *
- * Returns t iff its argument is an 'and' clause: (AND { expr }).
- */
-bool
-and_clause(Node *clause)
-{
-    return (clause != NULL &&
-            IsA(clause, BoolExpr) &&
-            ((BoolExpr *) clause)->boolop == AND_EXPR);
-}
-
-/*
- * make_andclause
- *
- * Creates an 'and' clause given a list of its subclauses.
- */
-Expr *
-make_andclause(List *andclauses)
-{
-    BoolExpr   *expr = makeNode(BoolExpr);
-
-    expr->boolop = AND_EXPR;
-    expr->args = andclauses;
-    expr->location = -1;
-    return (Expr *) expr;
-}
-
-/*
- * make_and_qual
- *
- * Variant of make_andclause for ANDing two qual conditions together.
- * Qual conditions have the property that a NULL nodetree is interpreted
- * as 'true'.
- *
- * NB: this makes no attempt to preserve AND/OR flatness; so it should not
- * be used on a qual that has already been run through prepqual.c.
- */
-Node *
-make_and_qual(Node *qual1, Node *qual2)
-{
-    if (qual1 == NULL)
-        return qual2;
-    if (qual2 == NULL)
-        return qual1;
-    return (Node *) make_andclause(list_make2(qual1, qual2));
-}
-
-/*
- * The planner frequently prefers to represent qualification expressions
- * as lists of boolean expressions with implicit AND semantics.
- *
- * These functions convert between an AND-semantics expression list and the
- * ordinary representation of a boolean expression.
- *
- * Note that an empty list is considered equivalent to TRUE.
- */
-Expr *
-make_ands_explicit(List *andclauses)
-{
-    if (andclauses == NIL)
-        return (Expr *) makeBoolConst(true, false);
-    else if (list_length(andclauses) == 1)
-        return (Expr *) linitial(andclauses);
-    else
-        return make_andclause(andclauses);
-}
-
-List *
-make_ands_implicit(Expr *clause)
-{
-    /*
-     * NB: because the parser sets the qual field to NULL in a query that has
-     * no WHERE clause, we must consider a NULL input clause as TRUE, even
-     * though one might more reasonably think it FALSE.  Grumble. If this
-     * causes trouble, consider changing the parser's behavior.
-     */
-    if (clause == NULL)
-        return NIL;                /* NULL -> NIL list == TRUE */
-    else if (and_clause((Node *) clause))
-        return ((BoolExpr *) clause)->args;
-    else if (IsA(clause, Const) &&
-             !((Const *) clause)->constisnull &&
-             DatumGetBool(((Const *) clause)->constvalue))
-        return NIL;                /* constant TRUE input -> NIL list */
-    else
-        return list_make1(clause);
-}
-
-
-/*****************************************************************************
  *        Aggregate-function clause manipulation
  *****************************************************************************/

@@ -3962,7 +3724,7 @@ simplify_or_arguments(List *args,
         unprocessed_args = list_delete_first(unprocessed_args);

         /* flatten nested ORs as per above comment */
-        if (or_clause(arg))
+        if (is_orclause(arg))
         {
             List       *subargs = list_copy(((BoolExpr *) arg)->args);

@@ -3988,7 +3750,7 @@ simplify_or_arguments(List *args,
          * since it's not a mainstream case. In particular we don't worry
          * about const-simplifying the input twice.
          */
-        if (or_clause(arg))
+        if (is_orclause(arg))
         {
             List       *subargs = list_copy(((BoolExpr *) arg)->args);

@@ -4064,7 +3826,7 @@ simplify_and_arguments(List *args,
         unprocessed_args = list_delete_first(unprocessed_args);

         /* flatten nested ANDs as per above comment */
-        if (and_clause(arg))
+        if (is_andclause(arg))
         {
             List       *subargs = list_copy(((BoolExpr *) arg)->args);

@@ -4090,7 +3852,7 @@ simplify_and_arguments(List *args,
          * since it's not a mainstream case. In particular we don't worry
          * about const-simplifying the input twice.
          */
-        if (and_clause(arg))
+        if (is_andclause(arg))
         {
             List       *subargs = list_copy(((BoolExpr *) arg)->args);

diff --git a/src/backend/optimizer/util/orclauses.c b/src/backend/optimizer/util/orclauses.c
index 9420f13..c62ba88 100644
--- a/src/backend/optimizer/util/orclauses.c
+++ b/src/backend/optimizer/util/orclauses.c
@@ -15,6 +15,8 @@

 #include "postgres.h"

+#include "nodes/makefuncs.h"
+#include "nodes/nodeFuncs.h"
 #include "optimizer/clauses.h"
 #include "optimizer/cost.h"
 #include "optimizer/orclauses.h"
@@ -173,7 +175,7 @@ extract_or_clause(RestrictInfo *or_rinfo, RelOptInfo *rel)
      * selectivity and other cached data is computed exactly the same way for
      * a restriction clause as for a join clause, which seems undesirable.
      */
-    Assert(or_clause((Node *) or_rinfo->orclause));
+    Assert(is_orclause(or_rinfo->orclause));
     foreach(lc, ((BoolExpr *) or_rinfo->orclause)->args)
     {
         Node       *orarg = (Node *) lfirst(lc);
@@ -181,7 +183,7 @@ extract_or_clause(RestrictInfo *or_rinfo, RelOptInfo *rel)
         Node       *subclause;

         /* OR arguments should be ANDs or sub-RestrictInfos */
-        if (and_clause(orarg))
+        if (is_andclause(orarg))
         {
             List       *andargs = ((BoolExpr *) orarg)->args;
             ListCell   *lc2;
@@ -231,7 +233,7 @@ extract_or_clause(RestrictInfo *or_rinfo, RelOptInfo *rel)
          * to preserve AND/OR flatness (ie, no OR directly underneath OR).
          */
         subclause = (Node *) make_ands_explicit(subclauses);
-        if (or_clause(subclause))
+        if (is_orclause(subclause))
             clauselist = list_concat(clauselist,
                                      list_copy(((BoolExpr *) subclause)->args));
         else
diff --git a/src/backend/optimizer/util/predtest.c b/src/backend/optimizer/util/predtest.c
index 3d5ef69..ecbb0db 100644
--- a/src/backend/optimizer/util/predtest.c
+++ b/src/backend/optimizer/util/predtest.c
@@ -19,6 +19,7 @@
 #include "catalog/pg_type.h"
 #include "executor/executor.h"
 #include "miscadmin.h"
+#include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
 #include "optimizer/clauses.h"
 #include "optimizer/predtest.h"
@@ -839,14 +840,14 @@ predicate_classify(Node *clause, PredIterInfo info)
     }

     /* Handle normal AND and OR boolean clauses */
-    if (and_clause(clause))
+    if (is_andclause(clause))
     {
         info->startup_fn = boolexpr_startup_fn;
         info->next_fn = list_next_fn;
         info->cleanup_fn = list_cleanup_fn;
         return CLASS_AND;
     }
-    if (or_clause(clause))
+    if (is_orclause(clause))
     {
         info->startup_fn = boolexpr_startup_fn;
         info->next_fn = list_next_fn;
diff --git a/src/backend/optimizer/util/restrictinfo.c b/src/backend/optimizer/util/restrictinfo.c
index e633881..c1bda81 100644
--- a/src/backend/optimizer/util/restrictinfo.c
+++ b/src/backend/optimizer/util/restrictinfo.c
@@ -14,6 +14,8 @@
  */
 #include "postgres.h"

+#include "nodes/makefuncs.h"
+#include "nodes/nodeFuncs.h"
 #include "optimizer/clauses.h"
 #include "optimizer/restrictinfo.h"
 #include "optimizer/var.h"
@@ -67,7 +69,7 @@ make_restrictinfo(Expr *clause,
      * If it's an OR clause, build a modified copy with RestrictInfos inserted
      * above each subclause of the top-level AND/OR structure.
      */
-    if (or_clause((Node *) clause))
+    if (is_orclause(clause))
         return (RestrictInfo *) make_sub_restrictinfos(clause,
                                                        is_pushed_down,
                                                        outerjoin_delayed,
@@ -78,7 +80,7 @@ make_restrictinfo(Expr *clause,
                                                        nullable_relids);

     /* Shouldn't be an AND clause, else AND/OR flattening messed up */
-    Assert(!and_clause((Node *) clause));
+    Assert(!is_andclause(clause));

     return make_restrictinfo_internal(clause,
                                       NULL,
@@ -232,7 +234,7 @@ make_sub_restrictinfos(Expr *clause,
                        Relids outer_relids,
                        Relids nullable_relids)
 {
-    if (or_clause((Node *) clause))
+    if (is_orclause(clause))
     {
         List       *orlist = NIL;
         ListCell   *temp;
@@ -257,7 +259,7 @@ make_sub_restrictinfos(Expr *clause,
                                                    outer_relids,
                                                    nullable_relids);
     }
-    else if (and_clause((Node *) clause))
+    else if (is_andclause(clause))
     {
         List       *andlist = NIL;
         ListCell   *temp;
diff --git a/src/backend/partitioning/partprune.c b/src/backend/partitioning/partprune.c
index 901433c..f5155fe 100644
--- a/src/backend/partitioning/partprune.c
+++ b/src/backend/partitioning/partprune.c
@@ -775,7 +775,7 @@ gen_partprune_steps_internal(GeneratePruningStepsContext *context,
              * independently, collect their step IDs to be stored in the
              * combine step we'll be creating.
              */
-            if (or_clause((Node *) clause))
+            if (is_orclause(clause))
             {
                 List       *arg_stepids = NIL;
                 bool        all_args_contradictory = true;
@@ -865,7 +865,7 @@ gen_partprune_steps_internal(GeneratePruningStepsContext *context,
                 }
                 continue;
             }
-            else if (and_clause((Node *) clause))
+            else if (is_andclause(clause))
             {
                 List       *args = ((BoolExpr *) clause)->args;
                 List       *argsteps,
@@ -3262,7 +3262,7 @@ match_boolean_partition_clause(Oid partopfamily, Expr *clause, Expr *partkey,
     }
     else
     {
-        bool        is_not_clause = not_clause((Node *) clause);
+        bool        is_not_clause = is_notclause(clause);

         leftop = is_not_clause ? get_notclausearg(clause) : clause;

diff --git a/src/backend/statistics/dependencies.c b/src/backend/statistics/dependencies.c
index 1d7e028..a8e9f72 100644
--- a/src/backend/statistics/dependencies.c
+++ b/src/backend/statistics/dependencies.c
@@ -18,6 +18,7 @@
 #include "catalog/pg_operator.h"
 #include "catalog/pg_statistic_ext.h"
 #include "lib/stringinfo.h"
+#include "nodes/nodeFuncs.h"
 #include "optimizer/clauses.h"
 #include "optimizer/cost.h"
 #include "optimizer/var.h"
@@ -802,7 +803,7 @@ dependency_is_compatible_clause(Node *clause, Index relid, AttrNumber *attnum)

         /* OK to proceed with checking "var" */
     }
-    else if (not_clause((Node *) rinfo->clause))
+    else if (is_notclause(rinfo->clause))
     {
         /*
          * "NOT x" can be interpreted as "x = false", so get the argument and
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index bcf4f10..12bba1b 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -69,6 +69,7 @@
 #include "commands/policy.h"
 #include "commands/trigger.h"
 #include "miscadmin.h"
+#include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
 #include "optimizer/clauses.h"
 #include "optimizer/prep.h"
diff --git a/src/include/nodes/makefuncs.h b/src/include/nodes/makefuncs.h
index 5b5aa2d..aa25fab 100644
--- a/src/include/nodes/makefuncs.h
+++ b/src/include/nodes/makefuncs.h
@@ -80,6 +80,18 @@ extern FuncExpr *makeFuncExpr(Oid funcid, Oid rettype, List *args,

 extern FuncCall *makeFuncCall(List *name, List *args, int location);

+extern Expr *make_opclause(Oid opno, Oid opresulttype, bool opretset,
+              Expr *leftop, Expr *rightop,
+              Oid opcollid, Oid inputcollid);
+
+extern Expr *make_andclause(List *andclauses);
+extern Expr *make_orclause(List *orclauses);
+extern Expr *make_notclause(Expr *notclause);
+
+extern Node *make_and_qual(Node *qual1, Node *qual2);
+extern Expr *make_ands_explicit(List *andclauses);
+extern List *make_ands_implicit(Expr *clause);
+
 extern DefElem *makeDefElem(char *name, Node *arg, int location);
 extern DefElem *makeDefElemExtended(char *nameSpace, char *name, Node *arg,
                     DefElemAction defaction, int location);
diff --git a/src/include/nodes/nodeFuncs.h b/src/include/nodes/nodeFuncs.h
index a9f76bb..9875934 100644
--- a/src/include/nodes/nodeFuncs.h
+++ b/src/include/nodes/nodeFuncs.h
@@ -50,6 +50,78 @@ extern void fix_opfuncids(Node *node);
 extern void set_opfuncid(OpExpr *opexpr);
 extern void set_sa_opfuncid(ScalarArrayOpExpr *opexpr);

+/* Is clause a FuncExpr clause? */
+static inline bool
+is_funcclause(const void *clause)
+{
+    return clause != NULL && IsA(clause, FuncExpr);
+}
+
+/* Is clause an OpExpr clause? */
+static inline bool
+is_opclause(const void *clause)
+{
+    return clause != NULL && IsA(clause, OpExpr);
+}
+
+/* Extract left arg of a binary opclause, or only arg of a unary opclause */
+static inline Node *
+get_leftop(const void *clause)
+{
+    const OpExpr *expr = (const OpExpr *) clause;
+
+    if (expr->args != NIL)
+        return (Node *) linitial(expr->args);
+    else
+        return NULL;
+}
+
+/* Extract right arg of a binary opclause (NULL if it's a unary opclause) */
+static inline Node *
+get_rightop(const void *clause)
+{
+    const OpExpr *expr = (const OpExpr *) clause;
+
+    if (list_length(expr->args) >= 2)
+        return (Node *) lsecond(expr->args);
+    else
+        return NULL;
+}
+
+/* Is clause an AND clause? */
+static inline bool
+is_andclause(const void *clause)
+{
+    return (clause != NULL &&
+            IsA(clause, BoolExpr) &&
+            ((const BoolExpr *) clause)->boolop == AND_EXPR);
+}
+
+/* Is clause an OR clause? */
+static inline bool
+is_orclause(const void *clause)
+{
+    return (clause != NULL &&
+            IsA(clause, BoolExpr) &&
+            ((const BoolExpr *) clause)->boolop == OR_EXPR);
+}
+
+/* Is clause a NOT clause? */
+static inline bool
+is_notclause(const void *clause)
+{
+    return (clause != NULL &&
+            IsA(clause, BoolExpr) &&
+            ((const BoolExpr *) clause)->boolop == NOT_EXPR);
+}
+
+/* Extract argument from a clause known to be a NOT clause */
+static inline Expr *
+get_notclausearg(const void *notclause)
+{
+    return (Expr *) linitial(((const BoolExpr *) notclause)->args);
+}
+
 extern bool check_functions_in_node(Node *node, check_function_callback checker,
                         void *context);

diff --git a/src/include/optimizer/clauses.h b/src/include/optimizer/clauses.h
index 6891d0d..3f53428 100644
--- a/src/include/optimizer/clauses.h
+++ b/src/include/optimizer/clauses.h
@@ -17,9 +17,6 @@
 #include "access/htup.h"
 #include "nodes/relation.h"

-#define is_opclause(clause)        ((clause) != NULL && IsA(clause, OpExpr))
-#define is_funcclause(clause)    ((clause) != NULL && IsA(clause, FuncExpr))
-
 typedef struct
 {
     int            numWindowFuncs; /* total number of WindowFuncs found */
@@ -27,25 +24,6 @@ typedef struct
     List      **windowFuncs;    /* lists of WindowFuncs for each winref */
 } WindowFuncLists;

-extern Expr *make_opclause(Oid opno, Oid opresulttype, bool opretset,
-              Expr *leftop, Expr *rightop,
-              Oid opcollid, Oid inputcollid);
-extern Node *get_leftop(const Expr *clause);
-extern Node *get_rightop(const Expr *clause);
-
-extern bool not_clause(Node *clause);
-extern Expr *make_notclause(Expr *notclause);
-extern Expr *get_notclausearg(Expr *notclause);
-
-extern bool or_clause(Node *clause);
-extern Expr *make_orclause(List *orclauses);
-
-extern bool and_clause(Node *clause);
-extern Expr *make_andclause(List *andclauses);
-extern Node *make_and_qual(Node *qual1, Node *qual2);
-extern Expr *make_ands_explicit(List *andclauses);
-extern List *make_ands_implicit(Expr *clause);
-
 extern bool contain_agg_clause(Node *clause);
 extern void get_agg_clause_costs(PlannerInfo *root, Node *clause,
                      AggSplit aggsplit, AggClauseCosts *costs);
diff --git a/src/test/modules/test_predtest/test_predtest.c b/src/test/modules/test_predtest/test_predtest.c
index 6c9ed9d..c03748c 100644
--- a/src/test/modules/test_predtest/test_predtest.c
+++ b/src/test/modules/test_predtest/test_predtest.c
@@ -17,6 +17,7 @@
 #include "catalog/pg_type.h"
 #include "executor/spi.h"
 #include "funcapi.h"
+#include "nodes/makefuncs.h"
 #include "optimizer/clauses.h"
 #include "optimizer/predtest.h"
 #include "utils/builtins.h"
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 4465f00..3304edb 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -836,7 +836,8 @@ subquery_planner(PlannerGlobal *glob, Query *parse,
              */
             if (rte->lateral && root->hasJoinRTEs)
                 rte->subquery = (Query *)
-                    flatten_join_alias_vars(root, (Node *) rte->subquery);
+                    flatten_join_alias_vars(root->parse,
+                                            (Node *) rte->subquery);
         }
         else if (rte->rtekind == RTE_FUNCTION)
         {
@@ -1033,7 +1034,7 @@ preprocess_expression(PlannerInfo *root, Node *expr, int kind)
           kind == EXPRKIND_VALUES ||
           kind == EXPRKIND_TABLESAMPLE ||
           kind == EXPRKIND_TABLEFUNC))
-        expr = flatten_join_alias_vars(root, expr);
+        expr = flatten_join_alias_vars(root->parse, expr);

     /*
      * Simplify constant expressions.
diff --git a/src/backend/optimizer/prep/prepjointree.c b/src/backend/optimizer/prep/prepjointree.c
index 3bef60a..1f993d4 100644
--- a/src/backend/optimizer/prep/prepjointree.c
+++ b/src/backend/optimizer/prep/prepjointree.c
@@ -986,7 +986,7 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte,
      * maybe even in the rewriter; but for now let's just fix this case here.)
      */
     subquery->targetList = (List *)
-        flatten_join_alias_vars(subroot, (Node *) subquery->targetList);
+        flatten_join_alias_vars(subroot->parse, (Node *) subquery->targetList);

     /*
      * Adjust level-0 varnos in subquery so that we can append its rangetable
@@ -3031,11 +3031,11 @@ get_relids_in_jointree(Node *jtnode, bool include_joins)
  * get_relids_for_join: get set of base RT indexes making up a join
  */
 Relids
-get_relids_for_join(PlannerInfo *root, int joinrelid)
+get_relids_for_join(Query *query, int joinrelid)
 {
     Node       *jtnode;

-    jtnode = find_jointree_node_for_rel((Node *) root->parse->jointree,
+    jtnode = find_jointree_node_for_rel((Node *) query->jointree,
                                         joinrelid);
     if (!jtnode)
         elog(ERROR, "could not find join node %d", joinrelid);
diff --git a/src/backend/optimizer/util/var.c b/src/backend/optimizer/util/var.c
index 48175b7..5116d7f 100644
--- a/src/backend/optimizer/util/var.c
+++ b/src/backend/optimizer/util/var.c
@@ -60,7 +60,7 @@ typedef struct

 typedef struct
 {
-    PlannerInfo *root;
+    Query       *query;            /* outer Query */
     int            sublevels_up;
     bool        possible_sublink;    /* could aliases include a SubLink? */
     bool        inserted_sublink;    /* have we inserted a SubLink? */
@@ -78,7 +78,7 @@ static bool pull_var_clause_walker(Node *node,
                        pull_var_clause_context *context);
 static Node *flatten_join_alias_vars_mutator(Node *node,
                                 flatten_join_alias_vars_context *context);
-static Relids alias_relid_set(PlannerInfo *root, Relids relids);
+static Relids alias_relid_set(Query *query, Relids relids);


 /*
@@ -667,16 +667,16 @@ pull_var_clause_walker(Node *node, pull_var_clause_context *context)
  * subqueries).
  */
 Node *
-flatten_join_alias_vars(PlannerInfo *root, Node *node)
+flatten_join_alias_vars(Query *query, Node *node)
 {
     flatten_join_alias_vars_context context;

-    context.root = root;
+    context.query = query;
     context.sublevels_up = 0;
     /* flag whether join aliases could possibly contain SubLinks */
-    context.possible_sublink = root->parse->hasSubLinks;
+    context.possible_sublink = query->hasSubLinks;
     /* if hasSubLinks is already true, no need to work hard */
-    context.inserted_sublink = root->parse->hasSubLinks;
+    context.inserted_sublink = query->hasSubLinks;

     return flatten_join_alias_vars_mutator(node, &context);
 }
@@ -696,7 +696,7 @@ flatten_join_alias_vars_mutator(Node *node,
         /* No change unless Var belongs to a JOIN of the target level */
         if (var->varlevelsup != context->sublevels_up)
             return node;        /* no need to copy, really */
-        rte = rt_fetch(var->varno, context->root->parse->rtable);
+        rte = rt_fetch(var->varno, context->query->rtable);
         if (rte->rtekind != RTE_JOIN)
             return node;
         if (var->varattno == InvalidAttrNumber)
@@ -783,7 +783,7 @@ flatten_join_alias_vars_mutator(Node *node,
         /* now fix PlaceHolderVar's relid sets */
         if (phv->phlevelsup == context->sublevels_up)
         {
-            phv->phrels = alias_relid_set(context->root,
+            phv->phrels = alias_relid_set(context->query,
                                           phv->phrels);
         }
         return (Node *) phv;
@@ -823,7 +823,7 @@ flatten_join_alias_vars_mutator(Node *node,
  * underlying base relids
  */
 static Relids
-alias_relid_set(PlannerInfo *root, Relids relids)
+alias_relid_set(Query *query, Relids relids)
 {
     Relids        result = NULL;
     int            rtindex;
@@ -831,10 +831,10 @@ alias_relid_set(PlannerInfo *root, Relids relids)
     rtindex = -1;
     while ((rtindex = bms_next_member(relids, rtindex)) >= 0)
     {
-        RangeTblEntry *rte = rt_fetch(rtindex, root->parse->rtable);
+        RangeTblEntry *rte = rt_fetch(rtindex, query->rtable);

         if (rte->rtekind == RTE_JOIN)
-            result = bms_join(result, get_relids_for_join(root, rtindex));
+            result = bms_join(result, get_relids_for_join(query, rtindex));
         else
             result = bms_add_member(result, rtindex);
     }
diff --git a/src/backend/parser/parse_agg.c b/src/backend/parser/parse_agg.c
index 8ed3816..5b73378 100644
--- a/src/backend/parser/parse_agg.c
+++ b/src/backend/parser/parse_agg.c
@@ -43,7 +43,7 @@ typedef struct
 {
     ParseState *pstate;
     Query       *qry;
-    PlannerInfo *root;
+    bool        hasJoinRTEs;
     List       *groupClauses;
     List       *groupClauseCommonVars;
     bool        have_non_var_grouping;
@@ -65,7 +65,7 @@ static void check_ungrouped_columns(Node *node, ParseState *pstate, Query *qry,
 static bool check_ungrouped_columns_walker(Node *node,
                                check_ungrouped_columns_context *context);
 static void finalize_grouping_exprs(Node *node, ParseState *pstate, Query *qry,
-                        List *groupClauses, PlannerInfo *root,
+                        List *groupClauses, bool hasJoinRTEs,
                         bool have_non_var_grouping);
 static bool finalize_grouping_exprs_walker(Node *node,
                                check_ungrouped_columns_context *context);
@@ -1039,7 +1039,6 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
     ListCell   *l;
     bool        hasJoinRTEs;
     bool        hasSelfRefRTEs;
-    PlannerInfo *root = NULL;
     Node       *clause;

     /* This should only be called if we found aggregates or grouping */
@@ -1130,20 +1129,11 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
      * If there are join alias vars involved, we have to flatten them to the
      * underlying vars, so that aliased and unaliased vars will be correctly
      * taken as equal.  We can skip the expense of doing this if no rangetable
-     * entries are RTE_JOIN kind. We use the planner's flatten_join_alias_vars
-     * routine to do the flattening; it wants a PlannerInfo root node, which
-     * fortunately can be mostly dummy.
+     * entries are RTE_JOIN kind.
      */
     if (hasJoinRTEs)
-    {
-        root = makeNode(PlannerInfo);
-        root->parse = qry;
-        root->planner_cxt = CurrentMemoryContext;
-        root->hasJoinRTEs = true;
-
-        groupClauses = (List *) flatten_join_alias_vars(root,
+        groupClauses = (List *) flatten_join_alias_vars(qry,
                                                         (Node *) groupClauses);
-    }

     /*
      * Detect whether any of the grouping expressions aren't simple Vars; if
@@ -1183,10 +1173,10 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
      */
     clause = (Node *) qry->targetList;
     finalize_grouping_exprs(clause, pstate, qry,
-                            groupClauses, root,
+                            groupClauses, hasJoinRTEs,
                             have_non_var_grouping);
     if (hasJoinRTEs)
-        clause = flatten_join_alias_vars(root, clause);
+        clause = flatten_join_alias_vars(qry, clause);
     check_ungrouped_columns(clause, pstate, qry,
                             groupClauses, groupClauseCommonVars,
                             have_non_var_grouping,
@@ -1194,10 +1184,10 @@ parseCheckAggregates(ParseState *pstate, Query *qry)

     clause = (Node *) qry->havingQual;
     finalize_grouping_exprs(clause, pstate, qry,
-                            groupClauses, root,
+                            groupClauses, hasJoinRTEs,
                             have_non_var_grouping);
     if (hasJoinRTEs)
-        clause = flatten_join_alias_vars(root, clause);
+        clause = flatten_join_alias_vars(qry, clause);
     check_ungrouped_columns(clause, pstate, qry,
                             groupClauses, groupClauseCommonVars,
                             have_non_var_grouping,
@@ -1245,7 +1235,7 @@ check_ungrouped_columns(Node *node, ParseState *pstate, Query *qry,

     context.pstate = pstate;
     context.qry = qry;
-    context.root = NULL;
+    context.hasJoinRTEs = false;    /* assume caller flattened join Vars */
     context.groupClauses = groupClauses;
     context.groupClauseCommonVars = groupClauseCommonVars;
     context.have_non_var_grouping = have_non_var_grouping;
@@ -1445,14 +1435,14 @@ check_ungrouped_columns_walker(Node *node,
  */
 static void
 finalize_grouping_exprs(Node *node, ParseState *pstate, Query *qry,
-                        List *groupClauses, PlannerInfo *root,
+                        List *groupClauses, bool hasJoinRTEs,
                         bool have_non_var_grouping)
 {
     check_ungrouped_columns_context context;

     context.pstate = pstate;
     context.qry = qry;
-    context.root = root;
+    context.hasJoinRTEs = hasJoinRTEs;
     context.groupClauses = groupClauses;
     context.groupClauseCommonVars = NIL;
     context.have_non_var_grouping = have_non_var_grouping;
@@ -1525,8 +1515,8 @@ finalize_grouping_exprs_walker(Node *node,
                 Node       *expr = lfirst(lc);
                 Index        ref = 0;

-                if (context->root)
-                    expr = flatten_join_alias_vars(context->root, expr);
+                if (context->hasJoinRTEs)
+                    expr = flatten_join_alias_vars(context->qry, expr);

                 /*
                  * Each expression must match a grouping entry at the current
diff --git a/src/include/optimizer/prep.h b/src/include/optimizer/prep.h
index 62d45dd..3ad8dcb 100644
--- a/src/include/optimizer/prep.h
+++ b/src/include/optimizer/prep.h
@@ -27,7 +27,7 @@ extern void pull_up_subqueries(PlannerInfo *root);
 extern void flatten_simple_union_all(PlannerInfo *root);
 extern void reduce_outer_joins(PlannerInfo *root);
 extern Relids get_relids_in_jointree(Node *jtnode, bool include_joins);
-extern Relids get_relids_for_join(PlannerInfo *root, int joinrelid);
+extern Relids get_relids_for_join(Query *query, int joinrelid);

 /*
  * prototypes for prepqual.c
diff --git a/src/include/optimizer/var.h b/src/include/optimizer/var.h
index a0c1387..f975074 100644
--- a/src/include/optimizer/var.h
+++ b/src/include/optimizer/var.h
@@ -35,6 +35,6 @@ extern bool contain_var_clause(Node *node);
 extern bool contain_vars_of_level(Node *node, int levelsup);
 extern int    locate_var_of_level(Node *node, int levelsup);
 extern List *pull_var_clause(Node *node, int flags);
-extern Node *flatten_join_alias_vars(PlannerInfo *root, Node *node);
+extern Node *flatten_join_alias_vars(Query *query, Node *node);

 #endif                            /* VAR_H */
diff --git a/contrib/bloom/blcost.c b/contrib/bloom/blcost.c
index 902d23e..2d8a7f1 100644
--- a/contrib/bloom/blcost.c
+++ b/contrib/bloom/blcost.c
@@ -13,7 +13,6 @@
 #include "postgres.h"

 #include "fmgr.h"
-#include "optimizer/cost.h"
 #include "utils/selfuncs.h"

 #include "bloom.h"
diff --git a/contrib/file_fdw/file_fdw.c b/contrib/file_fdw/file_fdw.c
index e7db83d..be626be 100644
--- a/contrib/file_fdw/file_fdw.c
+++ b/contrib/file_fdw/file_fdw.c
@@ -29,11 +29,10 @@
 #include "foreign/foreign.h"
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
-#include "optimizer/cost.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/pathnode.h"
 #include "optimizer/planmain.h"
 #include "optimizer/restrictinfo.h"
-#include "optimizer/var.h"
 #include "utils/memutils.h"
 #include "utils/rel.h"
 #include "utils/sampling.h"
diff --git a/contrib/postgres_fdw/deparse.c b/contrib/postgres_fdw/deparse.c
index f368d4b..b0e44e5 100644
--- a/contrib/postgres_fdw/deparse.c
+++ b/contrib/postgres_fdw/deparse.c
@@ -48,10 +48,9 @@
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
 #include "nodes/plannodes.h"
-#include "optimizer/clauses.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/prep.h"
 #include "optimizer/tlist.h"
-#include "optimizer/var.h"
 #include "parser/parsetree.h"
 #include "utils/builtins.h"
 #include "utils/lsyscache.h"
diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c
index 9244fe7..f753fff 100644
--- a/contrib/postgres_fdw/postgres_fdw.c
+++ b/contrib/postgres_fdw/postgres_fdw.c
@@ -28,11 +28,11 @@
 #include "nodes/nodeFuncs.h"
 #include "optimizer/cost.h"
 #include "optimizer/clauses.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/pathnode.h"
 #include "optimizer/paths.h"
 #include "optimizer/planmain.h"
 #include "optimizer/restrictinfo.h"
-#include "optimizer/var.h"
 #include "optimizer/tlist.h"
 #include "parser/parsetree.h"
 #include "utils/builtins.h"
diff --git a/contrib/tsm_system_rows/tsm_system_rows.c b/contrib/tsm_system_rows/tsm_system_rows.c
index 69944f6..c92490f 100644
--- a/contrib/tsm_system_rows/tsm_system_rows.c
+++ b/contrib/tsm_system_rows/tsm_system_rows.c
@@ -33,8 +33,7 @@
 #include "access/tsmapi.h"
 #include "catalog/pg_type.h"
 #include "miscadmin.h"
-#include "optimizer/clauses.h"
-#include "optimizer/cost.h"
+#include "optimizer/optimizer.h"
 #include "utils/sampling.h"

 PG_MODULE_MAGIC;
diff --git a/contrib/tsm_system_time/tsm_system_time.c b/contrib/tsm_system_time/tsm_system_time.c
index f516552..edeacf0 100644
--- a/contrib/tsm_system_time/tsm_system_time.c
+++ b/contrib/tsm_system_time/tsm_system_time.c
@@ -31,8 +31,7 @@
 #include "access/tsmapi.h"
 #include "catalog/pg_type.h"
 #include "miscadmin.h"
-#include "optimizer/clauses.h"
-#include "optimizer/cost.h"
+#include "optimizer/optimizer.h"
 #include "utils/sampling.h"
 #include "utils/spccache.h"

diff --git a/src/backend/access/gist/gistbuild.c b/src/backend/access/gist/gistbuild.c
index 94463ff..bd142a3 100644
--- a/src/backend/access/gist/gistbuild.c
+++ b/src/backend/access/gist/gistbuild.c
@@ -22,7 +22,7 @@
 #include "access/xloginsert.h"
 #include "catalog/index.h"
 #include "miscadmin.h"
-#include "optimizer/cost.h"
+#include "optimizer/optimizer.h"
 #include "storage/bufmgr.h"
 #include "storage/smgr.h"
 #include "utils/memutils.h"
diff --git a/src/backend/access/spgist/spgutils.c b/src/backend/access/spgist/spgutils.c
index de147d7..8e63c1f 100644
--- a/src/backend/access/spgist/spgutils.c
+++ b/src/backend/access/spgist/spgutils.c
@@ -22,7 +22,6 @@
 #include "access/transam.h"
 #include "access/xact.h"
 #include "catalog/pg_amop.h"
-#include "optimizer/paths.h"
 #include "storage/bufmgr.h"
 #include "storage/indexfsm.h"
 #include "storage/lmgr.h"
@@ -32,9 +31,6 @@
 #include "utils/lsyscache.h"
 #include "utils/syscache.h"

-extern Expr *spgcanorderbyop(IndexOptInfo *index,
-                PathKey *pathkey, int pathkeyno,
-                Expr *orderby_clause, int *indexcol_p);

 /*
  * SP-GiST handler function: return IndexAmRoutine with access method parameters
diff --git a/src/backend/access/tablesample/bernoulli.c b/src/backend/access/tablesample/bernoulli.c
index 5e5e32d..9360b5b 100644
--- a/src/backend/access/tablesample/bernoulli.c
+++ b/src/backend/access/tablesample/bernoulli.c
@@ -29,8 +29,7 @@
 #include "access/hash.h"
 #include "access/tsmapi.h"
 #include "catalog/pg_type.h"
-#include "optimizer/clauses.h"
-#include "optimizer/cost.h"
+#include "optimizer/optimizer.h"
 #include "utils/builtins.h"


diff --git a/src/backend/access/tablesample/system.c b/src/backend/access/tablesample/system.c
index 383387b..298e0ab 100644
--- a/src/backend/access/tablesample/system.c
+++ b/src/backend/access/tablesample/system.c
@@ -31,8 +31,7 @@
 #include "access/relscan.h"
 #include "access/tsmapi.h"
 #include "catalog/pg_type.h"
-#include "optimizer/clauses.h"
-#include "optimizer/cost.h"
+#include "optimizer/optimizer.h"
 #include "utils/builtins.h"


diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c
index 9c55c20..ce2b616 100644
--- a/src/backend/access/transam/parallel.c
+++ b/src/backend/access/transam/parallel.c
@@ -28,7 +28,7 @@
 #include "libpq/pqformat.h"
 #include "libpq/pqmq.h"
 #include "miscadmin.h"
-#include "optimizer/planmain.h"
+#include "optimizer/optimizer.h"
 #include "pgstat.h"
 #include "storage/ipc.h"
 #include "storage/sinval.h"
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index cc865de..910f651 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -64,9 +64,7 @@
 #include "executor/executor.h"
 #include "miscadmin.h"
 #include "nodes/nodeFuncs.h"
-#include "optimizer/clauses.h"
-#include "optimizer/var.h"
-#include "optimizer/planner.h"
+#include "optimizer/optimizer.h"
 #include "parser/parse_coerce.h"
 #include "parser/parse_collate.h"
 #include "parser/parse_expr.h"
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 225c078..169b2de 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -56,8 +56,7 @@
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
-#include "optimizer/clauses.h"
-#include "optimizer/planner.h"
+#include "optimizer/optimizer.h"
 #include "parser/parser.h"
 #include "rewrite/rewriteManip.h"
 #include "storage/bufmgr.h"
diff --git a/src/backend/catalog/partition.c b/src/backend/catalog/partition.c
index 62d1ec6..0d3bc3a 100644
--- a/src/backend/catalog/partition.c
+++ b/src/backend/catalog/partition.c
@@ -24,9 +24,7 @@
 #include "catalog/pg_inherits.h"
 #include "catalog/pg_partitioned_table.h"
 #include "nodes/makefuncs.h"
-#include "optimizer/clauses.h"
-#include "optimizer/prep.h"
-#include "optimizer/var.h"
+#include "optimizer/optimizer.h"
 #include "partitioning/partbounds.h"
 #include "rewrite/rewriteManip.h"
 #include "utils/fmgroids.h"
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index ec1d6b6..a74af4c 100644
--- a/src/backend/commands/cluster.c
+++ b/src/backend/commands/cluster.c
@@ -38,7 +38,7 @@
 #include "commands/tablecmds.h"
 #include "commands/vacuum.h"
 #include "miscadmin.h"
-#include "optimizer/planner.h"
+#include "optimizer/optimizer.h"
 #include "storage/bufmgr.h"
 #include "storage/lmgr.h"
 #include "storage/predicate.h"
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index 1c90934..86f2bf3 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -37,9 +37,7 @@
 #include "libpq/pqformat.h"
 #include "mb/pg_wchar.h"
 #include "miscadmin.h"
-#include "optimizer/clauses.h"
-#include "optimizer/planner.h"
-#include "optimizer/prep.h"
+#include "optimizer/optimizer.h"
 #include "nodes/makefuncs.h"
 #include "parser/parse_coerce.h"
 #include "parser/parse_collate.h"
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index 5d859b7..1831ea8 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -24,8 +24,6 @@
 #include "nodes/extensible.h"
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
-#include "optimizer/clauses.h"
-#include "optimizer/planmain.h"
 #include "parser/parsetree.h"
 #include "rewrite/rewriteHandler.h"
 #include "storage/bufmgr.h"
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index ac40168..9a2f1a8 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -54,8 +54,7 @@
 #include "executor/executor.h"
 #include "funcapi.h"
 #include "miscadmin.h"
-#include "optimizer/clauses.h"
-#include "optimizer/var.h"
+#include "optimizer/optimizer.h"
 #include "parser/parse_coerce.h"
 #include "parser/parse_collate.h"
 #include "parser/parse_expr.h"
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 5b2b8d2..bd85099 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -42,9 +42,7 @@
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
-#include "optimizer/clauses.h"
-#include "optimizer/planner.h"
-#include "optimizer/var.h"
+#include "optimizer/optimizer.h"
 #include "parser/parse_coerce.h"
 #include "parser/parse_func.h"
 #include "parser/parse_oper.h"
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index ff76499..434be40 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -63,11 +63,7 @@
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
 #include "nodes/parsenodes.h"
-#include "optimizer/clauses.h"
-#include "optimizer/planner.h"
-#include "optimizer/predtest.h"
-#include "optimizer/prep.h"
-#include "optimizer/var.h"
+#include "optimizer/optimizer.h"
 #include "parser/parse_clause.h"
 #include "parser/parse_coerce.h"
 #include "parser/parse_collate.h"
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 499030c..7b5896b 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -36,8 +36,7 @@
 #include "miscadmin.h"
 #include "nodes/bitmapset.h"
 #include "nodes/makefuncs.h"
-#include "optimizer/clauses.h"
-#include "optimizer/var.h"
+#include "optimizer/optimizer.h"
 #include "parser/parse_clause.h"
 #include "parser/parse_collate.h"
 #include "parser/parse_func.h"
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 35a6485..fa7161e 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -56,7 +56,7 @@
 #include "executor/executor.h"
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
-#include "optimizer/var.h"
+#include "optimizer/optimizer.h"
 #include "parser/parse_coerce.h"
 #include "parser/parse_collate.h"
 #include "parser/parse_expr.h"
diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c
index 2e061a5..e52b806 100644
--- a/src/backend/executor/execExpr.c
+++ b/src/backend/executor/execExpr.c
@@ -40,8 +40,7 @@
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
-#include "optimizer/clauses.h"
-#include "optimizer/planner.h"
+#include "optimizer/optimizer.h"
 #include "pgstat.h"
 #include "utils/builtins.h"
 #include "utils/datum.h"
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 5975c52..9a20460 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -52,7 +52,6 @@
 #include "jit/jit.h"
 #include "mb/pg_wchar.h"
 #include "miscadmin.h"
-#include "optimizer/clauses.h"
 #include "parser/parsetree.h"
 #include "rewrite/rewriteManip.h"
 #include "storage/bufmgr.h"
diff --git a/src/backend/executor/execParallel.c b/src/backend/executor/execParallel.c
index ceea3d6..b79be91 100644
--- a/src/backend/executor/execParallel.c
+++ b/src/backend/executor/execParallel.c
@@ -39,8 +39,6 @@
 #include "executor/tqueue.h"
 #include "jit/jit.h"
 #include "nodes/nodeFuncs.h"
-#include "optimizer/planmain.h"
-#include "optimizer/planner.h"
 #include "storage/spin.h"
 #include "tcop/tcopprot.h"
 #include "utils/datum.h"
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index 2a260a7..263a0f8 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -226,8 +226,7 @@
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
-#include "optimizer/clauses.h"
-#include "optimizer/tlist.h"
+#include "optimizer/optimizer.h"
 #include "parser/parse_agg.h"
 #include "parser/parse_coerce.h"
 #include "utils/acl.h"
diff --git a/src/backend/executor/nodeGather.c b/src/backend/executor/nodeGather.c
index 70a4e90..69d5a1f 100644
--- a/src/backend/executor/nodeGather.c
+++ b/src/backend/executor/nodeGather.c
@@ -38,7 +38,7 @@
 #include "executor/nodeSubplan.h"
 #include "executor/tqueue.h"
 #include "miscadmin.h"
-#include "optimizer/planmain.h"
+#include "optimizer/optimizer.h"
 #include "pgstat.h"
 #include "utils/memutils.h"
 #include "utils/rel.h"
diff --git a/src/backend/executor/nodeGatherMerge.c b/src/backend/executor/nodeGatherMerge.c
index 8635865..4de1d2b 100644
--- a/src/backend/executor/nodeGatherMerge.c
+++ b/src/backend/executor/nodeGatherMerge.c
@@ -23,7 +23,7 @@
 #include "executor/tqueue.h"
 #include "lib/binaryheap.h"
 #include "miscadmin.h"
-#include "optimizer/planmain.h"
+#include "optimizer/optimizer.h"
 #include "utils/memutils.h"
 #include "utils/rel.h"

diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c
index cdf1ad0..324356e 100644
--- a/src/backend/executor/nodeIndexscan.c
+++ b/src/backend/executor/nodeIndexscan.c
@@ -37,7 +37,6 @@
 #include "lib/pairingheap.h"
 #include "miscadmin.h"
 #include "nodes/nodeFuncs.h"
-#include "optimizer/clauses.h"
 #include "utils/array.h"
 #include "utils/datum.h"
 #include "utils/lsyscache.h"
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index 731391f..157ac04 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -41,7 +41,7 @@
 #include "executor/nodeWindowAgg.h"
 #include "miscadmin.h"
 #include "nodes/nodeFuncs.h"
-#include "optimizer/clauses.h"
+#include "optimizer/optimizer.h"
 #include "parser/parse_agg.h"
 #include "parser/parse_coerce.h"
 #include "utils/acl.h"
diff --git a/src/backend/jit/llvm/llvmjit_expr.c b/src/backend/jit/llvm/llvmjit_expr.c
index 351f6ec..df7e620 100644
--- a/src/backend/jit/llvm/llvmjit_expr.c
+++ b/src/backend/jit/llvm/llvmjit_expr.c
@@ -33,7 +33,6 @@
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
-#include "optimizer/planner.h"
 #include "parser/parse_coerce.h"
 #include "parser/parsetree.h"
 #include "pgstat.h"
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index e1ecfd6..72dcb12 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -35,13 +35,13 @@
 #include "optimizer/cost.h"
 #include "optimizer/geqo.h"
 #include "optimizer/inherit.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/pathnode.h"
 #include "optimizer/paths.h"
 #include "optimizer/plancat.h"
 #include "optimizer/planner.h"
 #include "optimizer/restrictinfo.h"
 #include "optimizer/tlist.h"
-#include "optimizer/var.h"
 #include "parser/parse_clause.h"
 #include "parser/parsetree.h"
 #include "partitioning/partprune.h"
diff --git a/src/backend/optimizer/path/clausesel.c b/src/backend/optimizer/path/clausesel.c
index 5045270..abca03b 100644
--- a/src/backend/optimizer/path/clausesel.c
+++ b/src/backend/optimizer/path/clausesel.c
@@ -18,6 +18,7 @@
 #include "nodes/nodeFuncs.h"
 #include "optimizer/clauses.h"
 #include "optimizer/cost.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/pathnode.h"
 #include "optimizer/plancat.h"
 #include "utils/fmgroids.h"
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index e288804..6c53f12 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -83,6 +83,7 @@
 #include "nodes/nodeFuncs.h"
 #include "optimizer/clauses.h"
 #include "optimizer/cost.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/pathnode.h"
 #include "optimizer/paths.h"
 #include "optimizer/placeholder.h"
diff --git a/src/backend/optimizer/path/equivclass.c b/src/backend/optimizer/path/equivclass.c
index 6e134ae..3454f12 100644
--- a/src/backend/optimizer/path/equivclass.c
+++ b/src/backend/optimizer/path/equivclass.c
@@ -24,11 +24,11 @@
 #include "nodes/nodeFuncs.h"
 #include "optimizer/appendinfo.h"
 #include "optimizer/clauses.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/pathnode.h"
 #include "optimizer/paths.h"
 #include "optimizer/planmain.h"
 #include "optimizer/restrictinfo.h"
-#include "optimizer/var.h"
 #include "utils/lsyscache.h"


diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index be50d56..7e1a390 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -28,12 +28,11 @@
 #include "nodes/nodeFuncs.h"
 #include "optimizer/clauses.h"
 #include "optimizer/cost.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/pathnode.h"
 #include "optimizer/paths.h"
-#include "optimizer/predtest.h"
 #include "optimizer/prep.h"
 #include "optimizer/restrictinfo.h"
-#include "optimizer/var.h"
 #include "utils/builtins.h"
 #include "utils/bytea.h"
 #include "utils/lsyscache.h"
diff --git a/src/backend/optimizer/path/pathkeys.c b/src/backend/optimizer/path/pathkeys.c
index 9dac50e..56d839b 100644
--- a/src/backend/optimizer/path/pathkeys.c
+++ b/src/backend/optimizer/path/pathkeys.c
@@ -21,10 +21,9 @@
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
 #include "nodes/plannodes.h"
-#include "optimizer/clauses.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/pathnode.h"
 #include "optimizer/paths.h"
-#include "optimizer/tlist.h"
 #include "utils/lsyscache.h"


diff --git a/src/backend/optimizer/path/tidpath.c b/src/backend/optimizer/path/tidpath.c
index 94c88bd..466e996 100644
--- a/src/backend/optimizer/path/tidpath.c
+++ b/src/backend/optimizer/path/tidpath.c
@@ -40,10 +40,10 @@
 #include "catalog/pg_type.h"
 #include "nodes/nodeFuncs.h"
 #include "optimizer/clauses.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/pathnode.h"
 #include "optimizer/paths.h"
 #include "optimizer/restrictinfo.h"
-#include "optimizer/var.h"


 /*
diff --git a/src/backend/optimizer/plan/analyzejoins.c b/src/backend/optimizer/plan/analyzejoins.c
index 1593dbe..a4efa69 100644
--- a/src/backend/optimizer/plan/analyzejoins.c
+++ b/src/backend/optimizer/plan/analyzejoins.c
@@ -25,11 +25,11 @@
 #include "nodes/nodeFuncs.h"
 #include "optimizer/clauses.h"
 #include "optimizer/joininfo.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/pathnode.h"
 #include "optimizer/paths.h"
 #include "optimizer/planmain.h"
 #include "optimizer/tlist.h"
-#include "optimizer/var.h"
 #include "utils/lsyscache.h"

 /* local functions */
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 97d0c28..5656e10 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -28,16 +28,15 @@
 #include "nodes/nodeFuncs.h"
 #include "optimizer/clauses.h"
 #include "optimizer/cost.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/paramassign.h"
 #include "optimizer/paths.h"
 #include "optimizer/placeholder.h"
 #include "optimizer/plancat.h"
 #include "optimizer/planmain.h"
-#include "optimizer/predtest.h"
 #include "optimizer/restrictinfo.h"
 #include "optimizer/subselect.h"
 #include "optimizer/tlist.h"
-#include "optimizer/var.h"
 #include "parser/parse_clause.h"
 #include "parser/parsetree.h"
 #include "partitioning/partprune.h"
diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c
index 06ed32a..501bc00 100644
--- a/src/backend/optimizer/plan/initsplan.c
+++ b/src/backend/optimizer/plan/initsplan.c
@@ -21,6 +21,7 @@
 #include "optimizer/clauses.h"
 #include "optimizer/cost.h"
 #include "optimizer/joininfo.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/pathnode.h"
 #include "optimizer/paths.h"
 #include "optimizer/placeholder.h"
@@ -28,7 +29,6 @@
 #include "optimizer/planner.h"
 #include "optimizer/prep.h"
 #include "optimizer/restrictinfo.h"
-#include "optimizer/var.h"
 #include "parser/analyze.h"
 #include "rewrite/rewriteManip.h"
 #include "utils/lsyscache.h"
diff --git a/src/backend/optimizer/plan/planagg.c b/src/backend/optimizer/plan/planagg.c
index d98cb89..8661709 100644
--- a/src/backend/optimizer/plan/planagg.c
+++ b/src/backend/optimizer/plan/planagg.c
@@ -35,6 +35,7 @@
 #include "nodes/nodeFuncs.h"
 #include "optimizer/clauses.h"
 #include "optimizer/cost.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/pathnode.h"
 #include "optimizer/paths.h"
 #include "optimizer/planmain.h"
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 3304edb..d5a2fd2 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -43,6 +43,7 @@
 #include "optimizer/clauses.h"
 #include "optimizer/cost.h"
 #include "optimizer/inherit.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/paramassign.h"
 #include "optimizer/pathnode.h"
 #include "optimizer/paths.h"
@@ -52,7 +53,6 @@
 #include "optimizer/prep.h"
 #include "optimizer/subselect.h"
 #include "optimizer/tlist.h"
-#include "optimizer/var.h"
 #include "parser/analyze.h"
 #include "parser/parsetree.h"
 #include "parser/parse_agg.h"
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c
index 6bd3b2d..0213a37 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -19,6 +19,7 @@
 #include "catalog/pg_type.h"
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/pathnode.h"
 #include "optimizer/planmain.h"
 #include "optimizer/planner.h"
diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c
index da65d04..a998b9b 100644
--- a/src/backend/optimizer/plan/subselect.c
+++ b/src/backend/optimizer/plan/subselect.c
@@ -25,13 +25,13 @@
 #include "nodes/nodeFuncs.h"
 #include "optimizer/clauses.h"
 #include "optimizer/cost.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/paramassign.h"
 #include "optimizer/pathnode.h"
 #include "optimizer/planmain.h"
 #include "optimizer/planner.h"
 #include "optimizer/prep.h"
 #include "optimizer/subselect.h"
-#include "optimizer/var.h"
 #include "parser/parse_relation.h"
 #include "rewrite/rewriteManip.h"
 #include "utils/builtins.h"
diff --git a/src/backend/optimizer/prep/prepjointree.c b/src/backend/optimizer/prep/prepjointree.c
index 1f993d4..bfcdc7c 100644
--- a/src/backend/optimizer/prep/prepjointree.c
+++ b/src/backend/optimizer/prep/prepjointree.c
@@ -27,11 +27,11 @@
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
 #include "optimizer/clauses.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/placeholder.h"
 #include "optimizer/prep.h"
 #include "optimizer/subselect.h"
 #include "optimizer/tlist.h"
-#include "optimizer/var.h"
 #include "parser/parse_relation.h"
 #include "parser/parsetree.h"
 #include "rewrite/rewriteManip.h"
diff --git a/src/backend/optimizer/prep/prepqual.c b/src/backend/optimizer/prep/prepqual.c
index 2bd6c20..e9a9497 100644
--- a/src/backend/optimizer/prep/prepqual.c
+++ b/src/backend/optimizer/prep/prepqual.c
@@ -33,7 +33,7 @@

 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
-#include "optimizer/clauses.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/prep.h"
 #include "utils/lsyscache.h"

diff --git a/src/backend/optimizer/prep/preptlist.c b/src/backend/optimizer/prep/preptlist.c
index 0e045f1..5392d1a 100644
--- a/src/backend/optimizer/prep/preptlist.c
+++ b/src/backend/optimizer/prep/preptlist.c
@@ -44,9 +44,9 @@
 #include "access/table.h"
 #include "catalog/pg_type.h"
 #include "nodes/makefuncs.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/prep.h"
 #include "optimizer/tlist.h"
-#include "optimizer/var.h"
 #include "parser/parsetree.h"
 #include "parser/parse_coerce.h"
 #include "rewrite/rewriteHandler.h"
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 816aa86..841a257 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -34,9 +34,9 @@
 #include "nodes/nodeFuncs.h"
 #include "optimizer/clauses.h"
 #include "optimizer/cost.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/planmain.h"
 #include "optimizer/prep.h"
-#include "optimizer/var.h"
 #include "parser/analyze.h"
 #include "parser/parse_agg.h"
 #include "parser/parse_coerce.h"
diff --git a/src/backend/optimizer/util/orclauses.c b/src/backend/optimizer/util/orclauses.c
index c62ba88..b671581 100644
--- a/src/backend/optimizer/util/orclauses.c
+++ b/src/backend/optimizer/util/orclauses.c
@@ -19,6 +19,7 @@
 #include "nodes/nodeFuncs.h"
 #include "optimizer/clauses.h"
 #include "optimizer/cost.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/orclauses.h"
 #include "optimizer/restrictinfo.h"

diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c
index b2637d0..257f0bf 100644
--- a/src/backend/optimizer/util/pathnode.c
+++ b/src/backend/optimizer/util/pathnode.c
@@ -23,13 +23,13 @@
 #include "optimizer/appendinfo.h"
 #include "optimizer/clauses.h"
 #include "optimizer/cost.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/pathnode.h"
 #include "optimizer/paths.h"
 #include "optimizer/planmain.h"
 #include "optimizer/prep.h"
 #include "optimizer/restrictinfo.h"
 #include "optimizer/tlist.h"
-#include "optimizer/var.h"
 #include "parser/parsetree.h"
 #include "utils/lsyscache.h"
 #include "utils/memutils.h"
diff --git a/src/backend/optimizer/util/placeholder.c b/src/backend/optimizer/util/placeholder.c
index b24478e..798aa8c 100644
--- a/src/backend/optimizer/util/placeholder.c
+++ b/src/backend/optimizer/util/placeholder.c
@@ -17,10 +17,10 @@

 #include "nodes/nodeFuncs.h"
 #include "optimizer/cost.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/pathnode.h"
 #include "optimizer/placeholder.h"
 #include "optimizer/planmain.h"
-#include "optimizer/var.h"
 #include "utils/lsyscache.h"

 /* Local functions */
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index 261492e..cb7f6f9 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -35,8 +35,8 @@
 #include "nodes/makefuncs.h"
 #include "optimizer/clauses.h"
 #include "optimizer/cost.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/plancat.h"
-#include "optimizer/predtest.h"
 #include "optimizer/prep.h"
 #include "partitioning/partbounds.h"
 #include "parser/parse_relation.h"
diff --git a/src/backend/optimizer/util/predtest.c b/src/backend/optimizer/util/predtest.c
index ecbb0db..3b260b1 100644
--- a/src/backend/optimizer/util/predtest.c
+++ b/src/backend/optimizer/util/predtest.c
@@ -21,8 +21,8 @@
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
-#include "optimizer/clauses.h"
-#include "optimizer/predtest.h"
+#include "nodes/relation.h"
+#include "optimizer/optimizer.h"
 #include "utils/array.h"
 #include "utils/inval.h"
 #include "utils/lsyscache.h"
diff --git a/src/backend/optimizer/util/restrictinfo.c b/src/backend/optimizer/util/restrictinfo.c
index c1bda81..1c47c70 100644
--- a/src/backend/optimizer/util/restrictinfo.c
+++ b/src/backend/optimizer/util/restrictinfo.c
@@ -17,8 +17,8 @@
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
 #include "optimizer/clauses.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/restrictinfo.h"
-#include "optimizer/var.h"


 static RestrictInfo *make_restrictinfo_internal(Expr *clause,
diff --git a/src/backend/optimizer/util/tlist.c b/src/backend/optimizer/util/tlist.c
index d0cc14f..14d1c67 100644
--- a/src/backend/optimizer/util/tlist.c
+++ b/src/backend/optimizer/util/tlist.c
@@ -17,6 +17,7 @@
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
 #include "optimizer/cost.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/tlist.h"


diff --git a/src/backend/optimizer/util/var.c b/src/backend/optimizer/util/var.c
index 5116d7f..315c81e 100644
--- a/src/backend/optimizer/util/var.c
+++ b/src/backend/optimizer/util/var.c
@@ -22,8 +22,8 @@

 #include "access/sysattr.h"
 #include "nodes/nodeFuncs.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/prep.h"
-#include "optimizer/var.h"
 #include "parser/parsetree.h"
 #include "rewrite/rewriteManip.h"

diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index 8f96558..f8dd8ac 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -29,7 +29,7 @@
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
-#include "optimizer/var.h"
+#include "optimizer/optimizer.h"
 #include "parser/analyze.h"
 #include "parser/parse_agg.h"
 #include "parser/parse_clause.h"
diff --git a/src/backend/parser/parse_agg.c b/src/backend/parser/parse_agg.c
index 5b73378..183ea0f 100644
--- a/src/backend/parser/parse_agg.c
+++ b/src/backend/parser/parse_agg.c
@@ -19,8 +19,7 @@
 #include "catalog/pg_type.h"
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
-#include "optimizer/tlist.h"
-#include "optimizer/var.h"
+#include "optimizer/optimizer.h"
 #include "parser/parse_agg.h"
 #include "parser/parse_clause.h"
 #include "parser/parse_coerce.h"
diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c
index 8805543..c6ce101 100644
--- a/src/backend/parser/parse_clause.c
+++ b/src/backend/parser/parse_clause.c
@@ -31,8 +31,7 @@
 #include "commands/defrem.h"
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
-#include "optimizer/tlist.h"
-#include "optimizer/var.h"
+#include "optimizer/optimizer.h"
 #include "parser/analyze.h"
 #include "parser/parsetree.h"
 #include "parser/parser.h"
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 3e0a762..7fc8d63 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -20,8 +20,7 @@
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
-#include "optimizer/tlist.h"
-#include "optimizer/var.h"
+#include "optimizer/optimizer.h"
 #include "parser/analyze.h"
 #include "parser/parse_clause.h"
 #include "parser/parse_coerce.h"
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index 445e81a..a37d1f1 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -50,9 +50,7 @@
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
-#include "optimizer/clauses.h"
-#include "optimizer/planner.h"
-#include "optimizer/var.h"
+#include "optimizer/optimizer.h"
 #include "parser/analyze.h"
 #include "parser/parse_clause.h"
 #include "parser/parse_coerce.h"
diff --git a/src/backend/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c
index f21c9b3..d478ae7 100644
--- a/src/backend/partitioning/partbounds.c
+++ b/src/backend/partitioning/partbounds.c
@@ -22,7 +22,6 @@
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
-#include "optimizer/clauses.h"
 #include "parser/parse_coerce.h"
 #include "partitioning/partprune.h"
 #include "partitioning/partbounds.h"
diff --git a/src/backend/partitioning/partprune.c b/src/backend/partitioning/partprune.c
index f5155fe..8c97219 100644
--- a/src/backend/partitioning/partprune.c
+++ b/src/backend/partitioning/partprune.c
@@ -45,12 +45,8 @@
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
 #include "optimizer/appendinfo.h"
-#include "optimizer/clauses.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/pathnode.h"
-#include "optimizer/planner.h"
-#include "optimizer/predtest.h"
-#include "optimizer/prep.h"
-#include "optimizer/var.h"
 #include "partitioning/partprune.h"
 #include "partitioning/partbounds.h"
 #include "rewrite/rewriteManip.h"
diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c
index 2c49c71..f951651 100644
--- a/src/backend/replication/logical/worker.c
+++ b/src/backend/replication/logical/worker.c
@@ -23,61 +23,46 @@

 #include "postgres.h"

-#include "miscadmin.h"
-#include "pgstat.h"
-#include "funcapi.h"
-
 #include "access/table.h"
 #include "access/xact.h"
 #include "access/xlog_internal.h"
-
 #include "catalog/catalog.h"
 #include "catalog/namespace.h"
 #include "catalog/pg_subscription.h"
 #include "catalog/pg_subscription_rel.h"
-
 #include "commands/tablecmds.h"
 #include "commands/trigger.h"
-
 #include "executor/executor.h"
 #include "executor/nodeModifyTable.h"
-
+#include "funcapi.h"
 #include "libpq/pqformat.h"
 #include "libpq/pqsignal.h"
-
 #include "mb/pg_wchar.h"
-
+#include "miscadmin.h"
 #include "nodes/makefuncs.h"
-
-#include "optimizer/planner.h"
-
+#include "optimizer/optimizer.h"
 #include "parser/parse_relation.h"
-
+#include "pgstat.h"
 #include "postmaster/bgworker.h"
 #include "postmaster/postmaster.h"
 #include "postmaster/walwriter.h"
-
 #include "replication/decode.h"
 #include "replication/logical.h"
 #include "replication/logicalproto.h"
 #include "replication/logicalrelation.h"
 #include "replication/logicalworker.h"
-#include "replication/reorderbuffer.h"
 #include "replication/origin.h"
+#include "replication/reorderbuffer.h"
 #include "replication/snapbuild.h"
 #include "replication/walreceiver.h"
 #include "replication/worker_internal.h"
-
 #include "rewrite/rewriteHandler.h"
-
 #include "storage/bufmgr.h"
 #include "storage/ipc.h"
 #include "storage/lmgr.h"
 #include "storage/proc.h"
 #include "storage/procarray.h"
-
 #include "tcop/tcopprot.h"
-
 #include "utils/builtins.h"
 #include "utils/catcache.h"
 #include "utils/datum.h"
@@ -87,8 +72,8 @@
 #include "utils/lsyscache.h"
 #include "utils/memutils.h"
 #include "utils/rel.h"
-#include "utils/timeout.h"
 #include "utils/syscache.h"
+#include "utils/timeout.h"

 #define NAPTIME_PER_CYCLE 1000    /* max sleep time between cycles (1s) */

diff --git a/src/backend/rewrite/rewriteManip.c b/src/backend/rewrite/rewriteManip.c
index fd7a751..57aee3d 100644
--- a/src/backend/rewrite/rewriteManip.c
+++ b/src/backend/rewrite/rewriteManip.c
@@ -17,7 +17,7 @@
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
 #include "nodes/plannodes.h"
-#include "optimizer/clauses.h"
+#include "nodes/relation.h"
 #include "parser/parse_coerce.h"
 #include "parser/parse_relation.h"
 #include "parser/parsetree.h"
diff --git a/src/backend/statistics/dependencies.c b/src/backend/statistics/dependencies.c
index a8e9f72..13492ce 100644
--- a/src/backend/statistics/dependencies.c
+++ b/src/backend/statistics/dependencies.c
@@ -20,8 +20,7 @@
 #include "lib/stringinfo.h"
 #include "nodes/nodeFuncs.h"
 #include "optimizer/clauses.h"
-#include "optimizer/cost.h"
-#include "optimizer/var.h"
+#include "optimizer/optimizer.h"
 #include "nodes/nodes.h"
 #include "nodes/relation.h"
 #include "statistics/extended_stats_internal.h"
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index e773f20..36cfd50 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -49,7 +49,7 @@
 #include "libpq/pqsignal.h"
 #include "miscadmin.h"
 #include "nodes/print.h"
-#include "optimizer/planner.h"
+#include "optimizer/optimizer.h"
 #include "pgstat.h"
 #include "pg_trace.h"
 #include "parser/analyze.h"
diff --git a/src/backend/utils/adt/array_selfuncs.c b/src/backend/utils/adt/array_selfuncs.c
index ad1201a..870131b 100644
--- a/src/backend/utils/adt/array_selfuncs.c
+++ b/src/backend/utils/adt/array_selfuncs.c
@@ -20,7 +20,6 @@
 #include "catalog/pg_collation.h"
 #include "catalog/pg_operator.h"
 #include "catalog/pg_statistic.h"
-#include "optimizer/clauses.h"
 #include "utils/array.h"
 #include "utils/builtins.h"
 #include "utils/lsyscache.h"
diff --git a/src/backend/utils/adt/orderedsetaggs.c b/src/backend/utils/adt/orderedsetaggs.c
index 6075bc3..2d384a9 100644
--- a/src/backend/utils/adt/orderedsetaggs.c
+++ b/src/backend/utils/adt/orderedsetaggs.c
@@ -22,7 +22,7 @@
 #include "executor/executor.h"
 #include "miscadmin.h"
 #include "nodes/nodeFuncs.h"
-#include "optimizer/tlist.h"
+#include "optimizer/optimizer.h"
 #include "utils/array.h"
 #include "utils/builtins.h"
 #include "utils/lsyscache.h"
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 302df16..09bc7e6 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -49,7 +49,7 @@
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
-#include "optimizer/tlist.h"
+#include "optimizer/optimizer.h"
 #include "parser/parse_node.h"
 #include "parser/parse_agg.h"
 #include "parser/parse_func.h"
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index 4af8c80..fb00504 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -121,12 +121,11 @@
 #include "nodes/nodeFuncs.h"
 #include "optimizer/clauses.h"
 #include "optimizer/cost.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/pathnode.h"
 #include "optimizer/paths.h"
 #include "optimizer/plancat.h"
-#include "optimizer/predtest.h"
 #include "optimizer/restrictinfo.h"
-#include "optimizer/var.h"
 #include "parser/parse_clause.h"
 #include "parser/parse_coerce.h"
 #include "parser/parsetree.h"
diff --git a/src/backend/utils/cache/partcache.c b/src/backend/utils/cache/partcache.c
index 2404073..1b50f28 100644
--- a/src/backend/utils/cache/partcache.c
+++ b/src/backend/utils/cache/partcache.c
@@ -25,8 +25,7 @@
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
-#include "optimizer/clauses.h"
-#include "optimizer/planner.h"
+#include "optimizer/optimizer.h"
 #include "partitioning/partbounds.h"
 #include "utils/builtins.h"
 #include "utils/datum.h"
diff --git a/src/backend/utils/cache/plancache.c b/src/backend/utils/cache/plancache.c
index 3f46b5d..9851bd4 100644
--- a/src/backend/utils/cache/plancache.c
+++ b/src/backend/utils/cache/plancache.c
@@ -61,10 +61,7 @@
 #include "executor/executor.h"
 #include "miscadmin.h"
 #include "nodes/nodeFuncs.h"
-#include "optimizer/cost.h"
-#include "optimizer/planmain.h"
-#include "optimizer/planner.h"
-#include "optimizer/prep.h"
+#include "optimizer/optimizer.h"
 #include "parser/analyze.h"
 #include "parser/parsetree.h"
 #include "storage/lmgr.h"
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 12bba1b..af96a03 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -71,9 +71,7 @@
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
-#include "optimizer/clauses.h"
-#include "optimizer/prep.h"
-#include "optimizer/var.h"
+#include "optimizer/optimizer.h"
 #include "partitioning/partbounds.h"
 #include "rewrite/rewriteDefine.h"
 #include "rewrite/rowsecurity.h"
diff --git a/src/backend/utils/cache/spccache.c b/src/backend/utils/cache/spccache.c
index 1d0c16b..6309a01 100644
--- a/src/backend/utils/cache/spccache.c
+++ b/src/backend/utils/cache/spccache.c
@@ -22,7 +22,7 @@
 #include "catalog/pg_tablespace.h"
 #include "commands/tablespace.h"
 #include "miscadmin.h"
-#include "optimizer/cost.h"
+#include "optimizer/optimizer.h"
 #include "storage/bufmgr.h"
 #include "utils/catcache.h"
 #include "utils/hsearch.h"
diff --git a/src/backend/utils/cache/typcache.c b/src/backend/utils/cache/typcache.c
index 2fb7dd3..7857424 100644
--- a/src/backend/utils/cache/typcache.c
+++ b/src/backend/utils/cache/typcache.c
@@ -59,7 +59,7 @@
 #include "commands/defrem.h"
 #include "executor/executor.h"
 #include "lib/dshash.h"
-#include "optimizer/planner.h"
+#include "optimizer/optimizer.h"
 #include "storage/lwlock.h"
 #include "utils/builtins.h"
 #include "utils/catcache.h"
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index c216ed0..98d75be 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -50,6 +50,7 @@
 #include "miscadmin.h"
 #include "optimizer/cost.h"
 #include "optimizer/geqo.h"
+#include "optimizer/optimizer.h"
 #include "optimizer/paths.h"
 #include "optimizer/planmain.h"
 #include "parser/parse_expr.h"
diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h
index 3430061..366b0a6 100644
--- a/src/include/nodes/relation.h
+++ b/src/include/nodes/relation.h
@@ -159,11 +159,17 @@ typedef struct PlannerGlobal
  * It holds links to all of the planner's working state, in addition to the
  * original Query.  Note that at present the planner extensively modifies
  * the passed-in Query data structure; someday that should stop.
+ *
+ * For reasons explained in optimizer/optimizer.h, we define the typedef
+ * either here or in that header, whichever is read first.
  *----------
  */
-struct AppendRelInfo;
+#ifndef HAVE_PLANNERINFO_TYPEDEF
+typedef struct PlannerInfo PlannerInfo;
+#define HAVE_PLANNERINFO_TYPEDEF 1
+#endif

-typedef struct PlannerInfo
+struct PlannerInfo
 {
     NodeTag        type;

@@ -173,7 +179,7 @@ typedef struct PlannerInfo

     Index        query_level;    /* 1 at the outermost Query */

-    struct PlannerInfo *parent_root;    /* NULL at outermost Query */
+    PlannerInfo *parent_root;    /* NULL at outermost Query */

     /*
      * plan_params contains the expressions that this query level needs to
@@ -343,7 +349,7 @@ typedef struct PlannerInfo

     /* Does this query modify any partition key columns? */
     bool        partColsUpdated;
-} PlannerInfo;
+};


 /*
@@ -2066,8 +2072,12 @@ typedef struct PlaceHolderVar
  * plain innerjoin semantics.  Note that lhs_strict, delay_upper_joins, and
  * of course the semi_xxx fields are not set meaningfully within such structs.
  */
+#ifndef HAVE_SPECIALJOININFO_TYPEDEF
+typedef struct SpecialJoinInfo SpecialJoinInfo;
+#define HAVE_SPECIALJOININFO_TYPEDEF 1
+#endif

-typedef struct SpecialJoinInfo
+struct SpecialJoinInfo
 {
     NodeTag        type;
     Relids        min_lefthand;    /* base relids in minimum LHS for join */
@@ -2082,7 +2092,7 @@ typedef struct SpecialJoinInfo
     bool        semi_can_hash;    /* true if semi_operators are all hash */
     List       *semi_operators; /* OIDs of equality join operators */
     List       *semi_rhs_exprs; /* righthand-side expressions of these ops */
-} SpecialJoinInfo;
+};

 /*
  * Append-relation info.
diff --git a/src/include/optimizer/clauses.h b/src/include/optimizer/clauses.h
index 3f53428..cfedd42 100644
--- a/src/include/optimizer/clauses.h
+++ b/src/include/optimizer/clauses.h
@@ -35,9 +35,6 @@ extern double expression_returns_set_rows(Node *clause);

 extern bool contain_subplans(Node *clause);

-extern bool contain_mutable_functions(Node *clause);
-extern bool contain_volatile_functions(Node *clause);
-extern bool contain_volatile_functions_not_nextval(Node *clause);
 extern char max_parallel_hazard(Query *parse);
 extern bool is_parallel_safe(PlannerInfo *root, Node *node);
 extern bool contain_nonstrict_functions(Node *clause);
@@ -56,17 +53,7 @@ extern int    NumRelids(Node *clause);
 extern void CommuteOpExpr(OpExpr *clause);
 extern void CommuteRowCompareExpr(RowCompareExpr *clause);

-extern Node *eval_const_expressions(PlannerInfo *root, Node *node);
-
-extern Node *estimate_expression_value(PlannerInfo *root, Node *node);
-
-extern Expr *evaluate_expr(Expr *expr, Oid result_type, int32 result_typmod,
-                           Oid result_collation);
-
 extern Query *inline_set_returning_function(PlannerInfo *root,
                               RangeTblEntry *rte);

-extern List *expand_function_arguments(List *args, Oid result_type,
-                          HeapTuple func_tuple);
-
 #endif                            /* CLAUSES_H */
diff --git a/src/include/optimizer/cost.h b/src/include/optimizer/cost.h
index e7005b4..d5912e3 100644
--- a/src/include/optimizer/cost.h
+++ b/src/include/optimizer/cost.h
@@ -44,15 +44,7 @@ typedef enum
  *      routines to compute costs and sizes
  */

-/* parameter variables and flags */
-extern PGDLLIMPORT double seq_page_cost;
-extern PGDLLIMPORT double random_page_cost;
-extern PGDLLIMPORT double cpu_tuple_cost;
-extern PGDLLIMPORT double cpu_index_tuple_cost;
-extern PGDLLIMPORT double cpu_operator_cost;
-extern PGDLLIMPORT double parallel_tuple_cost;
-extern PGDLLIMPORT double parallel_setup_cost;
-extern PGDLLIMPORT int effective_cache_size;
+/* parameter variables and flags (see also optimizer.h) */
 extern PGDLLIMPORT Cost disable_cost;
 extern PGDLLIMPORT int max_parallel_workers_per_gather;
 extern PGDLLIMPORT bool enable_seqscan;
@@ -74,7 +66,6 @@ extern PGDLLIMPORT bool enable_parallel_hash;
 extern PGDLLIMPORT bool enable_partition_pruning;
 extern PGDLLIMPORT int constraint_exclusion;

-extern double clamp_row_est(double nrows);
 extern double index_pages_fetched(double tuples_fetched, BlockNumber pages,
                     double index_pages, PlannerInfo *root);
 extern void cost_seqscan(Path *path, PlannerInfo *root, RelOptInfo *baserel,
@@ -163,6 +154,10 @@ extern void final_cost_hashjoin(PlannerInfo *root, HashPath *path,
                     JoinPathExtraData *extra);
 extern void cost_gather(GatherPath *path, PlannerInfo *root,
             RelOptInfo *baserel, ParamPathInfo *param_info, double *rows);
+extern void cost_gather_merge(GatherMergePath *path, PlannerInfo *root,
+                  RelOptInfo *rel, ParamPathInfo *param_info,
+                  Cost input_startup_cost, Cost input_total_cost,
+                  double *rows);
 extern void cost_subplan(PlannerInfo *root, SubPlan *subplan, Plan *plan);
 extern void cost_qual_eval(QualCost *cost, List *quals, PlannerInfo *root);
 extern void cost_qual_eval_node(QualCost *cost, Node *qual, PlannerInfo *root);
@@ -201,23 +196,4 @@ extern PathTarget *set_pathtarget_cost_width(PlannerInfo *root, PathTarget *targ
 extern double compute_bitmap_pages(PlannerInfo *root, RelOptInfo *baserel,
                      Path *bitmapqual, int loop_count, Cost *cost, double *tuple);

-/*
- * prototypes for clausesel.c
- *      routines to compute clause selectivities
- */
-extern Selectivity clauselist_selectivity(PlannerInfo *root,
-                       List *clauses,
-                       int varRelid,
-                       JoinType jointype,
-                       SpecialJoinInfo *sjinfo);
-extern Selectivity clause_selectivity(PlannerInfo *root,
-                   Node *clause,
-                   int varRelid,
-                   JoinType jointype,
-                   SpecialJoinInfo *sjinfo);
-extern void cost_gather_merge(GatherMergePath *path, PlannerInfo *root,
-                  RelOptInfo *rel, ParamPathInfo *param_info,
-                  Cost input_startup_cost, Cost input_total_cost,
-                  double *rows);
-
 #endif                            /* COST_H */
diff --git a/src/include/optimizer/optimizer.h b/src/include/optimizer/optimizer.h
index e69de29..1cd5c80 100644
--- a/src/include/optimizer/optimizer.h
+++ b/src/include/optimizer/optimizer.h
@@ -0,0 +1,175 @@
+/*-------------------------------------------------------------------------
+ *
+ * optimizer.h
+ *      External API for the Postgres planner.
+ *
+ * This header is meant to define everything that the core planner
+ * exposes for use by non-planner modules.
+ *
+ * Note that there are files outside src/backend/optimizer/ that are
+ * considered planner modules, because they're too much in bed with
+ * planner operations to be treated otherwise.  FDW planning code is an
+ * example.  For the most part, however, code outside the core planner
+ * should not need to include any optimizer/ header except this one.
+ *
+ * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/optimizer/optimizer.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef OPTIMIZER_H
+#define OPTIMIZER_H
+
+#include "nodes/parsenodes.h"
+
+/*
+ * We don't want to include nodes/relation.h here, because non-planner
+ * code should generally treat PlannerInfo as an opaque typedef.
+ * But we'd like such code to use that typedef name, so define the
+ * typedef either here or in relation.h, whichever is read first.
+ */
+#ifndef HAVE_PLANNERINFO_TYPEDEF
+typedef struct PlannerInfo PlannerInfo;
+#define HAVE_PLANNERINFO_TYPEDEF 1
+#endif
+
+/* Likewise for SpecialJoinInfo. */
+#ifndef HAVE_SPECIALJOININFO_TYPEDEF
+typedef struct SpecialJoinInfo SpecialJoinInfo;
+#define HAVE_SPECIALJOININFO_TYPEDEF 1
+#endif
+
+/* It also seems best not to include plannodes.h, params.h, or htup.h here */
+struct PlannedStmt;
+struct ParamListInfoData;
+struct HeapTupleData;
+
+
+/* in path/clausesel.c: */
+
+extern Selectivity clause_selectivity(PlannerInfo *root,
+                   Node *clause,
+                   int varRelid,
+                   JoinType jointype,
+                   SpecialJoinInfo *sjinfo);
+extern Selectivity clauselist_selectivity(PlannerInfo *root,
+                       List *clauses,
+                       int varRelid,
+                       JoinType jointype,
+                       SpecialJoinInfo *sjinfo);
+
+/* in path/costsize.c: */
+
+/* widely used cost parameters */
+extern PGDLLIMPORT double seq_page_cost;
+extern PGDLLIMPORT double random_page_cost;
+extern PGDLLIMPORT double cpu_tuple_cost;
+extern PGDLLIMPORT double cpu_index_tuple_cost;
+extern PGDLLIMPORT double cpu_operator_cost;
+extern PGDLLIMPORT double parallel_tuple_cost;
+extern PGDLLIMPORT double parallel_setup_cost;
+extern PGDLLIMPORT int effective_cache_size;
+
+extern double clamp_row_est(double nrows);
+
+/* in plan/planner.c: */
+
+/* possible values for force_parallel_mode */
+typedef enum
+{
+    FORCE_PARALLEL_OFF,
+    FORCE_PARALLEL_ON,
+    FORCE_PARALLEL_REGRESS
+}            ForceParallelMode;
+
+/* GUC parameters */
+extern int    force_parallel_mode;
+extern bool parallel_leader_participation;
+
+extern struct PlannedStmt *planner(Query *parse, int cursorOptions,
+        struct ParamListInfoData *boundParams);
+
+extern Expr *expression_planner(Expr *expr);
+extern Expr *expression_planner_with_deps(Expr *expr,
+                             List **relationOids,
+                             List **invalItems);
+
+extern bool plan_cluster_use_sort(Oid tableOid, Oid indexOid);
+extern int    plan_create_index_workers(Oid tableOid, Oid indexOid);
+
+/* in plan/setrefs.c: */
+
+extern void extract_query_dependencies(Node *query,
+                           List **relationOids,
+                           List **invalItems,
+                           bool *hasRowSecurity);
+
+/* in prep/prepqual.c: */
+
+extern Node *negate_clause(Node *node);
+extern Expr *canonicalize_qual(Expr *qual, bool is_check);
+
+/* in util/clauses.c: */
+
+extern bool contain_mutable_functions(Node *clause);
+extern bool contain_volatile_functions(Node *clause);
+extern bool contain_volatile_functions_not_nextval(Node *clause);
+
+extern Node *eval_const_expressions(PlannerInfo *root, Node *node);
+
+extern Node *estimate_expression_value(PlannerInfo *root, Node *node);
+
+extern Expr *evaluate_expr(Expr *expr, Oid result_type, int32 result_typmod,
+              Oid result_collation);
+
+extern List *expand_function_arguments(List *args, Oid result_type,
+                          struct HeapTupleData *func_tuple);
+
+/* in util/predtest.c: */
+
+extern bool predicate_implied_by(List *predicate_list, List *clause_list,
+                     bool weak);
+extern bool predicate_refuted_by(List *predicate_list, List *clause_list,
+                     bool weak);
+
+/* in util/tlist.c: */
+
+extern int    count_nonjunk_tlist_entries(List *tlist);
+extern TargetEntry *get_sortgroupref_tle(Index sortref,
+                     List *targetList);
+extern TargetEntry *get_sortgroupclause_tle(SortGroupClause *sgClause,
+                        List *targetList);
+extern Node *get_sortgroupclause_expr(SortGroupClause *sgClause,
+                         List *targetList);
+extern List *get_sortgrouplist_exprs(List *sgClauses,
+                        List *targetList);
+extern SortGroupClause *get_sortgroupref_clause(Index sortref,
+                        List *clauses);
+extern SortGroupClause *get_sortgroupref_clause_noerr(Index sortref,
+                              List *clauses);
+
+/* in util/var.c: */
+
+/* Bits that can be OR'd into the flags argument of pull_var_clause() */
+#define PVC_INCLUDE_AGGREGATES    0x0001    /* include Aggrefs in output list */
+#define PVC_RECURSE_AGGREGATES    0x0002    /* recurse into Aggref arguments */
+#define PVC_INCLUDE_WINDOWFUNCS 0x0004    /* include WindowFuncs in output list */
+#define PVC_RECURSE_WINDOWFUNCS 0x0008    /* recurse into WindowFunc arguments */
+#define PVC_INCLUDE_PLACEHOLDERS    0x0010    /* include PlaceHolderVars in
+                                             * output list */
+#define PVC_RECURSE_PLACEHOLDERS    0x0020    /* recurse into PlaceHolderVar
+                                             * arguments */
+
+extern Bitmapset *pull_varnos(Node *node);
+extern Bitmapset *pull_varnos_of_level(Node *node, int levelsup);
+extern void pull_varattnos(Node *node, Index varno, Bitmapset **varattnos);
+extern List *pull_vars_of_level(Node *node, int levelsup);
+extern bool contain_var_clause(Node *node);
+extern bool contain_vars_of_level(Node *node, int levelsup);
+extern int    locate_var_of_level(Node *node, int levelsup);
+extern List *pull_var_clause(Node *node, int flags);
+extern Node *flatten_join_alias_vars(Query *query, Node *node);
+
+#endif                            /* OPTIMIZER_H */
diff --git a/src/include/optimizer/planmain.h b/src/include/optimizer/planmain.h
index bec0c38..b2e1c07 100644
--- a/src/include/optimizer/planmain.h
+++ b/src/include/optimizer/planmain.h
@@ -17,19 +17,9 @@
 #include "nodes/plannodes.h"
 #include "nodes/relation.h"

-/* possible values for force_parallel_mode */
-typedef enum
-{
-    FORCE_PARALLEL_OFF,
-    FORCE_PARALLEL_ON,
-    FORCE_PARALLEL_REGRESS
-}            ForceParallelMode;
-
 /* GUC parameters */
 #define DEFAULT_CURSOR_TUPLE_FRACTION 0.1
 extern double cursor_tuple_fraction;
-extern int    force_parallel_mode;
-extern bool parallel_leader_participation;

 /* query_planner callback to compute query_pathkeys */
 typedef void (*query_pathkeys_callback) (PlannerInfo *root, void *extra);
@@ -119,10 +109,6 @@ extern bool innerrel_is_unique(PlannerInfo *root,
 extern Plan *set_plan_references(PlannerInfo *root, Plan *plan);
 extern void record_plan_function_dependency(PlannerInfo *root, Oid funcid);
 extern void record_plan_type_dependency(PlannerInfo *root, Oid typid);
-extern void extract_query_dependencies(Node *query,
-                           List **relationOids,
-                           List **invalItems,
-                           bool *hasRowSecurity);
 extern bool extract_query_dependencies_walker(Node *node, PlannerInfo *root);

 #endif                            /* PLANMAIN_H */
diff --git a/src/include/optimizer/planner.h b/src/include/optimizer/planner.h
index 8616681..769a2f8 100644
--- a/src/include/optimizer/planner.h
+++ b/src/include/optimizer/planner.h
@@ -3,6 +3,10 @@
  * planner.h
  *      prototypes for planner.c.
  *
+ * Note that the primary entry points for planner.c are declared in
+ * optimizer/optimizer.h, because they're intended to be called from
+ * non-planner code.  Declarations here are meant for use by other
+ * planner modules.
  *
  * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
@@ -33,8 +37,6 @@ typedef void (*create_upper_paths_hook_type) (PlannerInfo *root,
 extern PGDLLIMPORT create_upper_paths_hook_type create_upper_paths_hook;


-extern PlannedStmt *planner(Query *parse, int cursorOptions,
-        ParamListInfo boundParams);
 extern PlannedStmt *standard_planner(Query *parse, int cursorOptions,
                  ParamListInfo boundParams);

@@ -54,14 +56,6 @@ extern void mark_partial_aggref(Aggref *agg, AggSplit aggsplit);
 extern Path *get_cheapest_fractional_path(RelOptInfo *rel,
                              double tuple_fraction);

-extern Expr *expression_planner(Expr *expr);
-extern Expr *expression_planner_with_deps(Expr *expr,
-                             List **relationOids,
-                             List **invalItems);
-
 extern Expr *preprocess_phv_expression(PlannerInfo *root, Expr *expr);

-extern bool plan_cluster_use_sort(Oid tableOid, Oid indexOid);
-extern int    plan_create_index_workers(Oid tableOid, Oid indexOid);
-
 #endif                            /* PLANNER_H */
diff --git a/src/include/optimizer/predtest.h b/src/include/optimizer/predtest.h
index d5abe79..e69de29 100644
--- a/src/include/optimizer/predtest.h
+++ b/src/include/optimizer/predtest.h
@@ -1,25 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * predtest.h
- *      prototypes for predtest.c
- *
- *
- * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- * src/include/optimizer/predtest.h
- *
- *-------------------------------------------------------------------------
- */
-#ifndef PREDTEST_H
-#define PREDTEST_H
-
-#include "nodes/primnodes.h"
-
-
-extern bool predicate_implied_by(List *predicate_list, List *clause_list,
-                     bool weak);
-extern bool predicate_refuted_by(List *predicate_list, List *clause_list,
-                     bool weak);
-
-#endif                            /* PREDTEST_H */
diff --git a/src/include/optimizer/prep.h b/src/include/optimizer/prep.h
index 3ad8dcb..9a7a584 100644
--- a/src/include/optimizer/prep.h
+++ b/src/include/optimizer/prep.h
@@ -30,12 +30,6 @@ extern Relids get_relids_in_jointree(Node *jtnode, bool include_joins);
 extern Relids get_relids_for_join(Query *query, int joinrelid);

 /*
- * prototypes for prepqual.c
- */
-extern Node *negate_clause(Node *node);
-extern Expr *canonicalize_qual(Expr *qual, bool is_check);
-
-/*
  * prototypes for preptlist.c
  */
 extern List *preprocess_targetlist(PlannerInfo *root);
diff --git a/src/include/optimizer/tlist.h b/src/include/optimizer/tlist.h
index 8b967f9..13ac7b8 100644
--- a/src/include/optimizer/tlist.h
+++ b/src/include/optimizer/tlist.h
@@ -24,8 +24,6 @@ extern List *add_to_flat_tlist(List *tlist, List *exprs);

 extern List *get_tlist_exprs(List *tlist, bool includeJunk);

-extern int    count_nonjunk_tlist_entries(List *tlist);
-
 extern bool tlist_same_exprs(List *tlist1, List *tlist2);

 extern bool tlist_same_datatypes(List *tlist, List *colTypes, bool junkOK);
@@ -33,20 +31,6 @@ extern bool tlist_same_collations(List *tlist, List *colCollations, bool junkOK)

 extern void apply_tlist_labeling(List *dest_tlist, List *src_tlist);

-extern TargetEntry *get_sortgroupref_tle(Index sortref,
-                     List *targetList);
-extern TargetEntry *get_sortgroupclause_tle(SortGroupClause *sgClause,
-                        List *targetList);
-extern Node *get_sortgroupclause_expr(SortGroupClause *sgClause,
-                         List *targetList);
-extern List *get_sortgrouplist_exprs(List *sgClauses,
-                        List *targetList);
-
-extern SortGroupClause *get_sortgroupref_clause(Index sortref,
-                        List *clauses);
-extern SortGroupClause *get_sortgroupref_clause_noerr(Index sortref,
-                              List *clauses);
-
 extern Oid *extract_grouping_ops(List *groupClause);
 extern AttrNumber *extract_grouping_cols(List *groupClause, List *tlist);
 extern bool grouping_is_sortable(List *groupClause);
diff --git a/src/include/optimizer/var.h b/src/include/optimizer/var.h
index f975074..e69de29 100644
--- a/src/include/optimizer/var.h
+++ b/src/include/optimizer/var.h
@@ -1,40 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * var.h
- *      prototypes for optimizer/util/var.c.
- *
- *
- * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- * src/include/optimizer/var.h
- *
- *-------------------------------------------------------------------------
- */
-#ifndef VAR_H
-#define VAR_H
-
-#include "nodes/relation.h"
-
-/* Bits that can be OR'd into the flags argument of pull_var_clause() */
-#define PVC_INCLUDE_AGGREGATES    0x0001    /* include Aggrefs in output list */
-#define PVC_RECURSE_AGGREGATES    0x0002    /* recurse into Aggref arguments */
-#define PVC_INCLUDE_WINDOWFUNCS 0x0004    /* include WindowFuncs in output list */
-#define PVC_RECURSE_WINDOWFUNCS 0x0008    /* recurse into WindowFunc arguments */
-#define PVC_INCLUDE_PLACEHOLDERS    0x0010    /* include PlaceHolderVars in
-                                             * output list */
-#define PVC_RECURSE_PLACEHOLDERS    0x0020    /* recurse into PlaceHolderVar
-                                             * arguments */
-
-
-extern Relids pull_varnos(Node *node);
-extern Relids pull_varnos_of_level(Node *node, int levelsup);
-extern void pull_varattnos(Node *node, Index varno, Bitmapset **varattnos);
-extern List *pull_vars_of_level(Node *node, int levelsup);
-extern bool contain_var_clause(Node *node);
-extern bool contain_vars_of_level(Node *node, int levelsup);
-extern int    locate_var_of_level(Node *node, int levelsup);
-extern List *pull_var_clause(Node *node, int flags);
-extern Node *flatten_join_alias_vars(Query *query, Node *node);
-
-#endif                            /* VAR_H */
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index 45f10f9..85aa613 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -30,8 +30,7 @@
 #include "funcapi.h"
 #include "miscadmin.h"
 #include "nodes/nodeFuncs.h"
-#include "optimizer/clauses.h"
-#include "optimizer/planner.h"
+#include "optimizer/optimizer.h"
 #include "parser/parse_coerce.h"
 #include "parser/scansup.h"
 #include "storage/proc.h"
diff --git a/src/test/modules/test_predtest/test_predtest.c b/src/test/modules/test_predtest/test_predtest.c
index c03748c..10cd4f9 100644
--- a/src/test/modules/test_predtest/test_predtest.c
+++ b/src/test/modules/test_predtest/test_predtest.c
@@ -18,8 +18,7 @@
 #include "executor/spi.h"
 #include "funcapi.h"
 #include "nodes/makefuncs.h"
-#include "optimizer/clauses.h"
-#include "optimizer/predtest.h"
+#include "optimizer/optimizer.h"
 #include "utils/builtins.h"

 PG_MODULE_MAGIC;

pgsql-hackers by date:

Previous
From: Robert Haas
Date:
Subject: Re: proposal: new polymorphic types - commontype and commontypearray
Next
From: Corey Huinker
Date:
Subject: Re: Alternative to \copy in psql modelled after \g