Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions go/test/endtoend/vtgate/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,20 @@ create table t5_null_vindex(
id bigint not null,
idx varchar(50),
primary key(id)
) Engine=InnoDB;

create table t6(
id1 bigint,
id2 varchar(10),
primary key(id1)
) Engine=InnoDB;

create table t6_id2_idx(
id2 varchar(10),
id1 bigint,
keyspace_id varbinary(50),
primary key(id1),
key(id2)
) Engine=InnoDB;`

VSchema = `
Expand Down Expand Up @@ -151,6 +165,16 @@ create table t5_null_vindex(
"to": "keyspace_id"
},
"owner": "t4"
},
"t6_id2_vdx": {
"type": "consistent_lookup",
"params": {
"table": "t6_id2_idx",
"from": "id2,id1",
"to": "keyspace_id",
"ignore_nulls": "true"
},
"owner": "t6"
}
},
"tables": {
Expand Down Expand Up @@ -233,6 +257,26 @@ create table t5_null_vindex(
"name": "unicode_loose_md5"
}
]
},
"t6": {
"column_vindexes": [
{
"column": "id1",
"name": "hash"
},
{
"columns": ["id2", "id1"],
"name": "t6_id2_vdx"
}
]
},
"t6_id2_idx": {
"column_vindexes": [
{
"column": "id2",
"name": "xxhash"
}
]
},
"t5_null_vindex": {
"column_vindexes": [
Expand Down
22 changes: 22 additions & 0 deletions go/test/endtoend/vtgate/misc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,28 @@ func TestConsistentLookupUpdate(t *testing.T) {
require.Empty(t, qr.Rows)
}

func TestSelectNullLookup(t *testing.T) {
ctx := context.Background()
conn, err := mysql.Connect(ctx, &vtParams)
require.NoError(t, err)
defer conn.Close()

exec(t, conn, "begin")
exec(t, conn, "insert into t6(id1, id2) values(1, 'a'), (2, 'b'), (3, null)")
exec(t, conn, "commit")

assertMatches(t, conn, "select id1, id2 from t6 order by id1", "[[INT64(1) VARCHAR(\"a\")] [INT64(2) VARCHAR(\"b\")] [INT64(3) NULL]]")
assertIsEmpty(t, conn, "select id1, id2 from t6 where id2 = null")
assertMatches(t, conn, "select id1, id2 from t6 where id2 is null", "[[INT64(3) NULL]]")
assertMatches(t, conn, "select id1, id2 from t6 where id2 is not null order by id1", "[[INT64(1) VARCHAR(\"a\")] [INT64(2) VARCHAR(\"b\")]]")
assertIsEmpty(t, conn, "select id1, id2 from t6 where id1 IN (null)")
assertMatches(t, conn, "select id1, id2 from t6 where id1 IN (1,2,null) order by id1", "[[INT64(1) VARCHAR(\"a\")] [INT64(2) VARCHAR(\"b\")]]")
assertIsEmpty(t, conn, "select id1, id2 from t6 where id1 NOT IN (1,null) order by id1")
assertMatches(t, conn, "select id1, id2 from t6 where id1 NOT IN (1,3)", "[[INT64(2) VARCHAR(\"b\")]]")

exec(t, conn, "delete from t6")
}

func TestSelectNull(t *testing.T) {
ctx := context.Background()
conn, err := mysql.Connect(ctx, &vtParams)
Expand Down
1 change: 1 addition & 0 deletions go/vt/vtgate/planbuilder/route_option.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ func (ro *routeOption) computeISPlan(pb *primitiveBuilder, comparison *sqlparser
}

vindex = ro.FindVindex(pb, comparison.Expr)
// fallback to scatter gather if there is no vindex
if vindex == nil {
return engine.SelectScatter, nil, nil
}
Expand Down
8 changes: 8 additions & 0 deletions go/vt/vtgate/vindexes/consistent_lookup.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,14 @@ func (lu *ConsistentLookup) Map(vcursor VCursor, ids []sqltypes.Value) ([]key.De
return out, nil
}

// if ignore_nulls is set and the query is about single null value, then fallback to all shards
if len(ids) == 1 && ids[0].IsNull() && lu.lkp.IgnoreNulls {
for range ids {
out = append(out, key.DestinationKeyRange{KeyRange: &topodatapb.KeyRange{}})
}
return out, nil
}

results, err := lu.lkp.Lookup(vcursor, ids)
if err != nil {
return nil, err
Expand Down
8 changes: 8 additions & 0 deletions go/vt/vtgate/vindexes/lookup.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,14 @@ func (ln *LookupNonUnique) Map(vcursor VCursor, ids []sqltypes.Value) ([]key.Des
return out, nil
}

// if ignore_nulls is set and the query is about single null value, then fallback to all shards
if len(ids) == 1 && ids[0].IsNull() && ln.lkp.IgnoreNulls {
for range ids {
out = append(out, key.DestinationKeyRange{KeyRange: &topodatapb.KeyRange{}})
}
return out, nil
}

results, err := ln.lkp.Lookup(vcursor, ids)
if err != nil {
return nil, err
Expand Down
8 changes: 8 additions & 0 deletions go/vt/vtgate/vindexes/lookup_hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,14 @@ func (lh *LookupHash) Map(vcursor VCursor, ids []sqltypes.Value) ([]key.Destinat
return out, nil
}

// if ignore_nulls is set and the query is about single null value, then fallback to all shards
if len(ids) == 1 && ids[0].IsNull() && lh.lkp.IgnoreNulls {
for range ids {
out = append(out, key.DestinationKeyRange{KeyRange: &topodatapb.KeyRange{}})
}
return out, nil
}

results, err := lh.lkp.Lookup(vcursor, ids)
if err != nil {
return nil, err
Expand Down
8 changes: 8 additions & 0 deletions go/vt/vtgate/vindexes/lookup_unicodeloosemd5_hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,14 @@ func (lh *LookupUnicodeLooseMD5Hash) Map(vcursor VCursor, ids []sqltypes.Value)
return out, nil
}

// if ignore_nulls is set and the query is about single null value, then fallback to all shards
if len(ids) == 1 && ids[0].IsNull() && lh.lkp.IgnoreNulls {
for range ids {
out = append(out, key.DestinationKeyRange{KeyRange: &topodatapb.KeyRange{}})
}
return out, nil
}

ids, err := convertIds(ids)
if err != nil {
return nil, err
Expand Down