vitess.io/vitess@v0.16.2/go/vt/vtgate/planbuilder/jointab.go (about) 1 /* 2 Copyright 2019 The Vitess Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package planbuilder 18 19 import ( 20 "fmt" 21 22 "vitess.io/vitess/go/vt/sqlparser" 23 ) 24 25 // jointab manages procurement and naming of join 26 // variables across primitives. 27 type jointab struct { 28 refs map[*column]string 29 reserved *sqlparser.ReservedVars 30 varIndex int 31 } 32 33 // newJointab creates a new jointab for the current plan 34 // being built. It also needs the current list of bind vars 35 // used in the original query to make sure that the names 36 // it generates don't collide with those already in use. 37 func newJointab(reserved *sqlparser.ReservedVars) *jointab { 38 return &jointab{ 39 refs: make(map[*column]string), 40 reserved: reserved, 41 } 42 } 43 44 // Procure requests for the specified column from the plan 45 // and returns the join var name for it. 46 func (jt *jointab) Procure(plan logicalPlan, col *sqlparser.ColName, to int) string { 47 from, joinVar := jt.Lookup(col) 48 // If joinVar is empty, generate a unique name. 49 if joinVar == "" { 50 joinVar = jt.reserved.ReserveColName(col) 51 jt.refs[col.Metadata.(*column)] = joinVar 52 } 53 plan.SupplyVar(from, to, col, joinVar) 54 return joinVar 55 } 56 57 // GenerateSubqueryVars generates substitution variable names for 58 // a subquery. It returns two names based on: __sq, __sq_has_values. 59 // The appropriate names can be used for substitution 60 // depending on the scenario. 61 func (jt *jointab) GenerateSubqueryVars() (sq, hasValues string) { 62 for { 63 jt.varIndex++ 64 var1 := fmt.Sprintf("__sq%d", jt.varIndex) 65 var2 := fmt.Sprintf("__sq_has_values%d", jt.varIndex) 66 if !jt.reserved.ReserveAll(var1, var2) { 67 continue 68 } 69 return var1, var2 70 } 71 } 72 73 // Lookup returns the order of the route that supplies the column and 74 // the join var name if one has already been assigned for it. 75 func (jt *jointab) Lookup(col *sqlparser.ColName) (order int, joinVar string) { 76 c := col.Metadata.(*column) 77 return c.Origin().Order(), jt.refs[c] 78 }