Skip to content

Commit 0584509

Browse files
authored
Merge pull request #186 from erizocosmico/feature/filters-in
gitquery: support IN selectors
2 parents 7f0a1d9 + 7deb139 commit 0584509

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+2750
-1340
lines changed

Gopkg.lock

Lines changed: 4 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Gopkg.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[[constraint]]
22
name = "gopkg.in/src-d/go-mysql-server.v0"
3-
revision = "d517220df27cf67ae67a21b69f5d96118464327c"
3+
revision = "6a563e1a2bcdd038830ed6039fb770025fb325c8"
44

55
[[constraint]]
66
name = "github.com/jessevdk/go-flags"

blobs.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,11 @@ func (blobsTable) Schema() sql.Schema {
5757
return blobsSchema
5858
}
5959

60-
func (r *blobsTable) TransformUp(f func(sql.Node) (sql.Node, error)) (sql.Node, error) {
60+
func (r *blobsTable) TransformUp(f sql.TransformNodeFunc) (sql.Node, error) {
6161
return f(r)
6262
}
6363

64-
func (r *blobsTable) TransformExpressionsUp(f func(sql.Expression) (sql.Expression, error)) (sql.Node, error) {
64+
func (r *blobsTable) TransformExpressionsUp(f sql.TransformExprFunc) (sql.Node, error) {
6565
return r, nil
6666
}
6767

cmd/gitquery/server.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func (c *CmdServer) buildDatabase() error {
4343
}
4444

4545
c.engine.AddDatabase(gitquery.NewDatabase(c.name, c.pool))
46-
function.Register(c.engine.Catalog)
46+
c.engine.Catalog.RegisterFunctions(function.Functions)
4747
return nil
4848
}
4949

commits.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,11 @@ func (commitsTable) Schema() sql.Schema {
4747
return commitsSchema
4848
}
4949

50-
func (r *commitsTable) TransformUp(f func(sql.Node) (sql.Node, error)) (sql.Node, error) {
50+
func (r *commitsTable) TransformUp(f sql.TransformNodeFunc) (sql.Node, error) {
5151
return f(r)
5252
}
5353

54-
func (r *commitsTable) TransformExpressionsUp(f func(sql.Expression) (sql.Expression, error)) (sql.Node, error) {
54+
func (r *commitsTable) TransformExpressionsUp(f sql.TransformExprFunc) (sql.Node, error) {
5555
return r, nil
5656
}
5757

filters.go

Lines changed: 81 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,30 @@ func canHandleEquals(schema sql.Schema, tableName string, eq *expression.Equals)
9999
return false
100100
}
101101

102+
// canHandleIn returns whether the given in expression can be handled as a selector.
103+
// For that to happen, the left side must be a GetField expression and the right
104+
// side must be a Tuple expression with only Literal expressions as children.
105+
// The GetField expr must exist in the schema and match the given table name.
106+
func canHandleIn(schema sql.Schema, tableName string, in *expression.In) bool {
107+
left, ok := in.Left().(*expression.GetField)
108+
if !ok || !schema.Contains(left.Name()) || left.Table() != tableName {
109+
return false
110+
}
111+
112+
right, ok := in.Right().(expression.Tuple)
113+
if !ok {
114+
return false
115+
}
116+
117+
for _, elem := range right {
118+
if _, ok := elem.(*expression.Literal); !ok {
119+
return false
120+
}
121+
}
122+
123+
return true
124+
}
125+
102126
// getEqualityValues returns the field and value of the literal in the
103127
// given equality expression.
104128
func getEqualityValues(eq *expression.Equals) (string, interface{}, error) {
@@ -119,6 +143,36 @@ func getEqualityValues(eq *expression.Equals) (string, interface{}, error) {
119143
return "", "", nil
120144
}
121145

146+
// getInValues returns the field and values of the literals in the
147+
// given in expression.
148+
func getInValues(in *expression.In) (string, []interface{}, error) {
149+
left, ok := in.Left().(*expression.GetField)
150+
if !ok {
151+
return "", nil, nil
152+
}
153+
154+
right, ok := in.Right().(expression.Tuple)
155+
if !ok {
156+
return "", nil, nil
157+
}
158+
159+
var values = make([]interface{}, len(right))
160+
for i, elem := range right {
161+
lit, ok := elem.(*expression.Literal)
162+
if !ok {
163+
return "", nil, nil
164+
}
165+
166+
var err error
167+
values[i], err = lit.Eval(nil, nil)
168+
if err != nil {
169+
return "", nil, err
170+
}
171+
}
172+
173+
return left.Name(), values, nil
174+
}
175+
122176
// handledFilters returns the set of filters that can be handled with the given
123177
// schema. That is, all expressions that don't have GetField expressions that
124178
// don't belong to the given schema.
@@ -174,15 +228,36 @@ func classifyFilters(
174228
continue
175229
}
176230
}
177-
// TODO: handle IN when it's implemented
231+
case *expression.In:
232+
if canHandleIn(schema, table, f) {
233+
field, vals, err := getInValues(f)
234+
if err != nil {
235+
return nil, nil, err
236+
}
237+
238+
if stringContains(handledCols, field) {
239+
selectors[field] = append(selectors[field], selector(vals))
240+
continue
241+
}
242+
}
178243
case *expression.Or:
179244
exprs := unfoldOrs(f)
180245
// check all unfolded exprs can be handled, if not we have to
181246
// resort to treating them as conditions
182247
valid := true
183248
for _, e := range exprs {
184-
f, ok := e.(*expression.Equals)
185-
if !ok || !canHandleEquals(schema, table, f) {
249+
switch e := e.(type) {
250+
case *expression.Equals:
251+
if !canHandleEquals(schema, table, e) {
252+
valid = false
253+
break
254+
}
255+
case *expression.In:
256+
if !canHandleIn(schema, table, e) {
257+
valid = false
258+
break
259+
}
260+
default:
186261
valid = false
187262
break
188263
}
@@ -200,11 +275,9 @@ func classifyFilters(
200275
}
201276

202277
for k, v := range sels {
203-
var values = make(selector, len(v))
204-
for i, val := range v {
205-
if len(val) > 0 {
206-
values[i] = val[0]
207-
}
278+
var values selector
279+
for _, vals := range v {
280+
values = append(values, vals...)
208281
}
209282
selectors[k] = append(selectors[k], values)
210283
}

0 commit comments

Comments
 (0)