-
Notifications
You must be signed in to change notification settings - Fork 124
/
Copy pathcross_join.go
112 lines (88 loc) · 1.95 KB
/
cross_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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package plan
import (
"io"
"github.com/gitql/gitql/sql"
)
type CrossJoin struct {
BinaryNode
}
func NewCrossJoin(left sql.Node, right sql.Node) *CrossJoin {
return &CrossJoin{
BinaryNode: BinaryNode{
Left: left,
Right: right,
},
}
}
func (p *CrossJoin) Schema() sql.Schema {
return append(p.Left.Schema(), p.Right.Schema()...)
}
func (p *CrossJoin) Resolved() bool {
return p.Left.Resolved() && p.Right.Resolved()
}
func (p *CrossJoin) RowIter() (sql.RowIter, error) {
li, err := p.Left.RowIter()
if err != nil {
return nil, err
}
ri, err := p.Right.RowIter()
if err != nil {
return nil, err
}
return &crossJoinIterator{
li: li,
ri: ri,
}, nil
}
func (p *CrossJoin) TransformUp(f func(sql.Node) sql.Node) sql.Node {
ln := p.BinaryNode.Left.TransformUp(f)
rn := p.BinaryNode.Right.TransformUp(f)
n := NewCrossJoin(ln, rn)
return f(n)
}
func (p *CrossJoin) TransformExpressionsUp(f func(sql.Expression) sql.Expression) sql.Node {
ln := p.BinaryNode.Left.TransformExpressionsUp(f)
rn := p.BinaryNode.Right.TransformExpressionsUp(f)
return NewCrossJoin(ln, rn)
}
type crossJoinIterator struct {
li sql.RowIter
ri sql.RowIter
// TODO use a method to reset right iterator in order to not duplicate rows into memory
rightRows []sql.Row
index int
leftRow sql.Row
}
func (i *crossJoinIterator) Next() (sql.Row, error) {
for {
if i.leftRow == nil {
lr, err := i.li.Next()
if err != nil {
return nil, err
}
i.leftRow = lr
}
if len(i.rightRows) == 0 {
err := i.fillRows()
if err != nil && err != io.EOF {
return nil, err
}
}
if i.index <= len(i.rightRows)-1 {
fields := append(i.leftRow.Fields(), i.rightRows[i.index].Fields()...)
i.index++
return sql.NewMemoryRow(fields...), nil
}
i.index = 0
i.leftRow = nil
}
}
func (i *crossJoinIterator) fillRows() error {
for {
rr, err := i.ri.Next()
if err != nil {
return err
}
i.rightRows = append(i.rightRows, rr)
}
}