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

Commit 9b083fa

Browse files
authored
Zachmu/bug fixes to contribute (#784)
Zachmu/bug fixes to contribute
2 parents 764130c + 99dc027 commit 9b083fa

File tree

8 files changed

+474
-25
lines changed

8 files changed

+474
-25
lines changed

engine_test.go

Lines changed: 170 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,90 @@ var queries = []struct {
3232
"SELECT i FROM mytable;",
3333
[]sql.Row{{int64(1)}, {int64(2)}, {int64(3)}},
3434
},
35+
{
36+
"SELECT i + 1 FROM mytable;",
37+
[]sql.Row{{int64(2)}, {int64(3)}, {int64(4)}},
38+
},
39+
{
40+
"SELECT -i FROM mytable;",
41+
[]sql.Row{{int64(-1)}, {int64(-2)}, {int64(-3)}},
42+
},
43+
{
44+
"SELECT i FROM mytable where -i = -2;",
45+
[]sql.Row{{int64(2)}},
46+
},
3547
{
3648
"SELECT i FROM mytable WHERE i = 2;",
3749
[]sql.Row{{int64(2)}},
3850
},
51+
{
52+
"SELECT i FROM mytable WHERE i > 2;",
53+
[]sql.Row{{int64(3)}},
54+
},
55+
{
56+
"SELECT i FROM mytable WHERE i < 2;",
57+
[]sql.Row{{int64(1)}},
58+
},
59+
{
60+
"SELECT i FROM mytable WHERE i <> 2;",
61+
[]sql.Row{{int64(1)}, {int64(3)}},
62+
},
63+
{
64+
"SELECT f32 FROM floattable WHERE f64 = 2.0;",
65+
[]sql.Row{{float32(2.0)}},
66+
},
67+
{
68+
"SELECT f32 FROM floattable WHERE f64 < 2.0;",
69+
[]sql.Row{{float32(-1.0)}, {float32(-1.5)}, {float32(1.0)}, {float32(1.5)}},
70+
},
71+
{
72+
"SELECT f32 FROM floattable WHERE f64 > 2.0;",
73+
[]sql.Row{{float32(2.5)}},
74+
},
75+
{
76+
"SELECT f32 FROM floattable WHERE f64 <> 2.0;",
77+
[]sql.Row{{float32(-1.0)}, {float32(-1.5)}, {float32(1.0)}, {float32(1.5)}, {float32(2.5)}},
78+
},
79+
{
80+
"SELECT f64 FROM floattable WHERE f32 = 2.0;",
81+
[]sql.Row{{float64(2.0)}},
82+
},
83+
{
84+
"SELECT f64 FROM floattable WHERE f32 = -1.5;",
85+
[]sql.Row{{float64(-1.5)}},
86+
},
87+
{
88+
"SELECT f64 FROM floattable WHERE -f32 = -2.0;",
89+
[]sql.Row{{float64(2.0)}},
90+
},
91+
{
92+
"SELECT f64 FROM floattable WHERE f32 < 2.0;",
93+
[]sql.Row{{float64(-1.0)}, {float64(-1.5)}, {float64(1.0)}, {float64(1.5)}},
94+
},
95+
{
96+
"SELECT f64 FROM floattable WHERE f32 > 2.0;",
97+
[]sql.Row{{float64(2.5)}},
98+
},
99+
{
100+
"SELECT f64 FROM floattable WHERE f32 <> 2.0;",
101+
[]sql.Row{{float64(-1.0)}, {float64(-1.5)}, {float64(1.0)}, {float64(1.5)}, {float64(2.5)}},
102+
},
103+
{
104+
"SELECT f32 FROM floattable ORDER BY f64;",
105+
[]sql.Row{{float32(-1.5)}, {float32(-1.0)}, {float32(1.0)}, {float32(1.5)}, {float32(2.0)}, {float32(2.5)}},
106+
},
39107
{
40108
"SELECT i FROM mytable ORDER BY i DESC;",
41109
[]sql.Row{{int64(3)}, {int64(2)}, {int64(1)}},
42110
},
111+
{
112+
"SELECT i FROM mytable WHERE 'hello';",
113+
[]sql.Row{},
114+
},
115+
{
116+
"SELECT i FROM mytable WHERE not 'hello';",
117+
[]sql.Row{{int64(1)}, {int64(2)}, {int64(3)}},
118+
},
43119
{
44120
"SELECT i FROM mytable WHERE s = 'first row' ORDER BY i DESC;",
45121
[]sql.Row{{int64(1)}},
@@ -64,6 +140,38 @@ var queries = []struct {
64140
"SELECT i FROM mytable ORDER BY i LIMIT 2,100;",
65141
[]sql.Row{{int64(3)}},
66142
},
143+
{
144+
"SELECT i FROM niltable WHERE b IS NULL",
145+
[]sql.Row{{int64(2)}, {nil}},
146+
},
147+
{
148+
"SELECT i FROM niltable WHERE b IS NOT NULL",
149+
[]sql.Row{{int64(1)}, {nil}, {int64(4)}},
150+
},
151+
{
152+
"SELECT i FROM niltable WHERE b",
153+
[]sql.Row{{int64(1)}, {int64(4)}},
154+
},
155+
{
156+
"SELECT i FROM niltable WHERE NOT b",
157+
[]sql.Row{{nil}},
158+
},
159+
{
160+
"SELECT i FROM niltable WHERE b IS TRUE",
161+
[]sql.Row{{int64(1)}, {int64(4)}},
162+
},
163+
{
164+
"SELECT i FROM niltable WHERE b IS NOT TRUE",
165+
[]sql.Row{{int64(2)}, {nil}, {nil}},
166+
},
167+
{
168+
"SELECT f FROM niltable WHERE b IS FALSE",
169+
[]sql.Row{{3.0}},
170+
},
171+
{
172+
"SELECT i FROM niltable WHERE b IS NOT FALSE",
173+
[]sql.Row{{int64(1)}, {int64(2)}, {int64(4)}, {nil}},
174+
},
67175
{
68176
"SELECT COUNT(*) FROM mytable;",
69177
[]sql.Row{{int64(3)}},
@@ -593,6 +701,8 @@ var queries = []struct {
593701
{"othertable", "InnoDB", "10", "Fixed", int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), nil, nil, nil, "utf8_bin", nil, nil},
594702
{"tabletest", "InnoDB", "10", "Fixed", int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), nil, nil, nil, "utf8_bin", nil, nil},
595703
{"bigtable", "InnoDB", "10", "Fixed", int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), nil, nil, nil, "utf8_bin", nil, nil},
704+
{"floattable", "InnoDB", "10", "Fixed", int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), nil, nil, nil, "utf8_bin", nil, nil},
705+
{"niltable", "InnoDB", "10", "Fixed", int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), nil, nil, nil, "utf8_bin", nil, nil},
596706
},
597707
},
598708
{
@@ -601,6 +711,8 @@ var queries = []struct {
601711
{"mytable", "InnoDB", "10", "Fixed", int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), nil, nil, nil, "utf8_bin", nil, nil},
602712
{"othertable", "InnoDB", "10", "Fixed", int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), nil, nil, nil, "utf8_bin", nil, nil},
603713
{"bigtable", "InnoDB", "10", "Fixed", int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), nil, nil, nil, "utf8_bin", nil, nil},
714+
{"floattable", "InnoDB", "10", "Fixed", int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), nil, nil, nil, "utf8_bin", nil, nil},
715+
{"niltable", "InnoDB", "10", "Fixed", int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), nil, nil, nil, "utf8_bin", nil, nil},
604716
},
605717
},
606718
{
@@ -741,6 +853,8 @@ var queries = []struct {
741853
{"othertable"},
742854
{"tabletest"},
743855
{"bigtable"},
856+
{"floattable"},
857+
{"niltable"},
744858
},
745859
},
746860
{
@@ -766,6 +880,10 @@ var queries = []struct {
766880
{"i2"},
767881
{"t"},
768882
{"n"},
883+
{"f32"},
884+
{"f64"},
885+
{"b"},
886+
{"f"},
769887
},
770888
},
771889
{
@@ -781,6 +899,10 @@ var queries = []struct {
781899
{"i2"},
782900
{"t"},
783901
{"n"},
902+
{"f32"},
903+
{"f64"},
904+
{"b"},
905+
{"f"},
784906
},
785907
},
786908
{
@@ -796,6 +918,10 @@ var queries = []struct {
796918
{"i2"},
797919
{"t"},
798920
{"n"},
921+
{"f32"},
922+
{"f64"},
923+
{"b"},
924+
{"f"},
799925
},
800926
},
801927
{
@@ -830,6 +956,8 @@ var queries = []struct {
830956
{"othertable", "InnoDB", "10", "Fixed", int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), nil, nil, nil, "utf8_bin", nil, nil},
831957
{"tabletest", "InnoDB", "10", "Fixed", int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), nil, nil, nil, "utf8_bin", nil, nil},
832958
{"bigtable", "InnoDB", "10", "Fixed", int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), nil, nil, nil, "utf8_bin", nil, nil},
959+
{"floattable", "InnoDB", "10", "Fixed", int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), nil, nil, nil, "utf8_bin", nil, nil},
960+
{"niltable", "InnoDB", "10", "Fixed", int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), nil, nil, nil, "utf8_bin", nil, nil},
833961
},
834962
},
835963
{
@@ -941,6 +1069,8 @@ var queries = []struct {
9411069
{"othertable"},
9421070
{"tabletest"},
9431071
{"bigtable"},
1072+
{"floattable"},
1073+
{"niltable"},
9441074
},
9451075
},
9461076
{
@@ -950,6 +1080,8 @@ var queries = []struct {
9501080
{"othertable", "BASE TABLE"},
9511081
{"tabletest", "BASE TABLE"},
9521082
{"bigtable", "BASE TABLE"},
1083+
{"floattable", "BASE TABLE"},
1084+
{"niltable", "BASE TABLE"},
9531085
},
9541086
},
9551087
{
@@ -964,6 +1096,8 @@ var queries = []struct {
9641096
{"mytable"},
9651097
{"othertable"},
9661098
{"bigtable"},
1099+
{"floattable"},
1100+
{"niltable"},
9671101
},
9681102
},
9691103
{
@@ -1873,9 +2007,9 @@ func TestInnerNestedInNaturalJoins(t *testing.T) {
18732007

18742008
insertRows(
18752009
t, table3,
1876-
sql.NewRow(int32(1), float64(2.3), "table3"),
1877-
sql.NewRow(int32(2), float64(2.3), "table3"),
1878-
sql.NewRow(int32(30), float64(2.3), "table3"),
2010+
sql.NewRow(int32(1), float64(2.2), "table3"),
2011+
sql.NewRow(int32(2), float64(2.2), "table3"),
2012+
sql.NewRow(int32(30), float64(2.2), "table3"),
18792013
)
18802014

18812015
db := mem.NewDatabase("mydb")
@@ -2002,11 +2136,44 @@ func newEngineWithParallelism(t *testing.T, parallelism int) *sqle.Engine {
20022136
sql.NewRow("b", int64(9)),
20032137
)
20042138

2139+
floatTable := mem.NewPartitionedTable("floattable", sql.Schema{
2140+
{Name: "i", Type: sql.Int64, Source: "floattable"},
2141+
{Name: "f32", Type: sql.Float32, Source: "floattable"},
2142+
{Name: "f64", Type: sql.Float64, Source: "floattable"},
2143+
}, testNumPartitions)
2144+
2145+
insertRows(
2146+
t, floatTable,
2147+
sql.NewRow(1, float32(1.0), float64(1.0)),
2148+
sql.NewRow(2, float32(1.5), float64(1.5)),
2149+
sql.NewRow(3, float32(2.0), float64(2.0)),
2150+
sql.NewRow(4, float32(2.5), float64(2.5)),
2151+
sql.NewRow(-1, float32(-1.0), float64(-1.0)),
2152+
sql.NewRow(-2, float32(-1.5), float64(-1.5)),
2153+
)
2154+
2155+
nilTable := mem.NewPartitionedTable("niltable", sql.Schema{
2156+
{Name: "i", Type: sql.Int64, Source: "niltable", Nullable: true},
2157+
{Name: "b", Type: sql.Boolean, Source: "niltable", Nullable: true},
2158+
{Name: "f", Type: sql.Float64, Source: "niltable", Nullable: true},
2159+
}, testNumPartitions)
2160+
2161+
insertRows(
2162+
t, nilTable,
2163+
sql.NewRow(int64(1), true, float64(1.0)),
2164+
sql.NewRow(int64(2), nil, float64(2.0)),
2165+
sql.NewRow(nil, false, float64(3.0)),
2166+
sql.NewRow(int64(4), true, nil),
2167+
sql.NewRow(nil, nil, nil),
2168+
)
2169+
20052170
db := mem.NewDatabase("mydb")
20062171
db.AddTable("mytable", table)
20072172
db.AddTable("othertable", table2)
20082173
db.AddTable("tabletest", table3)
20092174
db.AddTable("bigtable", bigtable)
2175+
db.AddTable("floattable", floatTable)
2176+
db.AddTable("niltable", nilTable)
20102177

20112178
db2 := mem.NewDatabase("foo")
20122179
db2.AddTable("other_table", table4)

sql/analyzer/optimization_rules.go

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -380,27 +380,20 @@ func evalFilter(ctx *sql.Context, a *Analyzer, node sql.Node) (sql.Node, error)
380380
return e.Left, nil
381381
}
382382

383+
return e, nil
384+
case *expression.Literal, expression.Tuple:
383385
return e, nil
384386
default:
385387
if !isEvaluable(e) {
386388
return e, nil
387389
}
388390

389-
if _, ok := e.(*expression.Literal); ok {
390-
return e, nil
391-
}
392-
391+
// All other expressions types can be evaluated once and turned into literals for the rest of query execution
393392
val, err := e.Eval(ctx, nil)
394393
if err != nil {
395394
return e, nil
396395
}
397-
398-
val, err = sql.Boolean.Convert(val)
399-
if err != nil {
400-
return e, nil
401-
}
402-
403-
return expression.NewLiteral(val.(bool), sql.Boolean), nil
396+
return expression.NewLiteral(val, e.Type()), nil
404397
}
405398
})
406399
if err != nil {

sql/expression/istrue.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package expression
2+
3+
import (
4+
"errors"
5+
"github.com/src-d/go-mysql-server/sql"
6+
)
7+
8+
// IsTrue is an expression that checks if an expression is true.
9+
type IsTrue struct {
10+
UnaryExpression
11+
invert bool
12+
}
13+
14+
const IsTrueStr = "IS TRUE"
15+
const IsFalseStr = "IS FALSE"
16+
17+
// NewIsTrue creates a new IsTrue expression.
18+
func NewIsTrue(child sql.Expression) *IsTrue {
19+
return &IsTrue{UnaryExpression: UnaryExpression{child}}
20+
}
21+
22+
// NewIsFalse creates a new IsTrue expression with its boolean sense inverted (IsFalse, effectively).
23+
func NewIsFalse(child sql.Expression) *IsTrue {
24+
return &IsTrue{UnaryExpression: UnaryExpression{child}, invert: true}
25+
}
26+
27+
// Type implements the Expression interface.
28+
func (*IsTrue) Type() sql.Type {
29+
return sql.Boolean
30+
}
31+
32+
// IsNullable implements the Expression interface.
33+
func (*IsTrue) IsNullable() bool {
34+
return false
35+
}
36+
37+
// Eval implements the Expression interface.
38+
func (e *IsTrue) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
39+
v, err := e.Child.Eval(ctx, row)
40+
if err != nil {
41+
return nil, err
42+
}
43+
44+
var boolVal interface{}
45+
if v == nil {
46+
return false, nil
47+
} else {
48+
boolVal, err = sql.Boolean.Convert(v)
49+
if err != nil {
50+
return nil, err
51+
}
52+
}
53+
54+
if e.invert {
55+
return !boolVal.(bool), nil
56+
}
57+
return boolVal, nil
58+
}
59+
60+
func (e *IsTrue) String() string {
61+
isStr := IsTrueStr
62+
if e.invert {
63+
isStr = IsFalseStr
64+
}
65+
return e.Child.String() + " " + isStr
66+
}
67+
68+
// WithChildren implements the Expression interface.
69+
func (e *IsTrue) WithChildren(children ...sql.Expression) (sql.Expression, error) {
70+
if len(children) != 1 {
71+
return nil, errors.New("incorrect number of children")
72+
}
73+
74+
if e.invert {
75+
return NewIsFalse(children[0]), nil
76+
}
77+
return NewIsTrue(children[0]), nil
78+
}

0 commit comments

Comments
 (0)