/
semi_join.go
97 lines (81 loc) · 2.72 KB
/
semi_join.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/*
Copyright 2021 The Vitess Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package planbuilder
import (
vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc"
"vitess.io/vitess/go/vt/sqlparser"
"vitess.io/vitess/go/vt/vterrors"
"vitess.io/vitess/go/vt/vtgate/engine"
"vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext"
"vitess.io/vitess/go/vt/vtgate/semantics"
)
var _ logicalPlan = (*semiJoin)(nil)
// semiJoin is the logicalPlan for engine.SemiJoin.
// This gets built if a rhs is correlated and can
// be pulled out but requires some variables to be supplied from outside.
type semiJoin struct {
gen4Plan
rhs logicalPlan
lhs logicalPlan
cols []int
vars map[string]int
// LHSColumns are the columns from the LHS used for the join.
// These are the same columns pushed on the LHS that are now used in the vars field
LHSColumns []*sqlparser.ColName
}
// newSemiJoin builds a new semiJoin.
func newSemiJoin(lhs, rhs logicalPlan, vars map[string]int, lhsCols []*sqlparser.ColName) *semiJoin {
return &semiJoin{
rhs: rhs,
lhs: lhs,
vars: vars,
LHSColumns: lhsCols,
}
}
// Primitive implements the logicalPlan interface
func (ps *semiJoin) Primitive() engine.Primitive {
return &engine.SemiJoin{
Left: ps.lhs.Primitive(),
Right: ps.rhs.Primitive(),
Vars: ps.vars,
Cols: ps.cols,
}
}
// WireupGen4 implements the logicalPlan interface
func (ps *semiJoin) WireupGen4(ctx *plancontext.PlanningContext) error {
if err := ps.lhs.WireupGen4(ctx); err != nil {
return err
}
return ps.rhs.WireupGen4(ctx)
}
// Rewrite implements the logicalPlan interface
func (ps *semiJoin) Rewrite(inputs ...logicalPlan) error {
if len(inputs) != 2 {
return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "semiJoin: wrong number of inputs")
}
ps.lhs = inputs[0]
ps.rhs = inputs[1]
return nil
}
// ContainsTables implements the logicalPlan interface
func (ps *semiJoin) ContainsTables() semantics.TableSet {
return ps.lhs.ContainsTables().Merge(ps.rhs.ContainsTables())
}
// Inputs implements the logicalPlan interface
func (ps *semiJoin) Inputs() []logicalPlan {
return []logicalPlan{ps.lhs, ps.rhs}
}
// OutputColumns implements the logicalPlan interface
func (ps *semiJoin) OutputColumns() []sqlparser.SelectExpr {
return ps.lhs.OutputColumns()
}