Skip to content

Commit

Permalink
fix(spanner/spannertest): fix handling of NULL with LIKE operator (#2982
Browse files Browse the repository at this point in the history
)
  • Loading branch information
dsymonds committed Oct 8, 2020
1 parent cc37719 commit 5a0c4a4
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 0 deletions.
7 changes: 7 additions & 0 deletions spanner/spannertest/db_eval.go
Expand Up @@ -141,6 +141,13 @@ func (ec evalContext) evalBoolExpr(be spansql.BoolExpr) (bool, error) {
case spansql.Ne:
return compareVals(lhs, rhs) != 0, nil
case spansql.Like, spansql.NotLike:
if lhs == nil || rhs == nil {
// Either operand being NULL should result in NULL.
// TODO: Perhaps evalBoolExpr should be merged with evalExpr,
// and boolean coercion should happen at the top-most level
// so NULLs can be correctly transported.
return false, nil
}
left, ok := lhs.(string)
if !ok {
// TODO: byte works here too?
Expand Down
26 changes: 26 additions & 0 deletions spanner/spannertest/integration_test.go
Expand Up @@ -409,6 +409,7 @@ func TestIntegration_ReadsAndQueries(t *testing.T) {
"PlayerStats",
"JoinA",
"JoinB",
"SomeStrings",
}
for _, table := range allTables {
dropTable(t, adminClient, table)
Expand Down Expand Up @@ -594,6 +595,8 @@ func TestIntegration_ReadsAndQueries(t *testing.T) {
// JoinA and JoinB are "A" and "B" from https://cloud.google.com/spanner/docs/query-syntax#join_types.
`CREATE TABLE JoinA ( w INT64, x STRING(MAX) ) PRIMARY KEY (w, x)`,
`CREATE TABLE JoinB ( y INT64, z STRING(MAX) ) PRIMARY KEY (y, z)`,
// Some other test tables.
`CREATE TABLE SomeStrings ( i INT64, str STRING(MAX) ) PRIMARY KEY (i)`,
)
if err != nil {
t.Fatalf("Creating sample tables: %v", err)
Expand All @@ -614,6 +617,11 @@ func TestIntegration_ReadsAndQueries(t *testing.T) {
spanner.Insert("JoinB", []string{"y", "z"}, []interface{}{3, "m"}),
spanner.Insert("JoinB", []string{"y", "z"}, []interface{}{3, "n"}),
spanner.Insert("JoinB", []string{"y", "z"}, []interface{}{4, "p"}),

spanner.Insert("SomeStrings", []string{"i", "str"}, []interface{}{0, "afoo"}),
spanner.Insert("SomeStrings", []string{"i", "str"}, []interface{}{1, "abar"}),
spanner.Insert("SomeStrings", []string{"i", "str"}, []interface{}{2, nil}),
spanner.Insert("SomeStrings", []string{"i", "str"}, []interface{}{3, "bbar"}),
})
if err != nil {
t.Fatalf("Inserting sample data: %v", err)
Expand Down Expand Up @@ -874,6 +882,24 @@ func TestIntegration_ReadsAndQueries(t *testing.T) {
{int64(1)},
},
},
// Regression TEST for mishandling NULLs with LIKE operator.
{
`SELECT i, str FROM SomeStrings WHERE str LIKE "%bar"`,
nil,
[][]interface{}{
// Does not include [0, "afoo"] or [2, nil].
{int64(1), "abar"},
{int64(3), "bbar"},
},
},
{
`SELECT i, str FROM SomeStrings WHERE str NOT LIKE "%bar"`,
nil,
[][]interface{}{
// Does not include [1, "abar"], [2, nil] or [3, "bbar"].
{int64(0), "afoo"},
},
},
}
for _, test := range tests {
stmt := spanner.NewStatement(test.q)
Expand Down

0 comments on commit 5a0c4a4

Please sign in to comment.