-
Notifications
You must be signed in to change notification settings - Fork 219
Expand file tree
/
Copy pathplan_node.go
More file actions
112 lines (100 loc) · 2.49 KB
/
plan_node.go
File metadata and controls
112 lines (100 loc) · 2.49 KB
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/*
* Radon
*
* Copyright 2018 The Radon Authors.
* Code is licensed under the GPLv3.
*
*/
package planner
import (
"xcontext"
"github.com/xelabs/go-mysqlstack/sqlparser"
)
// PlanNode interface.
type PlanNode interface {
buildQuery(tbInfos map[string]*TableInfo)
Children() *PlanTree
getFields() []selectTuple
getReferredTables() map[string]*TableInfo
GetQuery() []xcontext.QueryTuple
pushOrderBy(sel sqlparser.SelectStatement) error
pushLimit(sel sqlparser.SelectStatement) error
}
// SelectNode interface.
type SelectNode interface {
PlanNode
pushFilter(filters []filterTuple) error
setParent(p SelectNode)
setWhereFilter(filter filterTuple)
setNoTableFilter(exprs []sqlparser.Expr)
setParenthese(hasParen bool)
pushEqualCmpr(joins []joinTuple) SelectNode
calcRoute() (SelectNode, error)
pushSelectExprs(fields, groups []selectTuple, sel *sqlparser.Select, aggTyp aggrType) error
pushSelectExpr(field selectTuple) (int, error)
pushHaving(havings []filterTuple) error
pushMisc(sel *sqlparser.Select)
reOrder(int)
Order() int
}
// findLCA get the two plannode's lowest common ancestors node.
func findLCA(h, p1, p2 SelectNode) SelectNode {
if p1 == h || p2 == h {
return h
}
jn, ok := h.(*JoinNode)
if !ok {
return nil
}
pl := findLCA(jn.Left, p1, p2)
pr := findLCA(jn.Right, p1, p2)
if pl != nil && pr != nil {
return jn
}
if pl == nil {
return pr
}
return pl
}
// getOneTableInfo get a tableInfo.
func getOneTableInfo(tbInfos map[string]*TableInfo) (string, *TableInfo) {
for tb, tbInfo := range tbInfos {
return tb, tbInfo
}
return "", nil
}
// procure requests for the specified column from the plan
// and returns the join var name for it.
func procure(tbInfos map[string]*TableInfo, col *sqlparser.ColName) string {
var joinVar string
field := col.Name.String()
table := col.Qualifier.Name.String()
tbInfo := tbInfos[table]
node := tbInfo.parent
jn := node.parent.(*JoinNode)
joinVar = col.Qualifier.Name.CompliantName() + "_" + col.Name.CompliantName()
if _, ok := jn.Vars[joinVar]; ok {
return joinVar
}
tuples := node.getFields()
index := -1
for i, tuple := range tuples {
if tuple.isCol {
if field == tuple.field && table == tuple.referTables[0] {
index = i
break
}
}
}
// key not in the select fields.
if index == -1 {
tuple := selectTuple{
expr: &sqlparser.AliasedExpr{Expr: col},
field: field,
referTables: []string{table},
}
index, _ = node.pushSelectExpr(tuple)
}
jn.Vars[joinVar] = index
return joinVar
}