vitess.io/vitess@v0.16.2/go/vt/vtgate/planbuilder/semi_join.go (about) 1 /* 2 Copyright 2021 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 "vitess.io/vitess/go/vt/sqlparser" 21 "vitess.io/vitess/go/vt/vterrors" 22 "vitess.io/vitess/go/vt/vtgate/engine" 23 "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" 24 "vitess.io/vitess/go/vt/vtgate/semantics" 25 ) 26 27 var _ logicalPlan = (*semiJoin)(nil) 28 29 // semiJoin is the logicalPlan for engine.SemiJoin. 30 // This gets built if a rhs is correlated and can 31 // be pulled out but requires some variables to be supplied from outside. 32 type semiJoin struct { 33 gen4Plan 34 rhs logicalPlan 35 lhs logicalPlan 36 cols []int 37 38 vars map[string]int 39 40 // LHSColumns are the columns from the LHS used for the join. 41 // These are the same columns pushed on the LHS that are now used in the vars field 42 LHSColumns []*sqlparser.ColName 43 } 44 45 // newSemiJoin builds a new semiJoin. 46 func newSemiJoin(lhs, rhs logicalPlan, vars map[string]int, lhsCols []*sqlparser.ColName) *semiJoin { 47 return &semiJoin{ 48 rhs: rhs, 49 lhs: lhs, 50 vars: vars, 51 LHSColumns: lhsCols, 52 } 53 } 54 55 // Primitive implements the logicalPlan interface 56 func (ps *semiJoin) Primitive() engine.Primitive { 57 return &engine.SemiJoin{ 58 Left: ps.lhs.Primitive(), 59 Right: ps.rhs.Primitive(), 60 Vars: ps.vars, 61 Cols: ps.cols, 62 } 63 } 64 65 // WireupGen4 implements the logicalPlan interface 66 func (ps *semiJoin) WireupGen4(ctx *plancontext.PlanningContext) error { 67 if err := ps.lhs.WireupGen4(ctx); err != nil { 68 return err 69 } 70 return ps.rhs.WireupGen4(ctx) 71 } 72 73 // Rewrite implements the logicalPlan interface 74 func (ps *semiJoin) Rewrite(inputs ...logicalPlan) error { 75 if len(inputs) != 2 { 76 return vterrors.VT13001("semiJoin: wrong number of inputs") 77 } 78 ps.lhs = inputs[0] 79 ps.rhs = inputs[1] 80 return nil 81 } 82 83 // ContainsTables implements the logicalPlan interface 84 func (ps *semiJoin) ContainsTables() semantics.TableSet { 85 return ps.lhs.ContainsTables().Merge(ps.rhs.ContainsTables()) 86 } 87 88 // Inputs implements the logicalPlan interface 89 func (ps *semiJoin) Inputs() []logicalPlan { 90 return []logicalPlan{ps.lhs, ps.rhs} 91 } 92 93 // OutputColumns implements the logicalPlan interface 94 func (ps *semiJoin) OutputColumns() []sqlparser.SelectExpr { 95 return ps.lhs.OutputColumns() 96 }