Skip to content
This repository was archived by the owner on Jan 28, 2021. It is now read-only.

Commit f4a1ef5

Browse files
author
kuba--
committed
Check projection aliases when assigned to index.
Signed-off-by: kuba-- <[email protected]>
1 parent 0093a75 commit f4a1ef5

File tree

5 files changed

+77
-26
lines changed

5 files changed

+77
-26
lines changed

engine_test.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111
"testing"
1212
"time"
1313

14-
"gopkg.in/src-d/go-mysql-server.v0"
14+
sqle "gopkg.in/src-d/go-mysql-server.v0"
1515
"gopkg.in/src-d/go-mysql-server.v0/auth"
1616
"gopkg.in/src-d/go-mysql-server.v0/mem"
1717
"gopkg.in/src-d/go-mysql-server.v0/sql"
@@ -1724,6 +1724,25 @@ func TestIndexes(t *testing.T) {
17241724
"SELECT * FROM mytable WHERE i = 1 AND i = 2",
17251725
([]sql.Row)(nil),
17261726
},
1727+
{
1728+
"SELECT i as mytable_i FROM mytable WHERE mytable_i = 2",
1729+
[]sql.Row{
1730+
{int64(2)},
1731+
},
1732+
},
1733+
{
1734+
"SELECT i as mytable_i FROM mytable WHERE mytable_i > 1",
1735+
[]sql.Row{
1736+
{int64(3)},
1737+
{int64(2)},
1738+
},
1739+
},
1740+
{
1741+
"SELECT i as mytable_i, s as mytable_s FROM mytable WHERE mytable_i = 2 AND mytable_s = 'second row'",
1742+
[]sql.Row{
1743+
{int64(2), "second row"},
1744+
},
1745+
},
17271746
}
17281747

17291748
for _, tt := range testCases {

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ require (
1818
github.com/mitchellh/hashstructure v1.0.0
1919
github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852
2020
github.com/opentracing/opentracing-go v1.0.2
21+
github.com/pbnjay/memory v0.0.0-20190104145345-974d429e7ae4
2122
github.com/pelletier/go-toml v1.2.0 // indirect
2223
github.com/pilosa/pilosa v1.2.0
2324
github.com/pkg/errors v0.8.1 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg
6969
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
7070
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs=
7171
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
72+
github.com/pbnjay/memory v0.0.0-20190104145345-974d429e7ae4 h1:MfIUBZ1bz7TgvQLVa/yPJZOGeKEgs6eTKUjz3zB4B+U=
73+
github.com/pbnjay/memory v0.0.0-20190104145345-974d429e7ae4/go.mod h1:RMU2gJXhratVxBDTFeOdNhd540tG57lt9FIUV0YLvIQ=
7274
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
7375
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
7476
github.com/pilosa/pilosa v1.2.0 h1:bi58fPsjyGIFnY5DtzECY+8RC9nRLvPrGC6fOqgtkTw=

sql/analyzer/assign_indexes.go

Lines changed: 52 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,17 @@ func assignIndexes(a *Analyzer, node sql.Node) (map[string]*indexLookup, error)
4242
return true
4343
}
4444

45+
aliases := make(map[string]sql.Expression)
46+
if prj, ok := filter.Child.(*plan.Project); ok {
47+
for _, ex := range prj.Expressions() {
48+
if alias, ok := ex.(*expression.Alias); ok {
49+
aliases[alias.Name()] = alias.Child
50+
}
51+
}
52+
}
53+
4554
var result map[string]*indexLookup
46-
result, err = getIndexes(filter.Expression, a)
55+
result, err = getIndexes(filter.Expression, aliases, a)
4756
if err != nil {
4857
return false
4958
}
@@ -60,16 +69,16 @@ func assignIndexes(a *Analyzer, node sql.Node) (map[string]*indexLookup, error)
6069
return indexes, err
6170
}
6271

