forked from src-d/go-mysql-server
/
core.go
208 lines (181 loc) · 6.96 KB
/
core.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
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
package sql // import "gopkg.in/src-d/go-mysql-server.v0/sql"
import (
"crypto/sha1"
"encoding/hex"
"fmt"
"gopkg.in/src-d/go-errors.v1"
)
var (
// ErrInvalidType is thrown when there is an unexpected type at some part of
// the execution tree.
ErrInvalidType = errors.NewKind("invalid type: %s")
// ErrTableAlreadyExists is thrown when someone tries to create a
// table with a name of an existing one
ErrTableAlreadyExists = errors.NewKind("table with name %s already exists")
// ErrTableNotFound is returned when the table is not available from the
// current scope.
ErrTableNotFound = errors.NewKind("table not found: %s")
//ErrUnexpectedRowLength is thrown when the obtained row has more columns than the schema
ErrUnexpectedRowLength = errors.NewKind("expected %d values, got %d")
)
// Nameable is something that has a name.
type Nameable interface {
// Name returns the name.
Name() string
}
// Tableable is something that has a table.
type Tableable interface {
// Table returns the table name.
Table() string
}
// Resolvable is something that can be resolved or not.
type Resolvable interface {
// Resolved returns whether the node is resolved.
Resolved() bool
}
// Transformable is a node which can be transformed.
type Transformable interface {
// TransformUp transforms all nodes and returns the result of this transformation.
// Transformation is not propagated to subqueries.
TransformUp(TransformNodeFunc) (Node, error)
// TransformExpressionsUp transforms all expressions inside the node and all its
// children and returns a node with the result of the transformations.
// Transformation is not propagated to subqueries.
TransformExpressionsUp(TransformExprFunc) (Node, error)
}
// TransformNodeFunc is a function that given a node will return that node
// as is or transformed along with an error, if any.
type TransformNodeFunc func(Node) (Node, error)
// TransformExprFunc is a function that given an expression will return that
// expression as is or transformed along with an error, if any.
type TransformExprFunc func(Expression) (Expression, error)
// Expression is a combination of one or more SQL expressions.
type Expression interface {
Resolvable
fmt.Stringer
// Type returns the expression type.
Type() Type
// IsNullable returns whether the expression can be null.
IsNullable() bool
// Eval evaluates the given row and returns a result.
Eval(*Context, Row) (interface{}, error)
// TransformUp transforms the expression and all its children with the
// given transform function.
TransformUp(TransformExprFunc) (Expression, error)
// Children returns the children expressions of this expression.
Children() []Expression
}
// ExpressionHash is a SHA-1 checksum
type ExpressionHash []byte
// NewExpressionHash returns a new SHA1 hash for given Expression instance.
// SHA1 checksum will be calculated based on ex.String().
func NewExpressionHash(ex Expression) ExpressionHash {
h := sha1.Sum([]byte(ex.String()))
return ExpressionHash(h[:])
}
// DecodeExpressionHash decodes a hexadecimal string to ExpressionHash
func DecodeExpressionHash(hexstr string) (ExpressionHash, error) {
h, err := hex.DecodeString(hexstr)
if err != nil {
return nil, err
}
return ExpressionHash(h), nil
}
// EncodeExpressionHash encodes an ExpressionHash to hexadecimal string
func EncodeExpressionHash(h ExpressionHash) string {
return hex.EncodeToString(h)
}
// Aggregation implements an aggregation expression, where an
// aggregation buffer is created for each grouping (NewBuffer) and rows in the
// grouping are fed to the buffer (Update). Multiple buffers can be merged
// (Merge), making partial aggregations possible.
// Note that Eval must be called with the final aggregation buffer in order to
// get the final result.
type Aggregation interface {
Expression
// NewBuffer creates a new aggregation buffer and returns it as a Row.
NewBuffer() Row
// Update updates the given buffer with the given row.
Update(ctx *Context, buffer, row Row) error
// Merge merges a partial buffer into a global one.
Merge(ctx *Context, buffer, partial Row) error
}
// Node is a node in the execution plan tree.
type Node interface {
Resolvable
Transformable
fmt.Stringer
// Schema of the node.
Schema() Schema
// Children nodes.
Children() []Node
// RowIter produces a row iterator from this node.
RowIter(*Context) (RowIter, error)
}
// Expressioner is a node that contains expressions.
type Expressioner interface {
// Expressions returns the list of expressions contained by the node.
Expressions() []Expression
// TransformExpressions applies for each expression in this node
// the expression's TransformUp method with the given function, and
// return a new node with the transformed expressions.
TransformExpressions(TransformExprFunc) (Node, error)
}
// Table represents a SQL table.
type Table interface {
Nameable
Node
}
// Indexable represents a table that supports being indexed and receiving
// indexes to be able to speed up its execution.
type Indexable interface {
PushdownProjectionAndFiltersTable
// IndexKeyValueIter returns an iterator with the values of each row in
// the table for the given column names.
IndexKeyValueIter(ctx *Context, colNames []string) (IndexKeyValueIter, error)
// WithProjectFiltersAndIndex is meant to be called instead of RowIter
// method of the table. Returns a new iterator given the columns,
// filters and the index so the table can improve its speed instead of
// making a full scan.
WithProjectFiltersAndIndex(
ctx *Context,
columns, filters []Expression,
index IndexValueIter,
) (RowIter, error)
}
// PushdownProjectionTable is a table that can produce a specific RowIter
// that's more optimized given the columns that are projected.
type PushdownProjectionTable interface {
Table
// WithProject replaces the RowIter method of the table and returns a new
// row iterator given the column names that are projected.
WithProject(ctx *Context, colNames []string) (RowIter, error)
}
// PushdownProjectionAndFiltersTable is a table that can produce a specific
// RowIter that's more optimized given the columns that are projected and
// the filters for this table.
type PushdownProjectionAndFiltersTable interface {
Table
// HandledFilters returns the subset of filters that can be handled by this
// table.
HandledFilters(filters []Expression) []Expression
// WithProjectAndFilters replaces the RowIter method of the table and
// return a new row iterator given the column names that are projected
// and the filters applied to this table.
WithProjectAndFilters(ctx *Context, columns, filters []Expression) (RowIter, error)
}
// Inserter allow rows to be inserted in them.
type Inserter interface {
// Insert the given row.
Insert(row Row) error
}
// Database represents the database.
type Database interface {
Nameable
// Tables returns the information of all tables.
Tables() map[string]Table
}
// Alterable should be implemented by databases that can handle DDL statements
type Alterable interface {
Create(name string, schema Schema) error
}