Repository: vitessio/vitess
Pull request #8806 (2021-09-13 18:19:51)

[Gen4] change planning context to be a reference
<!--
  Thank you for your contribution to the Vitess project.
  How to contribute: https://vitess.io/docs/contributing/
  Please first make sure there is an open Issue to discuss the feature/fix suggested in this PR.
  If this is a new feature, please mark the Issue as "RFC".
 -->

<!-- if this PR is Work in Progress please create it as a Draft Pull Request -->

## Description
<!-- A few sentences describing the overall goals of the pull request's commits. -->
<!-- If this is a bug fix and you think the fix should be backported, please write so. -->

Change planner context as reference to be passed to function calls.

It does not look like a significant impact.

```
name                                        old allocs/op  new allocs/op  delta
OLTP/Gen4-8                                    312µs ± 9%     338µs ± 1%     ~     (p=0.056 n=5+5)
OLTP/Gen4Greedy-8                              336µs ± 1%     339µs ± 0%     ~     (p=0.111 n=5+4)
OLTP/Gen4Left2Right-8                          329µs ± 8%     339µs ± 2%     ~     (p=0.421 n=5+5)
OLTP/Gen4WithFallback-8                        345µs ± 1%     344µs ± 3%     ~     (p=0.222 n=5+5)
TPCC/Gen4-8                                   2.30ms ± 2%    2.42ms ± 3%   +5.31%  (p=0.008 n=5+5)
TPCC/Gen4Greedy-8                             2.27ms ± 1%    2.40ms ± 1%   +6.08%  (p=0.008 n=5+5)
TPCC/Gen4Left2Right-8                         2.31ms ± 2%    2.40ms ± 1%   +4.15%  (p=0.008 n=5+5)
TPCC/Gen4WithFallback-8                       2.30ms ± 0%    2.45ms ± 5%   +6.27%  (p=0.008 n=5+5)
TPCH/Gen4-8                                   4.41ms ± 0%    5.19ms ±30%  +17.84%  (p=0.008 n=5+5)
TPCH/Gen4Greedy-8                             4.42ms ± 0%    4.74ms ± 1%   +7.35%  (p=0.016 n=4+5)
TPCH/Gen4Left2Right-8                         4.09ms ± 0%    4.34ms ± 1%   +6.01%  (p=0.016 n=4+5)
TPCH/Gen4WithFallback-8                       4.91ms ± 2%    5.30ms ± 5%   +7.92%  (p=0.008 n=5+5)
Planner/from_cases.txt-gen4-8                 5.86ms ± 1%    5.82ms ± 1%     ~     (p=0.056 n=5+5)
Planner/from_cases.txt-gen4left2right-8       5.65ms ± 1%    5.59ms ± 1%     ~     (p=0.222 n=5+5)
Planner/filter_cases.txt-gen4-8               8.06ms ± 2%    8.05ms ± 3%     ~     (p=0.690 n=5+5)
Planner/filter_cases.txt-gen4left2right-8     8.10ms ± 6%    7.93ms ± 1%     ~     (p=0.421 n=5+5)
Planner/large_cases.txt-gen4-8                 322µs ± 1%     322µs ± 1%     ~     (p=0.905 n=4+5)
Planner/large_cases.txt-gen4left2right-8       227µs ± 1%     227µs ± 1%     ~     (p=0.841 n=5+5)
Planner/aggr_cases.txt-gen4-8                 6.04ms ± 1%    6.02ms ± 1%     ~     (p=0.690 n=5+5)
Planner/aggr_cases.txt-gen4left2right-8       5.98ms ± 1%    6.00ms ± 1%     ~     (p=0.690 n=5+5)
Planner/select_cases.txt-gen4-8               3.17ms ± 1%    3.15ms ± 1%     ~     (p=0.095 n=5+5)
Planner/select_cases.txt-gen4left2right-8     3.10ms ± 1%    3.09ms ± 1%     ~     (p=0.548 n=5+5)
Planner/union_cases.txt-gen4-8                1.60ms ± 1%    1.65ms ± 5%     ~     (p=0.421 n=5+5)
Planner/union_cases.txt-gen4left2right-8      1.60ms ± 2%    1.60ms ± 2%     ~     (p=1.000 n=5+5)
OLTP/Gen4-8                                    101kB ± 0%     101kB ± 0%   -0.24%  (p=0.008 n=5+5)
OLTP/Gen4Greedy-8                              101kB ± 0%     101kB ± 0%   -0.21%  (p=0.008 n=5+5)
OLTP/Gen4Left2Right-8                          101kB ± 0%     101kB ± 0%   -0.22%  (p=0.008 n=5+5)
OLTP/Gen4WithFallback-8                        102kB ± 0%     101kB ± 0%   -0.23%  (p=0.008 n=5+5)
TPCC/Gen4-8                                    766kB ± 0%     765kB ± 0%   -0.17%  (p=0.008 n=5+5)
TPCC/Gen4Greedy-8                              766kB ± 0%     765kB ± 0%   -0.15%  (p=0.008 n=5+5)
TPCC/Gen4Left2Right-8                          764kB ± 0%     763kB ± 0%   -0.15%  (p=0.008 n=5+5)
TPCC/Gen4WithFallback-8                        769kB ± 0%     767kB ± 0%   -0.16%  (p=0.008 n=5+5)
TPCH/Gen4-8                                   1.69MB ± 0%    1.69MB ± 0%     ~     (p=0.056 n=5+5)
TPCH/Gen4Greedy-8                             1.69MB ± 0%    1.69MB ± 0%   -0.04%  (p=0.016 n=5+5)
TPCH/Gen4Left2Right-8                         1.50MB ± 0%    1.49MB ± 0%   -0.03%  (p=0.016 n=5+5)
TPCH/Gen4WithFallback-8                       1.84MB ± 0%    1.84MB ± 0%     ~     (p=0.095 n=5+5)
Planner/from_cases.txt-gen4-8                 2.01MB ± 0%    2.00MB ± 0%   -0.16%  (p=0.008 n=5+5)
Planner/from_cases.txt-gen4left2right-8       1.88MB ± 0%    1.88MB ± 0%   -0.20%  (p=0.008 n=5+5)
Planner/filter_cases.txt-gen4-8               2.71MB ± 0%    2.71MB ± 0%   -0.16%  (p=0.008 n=5+5)
Planner/filter_cases.txt-gen4left2right-8     2.68MB ± 0%    2.67MB ± 0%   -0.14%  (p=0.008 n=5+5)
Planner/large_cases.txt-gen4-8                 143kB ± 0%     143kB ± 0%   -0.03%  (p=0.008 n=5+5)
Planner/large_cases.txt-gen4left2right-8      90.6kB ± 0%    90.6kB ± 0%   -0.04%  (p=0.008 n=5+5)
Planner/aggr_cases.txt-gen4-8                 1.57MB ± 0%    1.57MB ± 0%   -0.20%  (p=0.008 n=5+5)
Planner/aggr_cases.txt-gen4left2right-8       1.56MB ± 0%    1.56MB ± 0%   -0.19%  (p=0.008 n=5+5)
Planner/select_cases.txt-gen4-8                941kB ± 0%     939kB ± 0%   -0.23%  (p=0.008 n=5+5)
Planner/select_cases.txt-gen4left2right-8      907kB ± 0%     905kB ± 0%   -0.24%  (p=0.008 n=5+5)
Planner/union_cases.txt-gen4-8                 450kB ± 0%     449kB ± 0%   -0.17%  (p=0.008 n=5+5)
Planner/union_cases.txt-gen4left2right-8       445kB ± 0%     444kB ± 0%   -0.16%  (p=0.008 n=5+5)
OLTP/Gen4-8                                    2.35k ± 0%     2.35k ± 0%   -0.21%  (p=0.008 n=5+5)
OLTP/Gen4Greedy-8                              2.35k ± 0%     2.35k ± 0%   -0.21%  (p=0.008 n=5+5)
OLTP/Gen4Left2Right-8                          2.35k ± 0%     2.35k ± 0%   -0.21%  (p=0.008 n=5+5)
OLTP/Gen4WithFallback-8                        2.38k ± 0%     2.38k ± 0%   -0.21%  (p=0.008 n=5+5)
TPCC/Gen4-8                                    17.8k ± 0%     17.8k ± 0%   -0.13%  (p=0.008 n=5+5)
TPCC/Gen4Greedy-8                              17.8k ± 0%     17.8k ± 0%   -0.13%  (p=0.008 n=5+5)
TPCC/Gen4Left2Right-8                          17.8k ± 0%     17.7k ± 0%   -0.13%  (p=0.008 n=5+5)
TPCC/Gen4WithFallback-8                        17.9k ± 0%     17.9k ± 0%   -0.13%  (p=0.008 n=5+5)
TPCH/Gen4-8                                    26.9k ± 0%     26.9k ± 0%   -0.04%  (p=0.000 n=4+5)
TPCH/Gen4Greedy-8                              26.9k ± 0%     26.9k ± 0%   -0.04%  (p=0.008 n=5+5)
TPCH/Gen4Left2Right-8                          23.0k ± 0%     23.0k ± 0%   -0.05%  (p=0.000 n=4+5)
TPCH/Gen4WithFallback-8                        28.9k ± 0%     28.9k ± 0%   -0.04%  (p=0.008 n=5+5)
Planner/from_cases.txt-gen4-8                  42.0k ± 0%     41.9k ± 0%   -0.17%  (p=0.008 n=5+5)
Planner/from_cases.txt-gen4left2right-8        40.2k ± 0%     40.1k ± 0%   -0.18%  (p=0.008 n=5+5)
Planner/filter_cases.txt-gen4-8                55.5k ± 0%     55.4k ± 0%   -0.16%  (p=0.016 n=4+5)
Planner/filter_cases.txt-gen4left2right-8      54.6k ± 0%     54.5k ± 0%   -0.16%  (p=0.008 n=5+5)
Planner/large_cases.txt-gen4-8                 2.42k ± 0%     2.42k ± 0%   -0.04%  (p=0.008 n=5+5)
Planner/large_cases.txt-gen4left2right-8       1.86k ± 0%     1.86k ± 0%   -0.05%  (p=0.008 n=5+5)
Planner/aggr_cases.txt-gen4-8                  37.6k ± 0%     37.5k ± 0%   -0.18%  (p=0.008 n=5+5)
Planner/aggr_cases.txt-gen4left2right-8        37.4k ± 0%     37.4k ± 0%   -0.18%  (p=0.008 n=5+5)
Planner/select_cases.txt-gen4-8                21.5k ± 0%     21.5k ± 0%   -0.22%  (p=0.008 n=5+5)
Planner/select_cases.txt-gen4left2right-8      21.1k ± 0%     21.0k ± 0%   -0.23%  (p=0.008 n=5+5)
Planner/union_cases.txt-gen4-8                 11.3k ± 0%     11.3k ± 0%   -0.14%  (p=0.008 n=5+5)
Planner/union_cases.txt-gen4left2right-8       11.2k ± 0%     11.2k ± 0%   -0.14%  (p=0.008 n=5+5)
```

