-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsubquery.go
More file actions
160 lines (130 loc) · 4.6 KB
/
subquery.go
File metadata and controls
160 lines (130 loc) · 4.6 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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
package expressions
import (
"bytes"
"fmt"
"github.com/efritz/gostgres/internal/execution/serialization"
"github.com/efritz/gostgres/internal/shared/impls"
"github.com/efritz/gostgres/internal/shared/rows"
"github.com/efritz/gostgres/internal/shared/scan"
)
type Query interface {
Serialize(w serialization.IndentWriter)
Optimize()
Scanner(ctx impls.Context) (scan.RowScanner, error)
}
//
//
//
type existsSubqueryExpression struct {
subquery Query
}
func NewExistsSubqueryExpression(subquery Query) impls.Expression {
return existsSubqueryExpression{
subquery: subquery,
}
}
func (e existsSubqueryExpression) String() string { return "" } // TODO
func (e existsSubqueryExpression) Equal(other impls.Expression) bool { return false } // TODO
func (e existsSubqueryExpression) Children() []impls.Expression { return nil } // TODO
func (e existsSubqueryExpression) Fold() impls.Expression { return e } // TODO
func (e existsSubqueryExpression) Map(f func(impls.Expression) impls.Expression) impls.Expression {
return e
} // TODO
func (e existsSubqueryExpression) ValueFrom(ctx impls.Context, row rows.Row) (any, error) {
// TODO - want to pull this out and do optimization before the enclosing query is executed
// TODO - need to pull out serialization into separate parts in the explain output as well
ctx.Log("Optimizing subquery")
e.subquery.Optimize()
var buf bytes.Buffer
w := serialization.NewIndentWriter(&buf)
e.subquery.Serialize(w)
ctx.Log("%s", buf.String())
ctx.Log("Preparing subquery over %s", row)
s, err := e.subquery.Scanner(ctx.WithOuterRow(row))
if err != nil {
return nil, err
}
ctx.Log("Scanning subquery")
if _, err := s.Scan(); err != nil {
if err != scan.ErrNoRows {
return nil, err
}
return false, err
}
return true, nil
}
//
//
//
type anySubqueryExpression struct {
expression impls.Expression
op string // TODO
subquery Query
}
func NewAnySubqueryExpression(expression impls.Expression, op string, subquery Query) impls.Expression {
return anySubqueryExpression{
expression: expression,
op: op,
subquery: subquery,
}
}
func (e anySubqueryExpression) String() string { return "" } // TODO
func (e anySubqueryExpression) Equal(other impls.Expression) bool { return false } // TODO
func (e anySubqueryExpression) Children() []impls.Expression { return nil } // TODO
func (e anySubqueryExpression) Fold() impls.Expression { return e } // TODO
func (e anySubqueryExpression) Map(f func(impls.Expression) impls.Expression) impls.Expression {
return e
} // TODO
func (e anySubqueryExpression) ValueFrom(ctx impls.Context, row rows.Row) (any, error) {
return nil, fmt.Errorf("unimplemented") // TODO
}
//
//
//
type allSubqueryExpression struct {
expression impls.Expression
op string // TODO
subquery Query
}
func NewAllSubqueryExpression(expression impls.Expression, op string, subquery Query) impls.Expression {
return allSubqueryExpression{
expression: expression,
op: op,
subquery: subquery,
}
}
func (e allSubqueryExpression) String() string { return "" } // TODO
func (e allSubqueryExpression) Equal(other impls.Expression) bool { return false } // TODO
func (e allSubqueryExpression) Children() []impls.Expression { return nil } // TODO
func (e allSubqueryExpression) Fold() impls.Expression { return e } // TODO
func (e allSubqueryExpression) Map(f func(impls.Expression) impls.Expression) impls.Expression {
return e
} // TODO
func (e allSubqueryExpression) ValueFrom(ctx impls.Context, row rows.Row) (any, error) {
return nil, fmt.Errorf("unimplemented") // TODO
}
//
//
//
type opSubqueryExpression struct {
expression impls.Expression
op string // TODO
subquery Query
}
func NewOpSubqueryExpression(expression impls.Expression, op string, subquery Query) impls.Expression {
return opSubqueryExpression{
expression: expression,
op: op,
subquery: subquery,
}
}
func (e opSubqueryExpression) String() string { return "" } // TODO
func (e opSubqueryExpression) Equal(other impls.Expression) bool { return false } // TODO
func (e opSubqueryExpression) Children() []impls.Expression { return nil } // TODO
func (e opSubqueryExpression) Fold() impls.Expression { return e } // TODO
func (e opSubqueryExpression) Map(f func(impls.Expression) impls.Expression) impls.Expression {
return e
} // TODO
func (e opSubqueryExpression) ValueFrom(ctx impls.Context, row rows.Row) (any, error) {
return nil, fmt.Errorf("unimplemented") // TODO
}