63-
func getIndexes(e sql.Expression, a *Analyzer) (map[string]*indexLookup, error) {
72+
func getIndexes(e sql.Expression, aliases map[string]sql.Expression, a *Analyzer) (map[string]*indexLookup, error) {
6473
var result = make(map[string]*indexLookup)
6574
switch e := e.(type) {
6675
case *expression.Or:
67-
leftIndexes, err := getIndexes(e.Left, a)
76+
leftIndexes, err := getIndexes(e.Left, aliases, a)
6877
if err != nil {
6978
return nil, err
7079
}
7180

72-
rightIndexes, err := getIndexes(e.Right, a)
81+
rightIndexes, err := getIndexes(e.Right, aliases, a)
7382
if err != nil {
7483
return nil, err
7584
}
@@ -101,7 +110,7 @@ func getIndexes(e sql.Expression, a *Analyzer) (map[string]*indexLookup, error)
101110
// the right branch is evaluable and the indexlookup supports set
102111
// operations.
103112
if !isEvaluable(c.Left()) && isEvaluable(c.Right()) {
104-
idx := a.Catalog.IndexByExpression(a.Catalog.CurrentDatabase(), c.Left())
113+
idx := a.Catalog.IndexByExpression(a.Catalog.CurrentDatabase(), unifyExpressions(aliases, c.Left())...)
105114
if idx != nil {
106115
var nidx sql.NegateIndex
107116
if negate {
@@ -178,7 +187,7 @@ func getIndexes(e sql.Expression, a *Analyzer) (map[string]*indexLookup, error)
178187
*expression.GreaterThan,
179188
*expression.LessThanOrEqual,
180189
*expression.GreaterThanOrEqual:
181-
idx, lookup, err := getComparisonIndex(a, e.(expression.Comparer))
190+
idx, lookup, err := getComparisonIndex(a, e.(expression.Comparer), aliases)
182191
if err != nil || lookup == nil {
183192
return result, err
184193
}
@@ -188,7 +197,7 @@ func getIndexes(e sql.Expression, a *Analyzer) (map[string]*indexLookup, error)
188197
lookup: lookup,
189198
}
190199
case *expression.Not:
191-
r, err := getNegatedIndexes(a, e)
200+
r, err := getNegatedIndexes(a, e, aliases)
192201
if err != nil {
193202
return nil, err
194203
}
@@ -198,7 +207,7 @@ func getIndexes(e sql.Expression, a *Analyzer) (map[string]*indexLookup, error)
198207
}
199208
case *expression.Between:
200209
if !isEvaluable(e.Val) && isEvaluable(e.Upper) && isEvaluable(e.Lower) {
201-
idx := a.Catalog.IndexByExpression(a.Catalog.CurrentDatabase(), e.Val)
210+
idx := a.Catalog.IndexByExpression(a.Catalog.CurrentDatabase(), unifyExpressions(aliases, e.Val)...)
202211
if idx != nil {
203212
// release the index if it was not used
204213
defer func() {
@@ -238,7 +247,7 @@ func getIndexes(e sql.Expression, a *Analyzer) (map[string]*indexLookup, error)
238247
exprs := splitExpression(e)
239248
used := make(map[sql.Expression]struct{})
240249

241-
result, err := getMultiColumnIndexes(exprs, a, used)
250+
result, err := getMultiColumnIndexes(exprs, a, used, aliases)
242251
if err != nil {
243252
return nil, err
244253
}
@@ -248,7 +257,7 @@ func getIndexes(e sql.Expression, a *Analyzer) (map[string]*indexLookup, error)
248257
continue
249258
}
250259

251-
indexes, err := getIndexes(e, a)
260+
indexes, err := getIndexes(e, aliases, a)
252261
if err != nil {
253262
return nil, err
254263
}
@@ -262,6 +271,23 @@ func getIndexes(e sql.Expression, a *Analyzer) (map[string]*indexLookup, error)
262271
return result, nil
263272
}
264273

274+
func unifyExpressions(aliases map[string]sql.Expression, expr ...sql.Expression) []sql.Expression {
275+
expressions := make([]sql.Expression, len(expr))
276+
277+
for i, e := range expr {
278+
uex := e
279+
if aliases != nil {
280+
if alias, ok := aliases[e.String()]; ok {
281+
uex = alias
282+
}
283+
}
284+
285+
expressions[i] = uex
286+
}
287+
288+
return expressions
289+
}
290+
265291
func betweenIndexLookup(index sql.Index, upper, lower []interface{}) (sql.IndexLookup, error) {
266292
ai, isAscend := index.(sql.AscendIndex)
267293
di, isDescend := index.(sql.DescendIndex)
@@ -293,6 +319,7 @@ func betweenIndexLookup(index sql.Index, upper, lower []interface{}) (sql.IndexL
293319
func getComparisonIndex(
294320
a *Analyzer,
295321
e expression.Comparer,
322+
aliases map[string]sql.Expression,
296323
) (sql.Index, sql.IndexLookup, error) {
297324
left, right := e.Left(), e.Right()
298325
// if the form is SOMETHING OP {INDEXABLE EXPR}, swap it, so it's {INDEXABLE EXPR} OP SOMETHING
@@ -301,7 +328,7 @@ func getComparisonIndex(
301328
}
302329

303330
if !isEvaluable(left) && isEvaluable(right) {
304-
idx := a.Catalog.IndexByExpression(a.Catalog.CurrentDatabase(), left)
331+
idx := a.Catalog.IndexByExpression(a.Catalog.CurrentDatabase(), unifyExpressions(aliases, left)...)
305332
if idx != nil {
306333
value, err := right.Eval(sql.NewEmptyContext(), nil)
307334
if err != nil {
@@ -363,10 +390,10 @@ func comparisonIndexLookup(
363390
return nil, nil
364391
}
365392

366-
func getNegatedIndexes(a *Analyzer, not *expression.Not) (map[string]*indexLookup, error) {
393+
func getNegatedIndexes(a *Analyzer, not *expression.Not, aliases map[string]sql.Expression) (map[string]*indexLookup, error) {
367394
switch e := not.Child.(type) {
368395
case *expression.Not:
369-
return getIndexes(e.Child, a)
396+
return getIndexes(e.Child, aliases, a)
370397
case *expression.Equals:
371398
left, right := e.Left(), e.Right()
372399
// if the form is SOMETHING OP {INDEXABLE EXPR}, swap it, so it's {INDEXABLE EXPR} OP SOMETHING
@@ -378,7 +405,7 @@ func getNegatedIndexes(a *Analyzer, not *expression.Not) (map[string]*indexLooku
378405
return nil, nil
379406
}
380407

381-
idx := a.Catalog.IndexByExpression(a.Catalog.CurrentDatabase(), left)
408+
idx := a.Catalog.IndexByExpression(a.Catalog.CurrentDatabase(), unifyExpressions(aliases, left)...)
382409
if idx == nil {
383410
return nil, nil
384411
}
@@ -410,37 +437,37 @@ func getNegatedIndexes(a *Analyzer, not *expression.Not) (map[string]*indexLooku
410437
return result, nil
411438
case *expression.GreaterThan:
412439
lte := expression.NewLessThanOrEqual(e.Left(), e.Right())
413-
return getIndexes(lte, a)
440+
return getIndexes(lte, aliases, a)
414441
case *expression.GreaterThanOrEqual:
415442
lt := expression.NewLessThan(e.Left(), e.Right())
416-
return getIndexes(lt, a)
443+
return getIndexes(lt, aliases, a)
417444
case *expression.LessThan:
418445
gte := expression.NewGreaterThanOrEqual(e.Left(), e.Right())
419-
return getIndexes(gte, a)
446+
return getIndexes(gte, aliases, a)
420447
case *expression.LessThanOrEqual:
421448
gt := expression.NewGreaterThan(e.Left(), e.Right())
422-
return getIndexes(gt, a)
449+
return getIndexes(gt, aliases, a)
423450
case *expression.Between:
424451
or := expression.NewOr(
425452
expression.NewLessThan(e.Val, e.Lower),
426453
expression.NewGreaterThan(e.Val, e.Upper),
427454
)
428455

429-
return getIndexes(or, a)
456+
return getIndexes(or, aliases, a)
430457
case *expression.Or:
431458
and := expression.NewAnd(
432459
expression.NewNot(e.Left),
433460
expression.NewNot(e.Right),
434461
)
435462

436-
return getIndexes(and, a)
463+
return getIndexes(and, aliases, a)
437464
case *expression.And:
438465
or := expression.NewOr(
439466
expression.NewNot(e.Left),
440467
expression.NewNot(e.Right),
441468
)
442469

443-
return getIndexes(or, a)
470+
return getIndexes(or, aliases, a)
444471
default:
445472
return nil, nil
446473

@@ -481,6 +508,7 @@ func getMultiColumnIndexes(
481508
exprs []sql.Expression,
482509
a *Analyzer,
483510
used map[sql.Expression]struct{},
511+
aliases map[string]sql.Expression,
484512
) (map[string]*indexLookup, error) {
485513
result := make(map[string]*indexLookup)
486514
columnExprs := columnExprsByTable(exprs)
@@ -502,7 +530,7 @@ func getMultiColumnIndexes(
502530
}
503531

504532
if len(selected) > 0 {
505-
index, lookup, err := getMultiColumnIndexForExpressions(a, selected, exps, used)
533+
index, lookup, err := getMultiColumnIndexForExpressions(a, selected, exps, used, aliases)
506534
if err != nil || lookup == nil {
507535
if index != nil {
508536
a.Catalog.ReleaseIndex(index)
@@ -534,8 +562,9 @@ func getMultiColumnIndexForExpressions(
534562
selected []sql.Expression,
535563
exprs []columnExpr,
536564
used map[sql.Expression]struct{},
565+
aliases map[string]sql.Expression,
537566
) (index sql.Index, lookup sql.IndexLookup, err error) {
538-
index = a.Catalog.IndexByExpression(a.Catalog.CurrentDatabase(), selected...)
567+
index = a.Catalog.IndexByExpression(a.Catalog.CurrentDatabase(), unifyExpressions(aliases, selected...)...)
539568
if index != nil {
540569
var first sql.Expression
541570
for _, e := range exprs {

sql/analyzer/assign_indexes_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,7 @@ func TestGetIndexes(t *testing.T) {
682682
t.Run(tt.expr.String(), func(t *testing.T) {
683683
require := require.New(t)
684684

685-
result, err := getIndexes(tt.expr, a)
685+
result, err := getIndexes(tt.expr, nil, a)
686686
if tt.ok {
687687
require.NoError(err)
688688
require.Equal(tt.expected, result)
@@ -779,7 +779,7 @@ func TestGetMultiColumnIndexes(t *testing.T) {
779779
lit(6),
780780
),
781781
}
782-
result, err := getMultiColumnIndexes(exprs, a, used)
782+
result, err := getMultiColumnIndexes(exprs, a, used, nil)
783783
require.NoError(err)
784784

785785
expected := map[string]*indexLookup{

0 commit comments

Comments
 (0)