## Related Issue(s)
<!-- List related issues and pull requests. If this PR fixes an issue, please add it using Fixes #????  -->

#7280 

## Checklist
- [ ] Should this PR be backported?
- [ ] Tests were added or are not required
- [ ] Documentation was added or is not required

## Deployment Notes
<!-- Notes regarding deployment of the contained body of work. These should note any db migrations, etc. -->


Patch:
diff --git a/go/vt/vtgate/planbuilder/gen4_planner.go b/go/vt/vtgate/planbuilder/gen4_planner.go
index 3bc37e64d2..45b1122564 100644
--- a/go/vt/vtgate/planbuilder/gen4_planner.go
+++ b/go/vt/vtgate/planbuilder/gen4_planner.go
@@ -154,8 +154,8 @@ func newBuildSelectPlan(selStmt sqlparser.SelectStatement, reservedVars *sqlpars
 	return plan, nil
 }
 
-func newPlanningContext(reservedVars *sqlparser.ReservedVars, semTable *semantics.SemTable, vschema ContextVSchema) planningContext {
-	ctx := planningContext{
+func newPlanningContext(reservedVars *sqlparser.ReservedVars, semTable *semantics.SemTable, vschema ContextVSchema) *planningContext {
+	ctx := &planningContext{
 		reservedVars: reservedVars,
 		semTable:     semTable,
 		vschema:      vschema,
@@ -194,7 +194,7 @@ func checkUnsupportedConstructs(sel *sqlparser.Select) error {
 	return nil
 }
 
-func planHorizon(ctx planningContext, plan logicalPlan, in sqlparser.SelectStatement) (logicalPlan, error) {
+func planHorizon(ctx *planningContext, plan logicalPlan, in sqlparser.SelectStatement) (logicalPlan, error) {
 	switch node := in.(type) {
 	case *sqlparser.Select:
 		hp := horizonPlanning{
@@ -235,7 +235,7 @@ func planHorizon(ctx planningContext, plan logicalPlan, in sqlparser.SelectState
 
 }
 
-func planOrderByOnUnion(ctx planningContext, plan logicalPlan, union *sqlparser.Union) (logicalPlan, error) {
+func planOrderByOnUnion(ctx *planningContext, plan logicalPlan, union *sqlparser.Union) (logicalPlan, error) {
 	qp, err := abstract.CreateQPFromUnion(union, ctx.semTable)
 	if err != nil {
 		return nil, err
diff --git a/go/vt/vtgate/planbuilder/horizon_planning.go b/go/vt/vtgate/planbuilder/horizon_planning.go
index ba77c8039b..6871e08a6b 100644
--- a/go/vt/vtgate/planbuilder/horizon_planning.go
+++ b/go/vt/vtgate/planbuilder/horizon_planning.go
@@ -38,7 +38,7 @@ type horizonPlanning struct {
 	vtgateGrouping  bool
 }
 
-func (hp *horizonPlanning) planHorizon(ctx planningContext, plan logicalPlan) (logicalPlan, error) {
+func (hp *horizonPlanning) planHorizon(ctx *planningContext, plan logicalPlan) (logicalPlan, error) {
 	rb, isRoute := plan.(*route)
 	if !isRoute && ctx.semTable.ProjectionErr != nil {
 		return nil, ctx.semTable.ProjectionErr
@@ -124,7 +124,7 @@ func (hp *horizonPlanning) planHorizon(ctx planningContext, plan logicalPlan) (l
 	return plan, nil
 }
 
-func pushProjections(ctx planningContext, plan logicalPlan, selectExprs []abstract.SelectExpr) error {
+func pushProjections(ctx *planningContext, plan logicalPlan, selectExprs []abstract.SelectExpr) error {
 	for _, e := range selectExprs {
 		aliasExpr, err := e.GetAliasedExpr()
 		if err != nil {
@@ -314,7 +314,7 @@ func (hp *horizonPlanning) haveToTruncate(v bool) {
 	hp.needsTruncation = hp.needsTruncation || v
 }
 
-func (hp *horizonPlanning) planAggregations(ctx planningContext, plan logicalPlan) (logicalPlan, error) {
+func (hp *horizonPlanning) planAggregations(ctx *planningContext, plan logicalPlan) (logicalPlan, error) {
 	newPlan := plan
 	var oa *orderedAggregate
 	uniqVindex := hasUniqueVindex(ctx.vschema, ctx.semTable, hp.qp.GroupByExprs)
@@ -510,7 +510,7 @@ func planGroupByGen4(groupExpr abstract.GroupBy, plan logicalPlan, semTable *sem
 	}
 }
 
-func (hp *horizonPlanning) planGroupByUsingOrderBy(ctx planningContext, plan logicalPlan) (logicalPlan, error) {
+func (hp *horizonPlanning) planGroupByUsingOrderBy(ctx *planningContext, plan logicalPlan) (logicalPlan, error) {
 	var orderExprs []abstract.OrderBy
 	for _, groupExpr := range hp.qp.GroupByExprs {
 		addExpr := true
@@ -533,7 +533,7 @@ func (hp *horizonPlanning) planGroupByUsingOrderBy(ctx planningContext, plan log
 	return plan, nil
 }
 
-func (hp *horizonPlanning) planOrderBy(ctx planningContext, orderExprs []abstract.OrderBy, plan logicalPlan) (logicalPlan, error) {
+func (hp *horizonPlanning) planOrderBy(ctx *planningContext, orderExprs []abstract.OrderBy, plan logicalPlan) (logicalPlan, error) {
 	switch plan := plan.(type) {
 	case *route:
 		newPlan, truncate, err := planOrderByForRoute(orderExprs, plan, ctx.semTable, hp.qp.HasStar)
@@ -685,7 +685,7 @@ func weightStringFor(expr sqlparser.Expr) sqlparser.Expr {
 
 }
 
-func (hp *horizonPlanning) planOrderByForJoin(ctx planningContext, orderExprs []abstract.OrderBy, plan *joinGen4) (logicalPlan, error) {
+func (hp *horizonPlanning) planOrderByForJoin(ctx *planningContext, orderExprs []abstract.OrderBy, plan *joinGen4) (logicalPlan, error) {
 	if allLeft(orderExprs, ctx.semTable, plan.Left.ContainsTables()) {
 		newLeft, err := hp.planOrderBy(ctx, orderExprs, plan.Left)
 		if err != nil {
@@ -741,7 +741,7 @@ func findExprInOrderedAggr(plan *orderedAggregate, order abstract.OrderBy) (int,
 	return 0, 0, false
 }
 
-func (hp *horizonPlanning) createMemorySortPlan(ctx planningContext, plan logicalPlan, orderExprs []abstract.OrderBy) (logicalPlan, error) {
+func (hp *horizonPlanning) createMemorySortPlan(ctx *planningContext, plan logicalPlan, orderExprs []abstract.OrderBy) (logicalPlan, error) {
 	primitive := &engine.MemorySort{}
 	ms := &memorySort{
 		resultsBuilder: resultsBuilder{
@@ -778,7 +778,7 @@ func allLeft(orderExprs []abstract.OrderBy, semTable *semantics.SemTable, lhsTab
 	return true
 }
 
-func (hp *horizonPlanning) planDistinct(ctx planningContext, plan logicalPlan) (logicalPlan, error) {
+func (hp *horizonPlanning) planDistinct(ctx *planningContext, plan logicalPlan) (logicalPlan, error) {
 	if !hp.qp.NeedsDistinct() {
 		return plan, nil
 	}
@@ -841,7 +841,7 @@ func (hp *horizonPlanning) planDistinctOA(currPlan *orderedAggregate) (logicalPl
 	return oa, nil
 }
 
-func (hp *horizonPlanning) addDistinct(ctx planningContext, plan logicalPlan) (logicalPlan, error) {
+func (hp *horizonPlanning) addDistinct(ctx *planningContext, plan logicalPlan) (logicalPlan, error) {
 	eaggr := &engine.OrderedAggregate{}
 	var orderExprs []abstract.OrderBy
 	for index, sExpr := range hp.qp.SelectExprs {
@@ -931,7 +931,7 @@ func selectHasUniqueVindex(vschema ContextVSchema, semTable *semantics.SemTable,
 // needDistinctHandling returns true if oa needs to handle the distinct clause.
 // If true, it will also return the aliased expression that needs to be pushed
 // down into the underlying route.
-func (hp *horizonPlanning) needDistinctHandling(ctx planningContext, funcExpr *sqlparser.FuncExpr, opcode engine.AggregateOpcode, input logicalPlan) (bool, *sqlparser.AliasedExpr, error) {
+func (hp *horizonPlanning) needDistinctHandling(ctx *planningContext, funcExpr *sqlparser.FuncExpr, opcode engine.AggregateOpcode, input logicalPlan) (bool, *sqlparser.AliasedExpr, error) {
 	if !funcExpr.Distinct {
 		return false, nil, nil
 	}
@@ -955,7 +955,7 @@ func (hp *horizonPlanning) needDistinctHandling(ctx planningContext, funcExpr *s
 	return true, innerAliased, nil
 }
 
-func (hp *horizonPlanning) planHaving(ctx planningContext, plan logicalPlan) error {
+func (hp *horizonPlanning) planHaving(ctx *planningContext, plan logicalPlan) error {
 	if hp.sel.Having == nil {
 		return nil
 	}
diff --git a/go/vt/vtgate/planbuilder/querytree_transformers.go b/go/vt/vtgate/planbuilder/querytree_transformers.go
index a4b470070b..5bf3368928 100644
--- a/go/vt/vtgate/planbuilder/querytree_transformers.go
+++ b/go/vt/vtgate/planbuilder/querytree_transformers.go
@@ -30,7 +30,7 @@ import (
 	"vitess.io/vitess/go/vt/vterrors"
 )
 
-func transformToLogicalPlan(ctx planningContext, tree queryTree) (logicalPlan, error) {
+func transformToLogicalPlan(ctx *planningContext, tree queryTree) (logicalPlan, error) {
 	switch n := tree.(type) {
 	case *routeTree:
 		return transformRoutePlan(ctx, n)
@@ -94,7 +94,7 @@ func transformVindexTree(n *vindexTree) (logicalPlan, error) {
 	return plan, nil
 }
 
-func transformSubqueryTree(ctx planningContext, n *subqueryTree) (logicalPlan, error) {
+func transformSubqueryTree(ctx *planningContext, n *subqueryTree) (logicalPlan, error) {
 	innerPlan, err := transformToLogicalPlan(ctx, n.inner)
 	if err != nil {
 		return nil, err
@@ -113,7 +113,7 @@ func transformSubqueryTree(ctx planningContext, n *subqueryTree) (logicalPlan, e
 	return plan, err
 }
 
-func transformDerivedPlan(ctx planningContext, n *derivedTree) (logicalPlan, error) {
+func transformDerivedPlan(ctx *planningContext, n *derivedTree) (logicalPlan, error) {
 	// transforming the inner part of the derived table into a logical plan
 	// so that we can do horizon planning on the inner. If the logical plan
 	// we've produced is a Route, we set its Select.From field to be an aliased
@@ -155,7 +155,7 @@ func transformDerivedPlan(ctx planningContext, n *derivedTree) (logicalPlan, err
 	return plan, nil
 }
 
-func transformConcatenatePlan(ctx planningContext, n *concatenateTree) (logicalPlan, error) {
+func transformConcatenatePlan(ctx *planningContext, n *concatenateTree) (logicalPlan, error) {
 	var sources []logicalPlan
 
 	for i, source := range n.sources {
@@ -185,7 +185,7 @@ func transformConcatenatePlan(ctx planningContext, n *concatenateTree) (logicalP
 	}, nil
 }
 
-func mergeUnionLogicalPlans(ctx planningContext, left logicalPlan, right logicalPlan) logicalPlan {
+func mergeUnionLogicalPlans(ctx *planningContext, left logicalPlan, right logicalPlan) logicalPlan {
 	lroute, ok := left.(*route)
 	if !ok {
 		return nil
@@ -212,7 +212,7 @@ func mergeUnionLogicalPlans(ctx planningContext, left logicalPlan, right logical
 	return nil
 }
 
-func createLogicalPlan(ctx planningContext, source queryTree, selStmt *sqlparser.Select) (logicalPlan, error) {
+func createLogicalPlan(ctx *planningContext, source queryTree, selStmt *sqlparser.Select) (logicalPlan, error) {
 	plan, err := transformToLogicalPlan(ctx, source)
 	if err != nil {
 		return nil, err
@@ -229,7 +229,7 @@ func createLogicalPlan(ctx planningContext, source queryTree, selStmt *sqlparser
 	return plan, nil
 }
 
-func transformRoutePlan(ctx planningContext, n *routeTree) (*route, error) {
+func transformRoutePlan(ctx *planningContext, n *routeTree) (*route, error) {
 	var tablesForSelect sqlparser.TableExprs
 	tableNameMap := map[string]interface{}{}
 
@@ -342,7 +342,7 @@ func transformRoutePlan(ctx planningContext, n *routeTree) (*route, error) {
 	}, nil
 }
 
-func transformDistinctPlan(ctx planningContext, n *distinctTree) (logicalPlan, error) {
+func transformDistinctPlan(ctx *planningContext, n *distinctTree) (logicalPlan, error) {
 	innerPlan, err := transformToLogicalPlan(ctx, n.source)
 	if err != nil {
 		return nil, err
@@ -358,7 +358,7 @@ func transformDistinctPlan(ctx planningContext, n *distinctTree) (logicalPlan, e
 	return newDistinct(innerPlan), nil
 }
 
-func transformJoinPlan(ctx planningContext, n *joinTree) (logicalPlan, error) {
+func transformJoinPlan(ctx *planningContext, n *joinTree) (logicalPlan, error) {
 	lhs, err := transformToLogicalPlan(ctx, n.lhs)
 	if err != nil {
 		return nil, err
diff --git a/go/vt/vtgate/planbuilder/route_planning.go b/go/vt/vtgate/planbuilder/route_planning.go
index 2623ecdf2f..ee21bfe403 100644
--- a/go/vt/vtgate/planbuilder/route_planning.go
+++ b/go/vt/vtgate/planbuilder/route_planning.go
@@ -48,7 +48,7 @@ func (c planningContext) isSubQueryToReplace(name string) bool {
 	return found
 }
 
-func optimizeQuery(ctx planningContext, opTree abstract.Operator) (queryTree, error) {
+func optimizeQuery(ctx *planningContext, opTree abstract.Operator) (queryTree, error) {
 	switch op := opTree.(type) {
 	case *abstract.QueryGraph:
 		switch {
@@ -106,7 +106,7 @@ func optimizeQuery(ctx planningContext, opTree abstract.Operator) (queryTree, er
 	}
 }
 
-func optimizeUnion(ctx planningContext, op *abstract.Concatenate) (queryTree, error) {
+func optimizeUnion(ctx *planningContext, op *abstract.Concatenate) (queryTree, error) {
 	var sources []queryTree
 	for _, source := range op.Sources {
 		qt, err := optimizeQuery(ctx, source)
@@ -123,7 +123,7 @@ func optimizeUnion(ctx planningContext, op *abstract.Concatenate) (queryTree, er
 	}, nil
 }
 
-func createVindexTree(ctx planningContext, op *abstract.Vindex) (*vindexTree, error) {
+func createVindexTree(ctx *planningContext, op *abstract.Vindex) (*vindexTree, error) {
 	solves := ctx.semTable.TableSetFor(op.Table.Alias)
 	plan := &vindexTree{
 		opCode: op.OpCode,
@@ -135,7 +135,7 @@ func createVindexTree(ctx planningContext, op *abstract.Vindex) (*vindexTree, er
 	return plan, nil
 }
 
-func optimizeSubQuery(ctx planningContext, op *abstract.SubQuery) (queryTree, error) {
+func optimizeSubQuery(ctx *planningContext, op *abstract.SubQuery) (queryTree, error) {
 	outerTree, err := optimizeQuery(ctx, op.Outer)
 	if err != nil {
 		return nil, err
@@ -190,7 +190,7 @@ func optimizeSubQuery(ctx planningContext, op *abstract.SubQuery) (queryTree, er
 	return outerTree, nil
 }
 
-func tryMergeSubQuery(ctx planningContext, outer, subq queryTree, subQueryInner *abstract.SubQueryInner, joinPredicates []sqlparser.Expr, merger mergeFunc) (queryTree, error) {
+func tryMergeSubQuery(ctx *planningContext, outer, subq queryTree, subQueryInner *abstract.SubQueryInner, joinPredicates []sqlparser.Expr, merger mergeFunc) (queryTree, error) {
 	var merged queryTree
 	var err error
 	switch outerTree := outer.(type) {
@@ -209,7 +209,7 @@ func tryMergeSubQuery(ctx planningContext, outer, subq queryTree, subQueryInner
 			if err != nil {
 				return nil, err
 			}
-			return rt, rewriteSubqueryDependenciesForJoin(outerTree.rhs, outerTree, subQueryInner, ctx)
+			return rt, rewriteSubqueryDependenciesForJoin(ctx, outerTree.rhs, outerTree, subQueryInner)
 		}
 		merged, err = tryMergeSubQuery(ctx, outerTree.lhs, subq, subQueryInner, joinPredicates, newMergefunc)
 		if err != nil {
@@ -225,7 +225,7 @@ func tryMergeSubQuery(ctx planningContext, outer, subq queryTree, subQueryInner
 			if err != nil {
 				return nil, err
 			}
-			return rt, rewriteSubqueryDependenciesForJoin(outerTree.lhs, outerTree, subQueryInner, ctx)
+			return rt, rewriteSubqueryDependenciesForJoin(ctx, outerTree.lhs, outerTree, subQueryInner)
 		}
 		merged, err = tryMergeSubQuery(ctx, outerTree.rhs, subq, subQueryInner, joinPredicates, newMergefunc)
 		if err != nil {
@@ -243,7 +243,7 @@ func tryMergeSubQuery(ctx planningContext, outer, subq queryTree, subQueryInner
 
 // outerTree is the joinTree within whose children the subquery lives in
 // the child of joinTree which does not contain the subquery is the otherTree
-func rewriteSubqueryDependenciesForJoin(otherTree queryTree, outerTree *joinTree, subQueryInner *abstract.SubQueryInner, ctx planningContext) error {
+func rewriteSubqueryDependenciesForJoin(ctx *planningContext, otherTree queryTree, outerTree *joinTree, subQueryInner *abstract.SubQueryInner) error {
 	// first we find the other side of the tree by comparing the tableIDs
 	// other side is RHS if the subquery is in the LHS, otherwise it is LHS
 	var rewriteError error
@@ -280,7 +280,7 @@ func rewriteSubqueryDependenciesForJoin(otherTree queryTree, outerTree *joinTree
 	return rewriteError
 }
 
-func mergeSubQuery(ctx planningContext, outer *routeTree, subq *abstract.SubQueryInner) (*routeTree, error) {
+func mergeSubQuery(ctx *planningContext, outer *routeTree, subq *abstract.SubQueryInner) (*routeTree, error) {
 	ctx.sqToReplace[subq.ArgName] = subq.SelectStatement
 	// go over the subquery and add its tables to the one's solved by the route it is merged with
 	// this is needed to so that later when we try to push projections, we get the correct
@@ -404,7 +404,7 @@ func stripDownQuery(from, to sqlparser.SelectStatement) error {
 	return nil
 }
 
-func pushJoinPredicate(ctx planningContext, exprs []sqlparser.Expr, tree queryTree) (queryTree, error) {
+func pushJoinPredicate(ctx *planningContext, exprs []sqlparser.Expr, tree queryTree) (queryTree, error) {
 	switch node := tree.(type) {
 	case *routeTree:
 		plan := node.clone().(*routeTree)
@@ -514,11 +514,11 @@ func breakPredicateInLHSandRHS(
 	return
 }
 
-func mergeOrJoinInner(ctx planningContext, lhs, rhs queryTree, joinPredicates []sqlparser.Expr) (queryTree, error) {
+func mergeOrJoinInner(ctx *planningContext, lhs, rhs queryTree, joinPredicates []sqlparser.Expr) (queryTree, error) {
 	return mergeOrJoin(ctx, lhs, rhs, joinPredicates, true)
 }
 
-func mergeOrJoin(ctx planningContext, lhs, rhs queryTree, joinPredicates []sqlparser.Expr, inner bool) (queryTree, error) {
+func mergeOrJoin(ctx *planningContext, lhs, rhs queryTree, joinPredicates []sqlparser.Expr, inner bool) (queryTree, error) {
 	newTabletSet := lhs.tableID() | rhs.tableID()
 
 	merger := func(a, b *routeTree) (*routeTree, error) {
@@ -550,7 +550,7 @@ type (
 	and removes the two inputs to this cheapest plan and instead adds the join.
 	As an optimization, it first only considers joining tables that have predicates defined between them
 */
-func greedySolve(ctx planningContext, qg *abstract.QueryGraph) (queryTree, error) {
+func greedySolve(ctx *planningContext, qg *abstract.QueryGraph) (queryTree, error) {
 	joinTrees, err := seedPlanList(ctx, qg)
 	planCache := cacheMap{}
 	if err != nil {
@@ -564,7 +564,7 @@ func greedySolve(ctx planningContext, qg *abstract.QueryGraph) (queryTree, error
 	return tree, nil
 }
 
-func mergeJoinTrees(ctx planningContext, qg *abstract.QueryGraph, joinTrees []queryTree, planCache cacheMap, crossJoinsOK bool) (queryTree, error) {
+func mergeJoinTrees(ctx *planningContext, qg *abstract.QueryGraph, joinTrees []queryTree, planCache cacheMap, crossJoinsOK bool) (queryTree, error) {
 	if len(joinTrees) == 0 {
 		return nil, nil
 	}
@@ -594,7 +594,7 @@ func mergeJoinTrees(ctx planningContext, qg *abstract.QueryGraph, joinTrees []qu
 	return joinTrees[0], nil
 }
 
-func (cm cacheMap) getJoinTreeFor(ctx planningContext, lhs, rhs queryTree, joinPredicates []sqlparser.Expr) (queryTree, error) {
+func (cm cacheMap) getJoinTreeFor(ctx *planningContext, lhs, rhs queryTree, joinPredicates []sqlparser.Expr) (queryTree, error) {
 	solves := tableSetPair{left: lhs.tableID(), right: rhs.tableID()}
 	cachedPlan := cm[solves]
 	if cachedPlan != nil {
@@ -610,7 +610,7 @@ func (cm cacheMap) getJoinTreeFor(ctx planningContext, lhs, rhs queryTree, joinP
 }
 
 func findBestJoinTree(
-	ctx planningContext,
+	ctx *planningContext,
 	qg *abstract.QueryGraph,
 	plans []queryTree,
 	planCache cacheMap,
@@ -643,7 +643,7 @@ func findBestJoinTree(
 	return bestPlan, lIdx, rIdx, nil
 }
 
-func leftToRightSolve(ctx planningContext, qg *abstract.QueryGraph) (queryTree, error) {
+func leftToRightSolve(ctx *planningContext, qg *abstract.QueryGraph) (queryTree, error) {
 	plans, err := seedPlanList(ctx, qg)
 	if err != nil {
 		return nil, err
@@ -666,7 +666,7 @@ func leftToRightSolve(ctx planningContext, qg *abstract.QueryGraph) (queryTree,
 }
 
 // seedPlanList returns a routeTree for each table in the qg
-func seedPlanList(ctx planningContext, qg *abstract.QueryGraph) ([]queryTree, error) {
+func seedPlanList(ctx *planningContext, qg *abstract.QueryGraph) ([]queryTree, error) {
 	plans := make([]queryTree, len(qg.Tables))
 
 	// we start by seeding the table with the single routes
@@ -688,7 +688,7 @@ func removeAt(plans []queryTree, idx int) []queryTree {
 	return append(plans[:idx], plans[idx+1:]...)
 }
 
-func createRoutePlan(ctx planningContext, table *abstract.QueryTable, solves semantics.TableSet) (*routeTree, error) {
+func createRoutePlan(ctx *planningContext, table *abstract.QueryTable, solves semantics.TableSet) (*routeTree, error) {
 	if table.IsInfSchema {
 		ks, err := ctx.vschema.AnyKeyspace()
 		if err != nil {
@@ -781,7 +781,7 @@ func createRoutePlan(ctx planningContext, table *abstract.QueryTable, solves sem
 	return plan, nil
 }
 
-func findColumnVindex(ctx planningContext, a *routeTree, exp sqlparser.Expr) vindexes.SingleColumn {
+func findColumnVindex(ctx *planningContext, a *routeTree, exp sqlparser.Expr) vindexes.SingleColumn {
 	_, isCol := exp.(*sqlparser.ColName)
 	if !isCol {
 		return nil
@@ -823,7 +823,7 @@ func findColumnVindex(ctx planningContext, a *routeTree, exp sqlparser.Expr) vin
 	return singCol
 }
 
-func canMergeOnFilter(ctx planningContext, a, b *routeTree, predicate sqlparser.Expr) bool {
+func canMergeOnFilter(ctx *planningContext, a, b *routeTree, predicate sqlparser.Expr) bool {
 	comparison, ok := predicate.(*sqlparser.ComparisonExpr)
 	if !ok {
 		return false
@@ -849,7 +849,7 @@ func canMergeOnFilter(ctx planningContext, a, b *routeTree, predicate sqlparser.
 	return rVindex == lVindex
 }
 
-func canMergeOnFilters(ctx planningContext, a, b *routeTree, joinPredicates []sqlparser.Expr) bool {
+func canMergeOnFilters(ctx *planningContext, a, b *routeTree, joinPredicates []sqlparser.Expr) bool {
 	for _, predicate := range joinPredicates {
 		for _, expr := range sqlparser.SplitAndExpression(nil, predicate) {
 			if canMergeOnFilter(ctx, a, b, expr) {
@@ -862,7 +862,7 @@ func canMergeOnFilters(ctx planningContext, a, b *routeTree, joinPredicates []sq
 
 type mergeFunc func(a, b *routeTree) (*routeTree, error)
 
-func canMergePlans(ctx planningContext, a, b *route) bool {
+func canMergePlans(ctx *planningContext, a, b *route) bool {
 	// this method should be close to tryMerge below. it does the same thing, but on logicalPlans instead of queryTrees
 	if a.eroute.Keyspace.Name != b.eroute.Keyspace.Name {
 		return false
@@ -893,7 +893,7 @@ func canMergePlans(ctx planningContext, a, b *route) bool {
 	return false
 }
 
-func tryMerge(ctx planningContext, a, b queryTree, joinPredicates []sqlparser.Expr, merger mergeFunc) (queryTree, error) {
+func tryMerge(ctx *planningContext, a, b queryTree, joinPredicates []sqlparser.Expr, merger mergeFunc) (queryTree, error) {
 	aRoute, bRoute := queryTreesToRoutes(a.clone(), b.clone())
 	if aRoute == nil || bRoute == nil {
 		return nil, nil
@@ -1084,7 +1084,7 @@ func findTables(deps semantics.TableSet, tables parenTables) (relation, relation
 	return nil, nil, tables
 }
 
-func createRoutePlanForOuter(ctx planningContext, aRoute, bRoute *routeTree, newTabletSet semantics.TableSet, joinPredicates []sqlparser.Expr) *routeTree {
+func createRoutePlanForOuter(ctx *planningContext, aRoute, bRoute *routeTree, newTabletSet semantics.TableSet, joinPredicates []sqlparser.Expr) *routeTree {
 	// create relation slice with all tables
 	tables := bRoute.tables
 	// we are doing an outer join where the outer part contains multiple tables - we have to turn the outer part into a join or two
@@ -1122,7 +1122,7 @@ func createRoutePlanForOuter(ctx planningContext, aRoute, bRoute *routeTree, new
 	}
 }
 
-func gen4ValuesEqual(ctx planningContext, a, b []sqlparser.Expr) bool {
+func gen4ValuesEqual(ctx *planningContext, a, b []sqlparser.Expr) bool {
 	if len(a) != len(b) {
 		return false
 	}
@@ -1138,7 +1138,7 @@ func gen4ValuesEqual(ctx planningContext, a, b []sqlparser.Expr) bool {
 	return true
 }
 
-func gen4ValEqual(ctx planningContext, a, b sqlparser.Expr) bool {
+func gen4ValEqual(ctx *planningContext, a, b sqlparser.Expr) bool {
 	switch a := a.(type) {
 	case *sqlparser.ColName:
 		if b, ok := b.(*sqlparser.ColName); ok {
diff --git a/go/vt/vtgate/planbuilder/routetree.go b/go/vt/vtgate/planbuilder/routetree.go
index 1e117783da..3004f8b9ef 100644
--- a/go/vt/vtgate/planbuilder/routetree.go
+++ b/go/vt/vtgate/planbuilder/routetree.go
@@ -163,7 +163,7 @@ outer:
 
 // addPredicate adds these predicates added to it. if the predicates can help,
 // they will improve the routeOpCode
-func (rp *routeTree) addPredicate(ctx planningContext, predicates ...sqlparser.Expr) error {
+func (rp *routeTree) addPredicate(ctx *planningContext, predicates ...sqlparser.Expr) error {
 	if rp.canImprove() {
 		newVindexFound, err := rp.searchForNewVindexes(ctx, predicates)
 		if err != nil {
@@ -187,7 +187,7 @@ func (rp *routeTree) canImprove() bool {
 	return rp.routeOpCode != engine.SelectNone
 }
 
-func (rp *routeTree) searchForNewVindexes(ctx planningContext, predicates []sqlparser.Expr) (bool, error) {
+func (rp *routeTree) searchForNewVindexes(ctx *planningContext, predicates []sqlparser.Expr) (bool, error) {
 	newVindexFound := false
 	for _, filter := range predicates {
 		switch node := filter.(type) {
@@ -265,7 +265,7 @@ func (rp *routeTree) isImpossibleNotIN(node *sqlparser.ComparisonExpr) bool {
 	return false
 }
 
-func (rp *routeTree) planEqualOp(ctx planningContext, node *sqlparser.ComparisonExpr) (bool, error) {
+func (rp *routeTree) planEqualOp(ctx *planningContext, node *sqlparser.ComparisonExpr) (bool, error) {
 	column, ok := node.Left.(*sqlparser.ColName)
 	other := node.Right
 	vdValue := other
@@ -285,7 +285,7 @@ func (rp *routeTree) planEqualOp(ctx planningContext, node *sqlparser.Comparison
 	return rp.haveMatchingVindex(ctx, node, vdValue, column, *val, equalOrEqualUnique, justTheVindex), err
 }
 
-func (rp *routeTree) planSimpleInOp(ctx planningContext, node *sqlparser.ComparisonExpr, left *sqlparser.ColName) (bool, error) {
+func (rp *routeTree) planSimpleInOp(ctx *planningContext, node *sqlparser.ComparisonExpr, left *sqlparser.ColName) (bool, error) {
 	vdValue := node.Right
 	value, err := rp.makePlanValue(ctx, vdValue)
 	if err != nil || value == nil {
@@ -302,7 +302,7 @@ func (rp *routeTree) planSimpleInOp(ctx planningContext, node *sqlparser.Compari
 	return rp.haveMatchingVindex(ctx, node, vdValue, left, *value, opcode, justTheVindex), err
 }
 
-func (rp *routeTree) planCompositeInOp(ctx planningContext, node *sqlparser.ComparisonExpr, left sqlparser.ValTuple) (bool, error) {
+func (rp *routeTree) planCompositeInOp(ctx *planningContext, node *sqlparser.ComparisonExpr, left sqlparser.ValTuple) (bool, error) {
 	right, rightIsValTuple := node.Right.(sqlparser.ValTuple)
 	if !rightIsValTuple {
 		return false, nil
@@ -310,7 +310,7 @@ func (rp *routeTree) planCompositeInOp(ctx planningContext, node *sqlparser.Comp
 	return rp.planCompositeInOpRecursive(ctx, node, left, right, nil)
 }
 
-func (rp *routeTree) planCompositeInOpRecursive(ctx planningContext, node *sqlparser.ComparisonExpr, left, right sqlparser.ValTuple, coordinates []int) (bool, error) {
+func (rp *routeTree) planCompositeInOpRecursive(ctx *planningContext, node *sqlparser.ComparisonExpr, left, right sqlparser.ValTuple, coordinates []int) (bool, error) {
 	foundVindex := false
 	cindex := len(coordinates)
 	coordinates = append(coordinates, 0)
@@ -355,7 +355,7 @@ func (rp *routeTree) planCompositeInOpRecursive(ctx planningContext, node *sqlpa
 	return foundVindex, nil
 }
 
-func (rp *routeTree) planInOp(ctx planningContext, node *sqlparser.ComparisonExpr) (bool, error) {
+func (rp *routeTree) planInOp(ctx *planningContext, node *sqlparser.ComparisonExpr) (bool, error) {
 	switch left := node.Left.(type) {
 	case *sqlparser.ColName:
 		return rp.planSimpleInOp(ctx, node, left)
@@ -365,7 +365,7 @@ func (rp *routeTree) planInOp(ctx planningContext, node *sqlparser.ComparisonExp
 	return false, nil
 }
 
-func (rp *routeTree) planLikeOp(ctx planningContext, node *sqlparser.ComparisonExpr) (bool, error) {
+func (rp *routeTree) planLikeOp(ctx *planningContext, node *sqlparser.ComparisonExpr) (bool, error) {
 	column, ok := node.Left.(*sqlparser.ColName)
 	if !ok {
 		return false, nil
@@ -390,7 +390,7 @@ func (rp *routeTree) planLikeOp(ctx planningContext, node *sqlparser.ComparisonE
 	return rp.haveMatchingVindex(ctx, node, vdValue, column, *val, selectEqual, vdx), err
 }
 
-func (rp *routeTree) planIsExpr(ctx planningContext, node *sqlparser.IsExpr) (bool, error) {
+func (rp *routeTree) planIsExpr(ctx *planningContext, node *sqlparser.IsExpr) (bool, error) {
 	// we only handle IS NULL correct. IsExpr can contain other expressions as well
 	if node.Right != sqlparser.IsNullOp {
 		return false, nil
@@ -413,7 +413,7 @@ func (rp *routeTree) planIsExpr(ctx planningContext, node *sqlparser.IsExpr) (bo
 // method will stops and return nil values.
 // Otherwise, the method will try to apply makePlanValue for any equality the sqlparser.Expr n has.
 // The first PlanValue that is successfully produced will be returned.
-func (rp *routeTree) makePlanValue(ctx planningContext, n sqlparser.Expr) (*sqltypes.PlanValue, error) {
+func (rp *routeTree) makePlanValue(ctx *planningContext, n sqlparser.Expr) (*sqltypes.PlanValue, error) {
 	if ctx.isSubQueryToReplace(argumentName(n)) {
 		return nil, nil
 	}
@@ -452,7 +452,7 @@ func allNotNil(s []sqlparser.Expr) bool {
 }
 
 func (rp *routeTree) haveMatchingVindex(
-	ctx planningContext,
+	ctx *planningContext,
 	node sqlparser.Expr,
 	valueExpr sqlparser.Expr,
 	column *sqlparser.ColName,
@@ -564,7 +564,7 @@ func (rp *routeTree) Predicates() sqlparser.Expr {
 }
 
 // resetRoutingSelections resets all vindex selections and replans this routeTree
-func (rp *routeTree) resetRoutingSelections(ctx planningContext) error {
+func (rp *routeTree) resetRoutingSelections(ctx *planningContext) error {
 
 	vschemaTable := rp.tables[0].(*routeTable).vtable
 


Test patch:
diff --git a/go/vt/vtgate/planbuilder/route_planning_test.go b/go/vt/vtgate/planbuilder/route_planning_test.go
index 97a6e63d70..4f2a72bdc1 100644
--- a/go/vt/vtgate/planbuilder/route_planning_test.go
+++ b/go/vt/vtgate/planbuilder/route_planning_test.go
@@ -102,7 +102,7 @@ func TestMergeJoins(t *testing.T) {
 	}}
 	for i, tc := range tests {
 		t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
-			result, _ := tryMerge(planningContext{semTable: semantics.NewSemTable()}, tc.l, tc.r, tc.predicates, nil) // fakeMerger ? how to test this
+			result, _ := tryMerge(&planningContext{semTable: semantics.NewSemTable()}, tc.l, tc.r, tc.predicates, nil) // fakeMerger ? how to test this
 			assert.Equal(t, tc.expected, result)
 		})
 	}
@@ -167,7 +167,7 @@ func TestCreateRoutePlanForOuter(t *testing.T) {
 		predicates:  []sqlparser.Expr{equals(col1, col2)},
 	}
 	semTable := semantics.NewSemTable()
-	merge, _ := tryMerge(planningContext{semTable: semTable}, a, b, []sqlparser.Expr{}, fakeMerger)
+	merge, _ := tryMerge(&planningContext{semTable: semTable}, a, b, []sqlparser.Expr{}, fakeMerger)
 	assert.NotNil(merge)
 }