зеркало из https://github.com/github/vitess-gh.git
675 строки
20 KiB
Go
675 строки
20 KiB
Go
// Copyright 2014, Google Inc. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package vtgate
|
|
|
|
import (
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/youtube/vitess/go/sqltypes"
|
|
"github.com/youtube/vitess/go/vt/tabletserver/querytypes"
|
|
"github.com/youtube/vitess/go/vt/topo"
|
|
_ "github.com/youtube/vitess/go/vt/vtgate/vindexes"
|
|
)
|
|
|
|
func TestUnsharded(t *testing.T) {
|
|
router, _, _, sbclookup := createRouterEnv()
|
|
|
|
_, err := routerExec(router, "select * from music_user_map where id = 1", nil)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
wantQueries := []querytypes.BoundQuery{{
|
|
Sql: "select * from music_user_map where id = 1",
|
|
BindVariables: map[string]interface{}{},
|
|
}}
|
|
if !reflect.DeepEqual(sbclookup.Queries, wantQueries) {
|
|
t.Errorf("sbclookup.Queries: %+v, want %+v\n", sbclookup.Queries, wantQueries)
|
|
}
|
|
|
|
_, err = routerExec(router, "update music_user_map set id = 1", nil)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
wantQueries = []querytypes.BoundQuery{{
|
|
Sql: "select * from music_user_map where id = 1",
|
|
BindVariables: map[string]interface{}{},
|
|
}, {
|
|
Sql: "update music_user_map set id = 1",
|
|
BindVariables: map[string]interface{}{},
|
|
}}
|
|
if !reflect.DeepEqual(sbclookup.Queries, wantQueries) {
|
|
t.Errorf("sbclookup.Queries: %+v, want %+v\n", sbclookup.Queries, wantQueries)
|
|
}
|
|
|
|
sbclookup.Queries = nil
|
|
_, err = routerExec(router, "delete from music_user_map", nil)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
wantQueries = []querytypes.BoundQuery{{
|
|
Sql: "delete from music_user_map",
|
|
BindVariables: map[string]interface{}{},
|
|
}}
|
|
if !reflect.DeepEqual(sbclookup.Queries, wantQueries) {
|
|
t.Errorf("sbclookup.Queries: %+v, want %+v\n", sbclookup.Queries, wantQueries)
|
|
}
|
|
|
|
sbclookup.Queries = nil
|
|
_, err = routerExec(router, "insert into music_user_map values(1)", nil)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
wantQueries = []querytypes.BoundQuery{{
|
|
Sql: "insert into music_user_map values(1)",
|
|
BindVariables: map[string]interface{}{},
|
|
}}
|
|
if !reflect.DeepEqual(sbclookup.Queries, wantQueries) {
|
|
t.Errorf("sbclookup.Queries: %+v, want %+v\n", sbclookup.Queries, wantQueries)
|
|
}
|
|
}
|
|
|
|
func TestStreamUnsharded(t *testing.T) {
|
|
router, _, _, _ := createRouterEnv()
|
|
|
|
sql := "select * from music_user_map where id = 1"
|
|
result, err := routerStream(router, sql)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
wantResult := singleRowResult
|
|
if !reflect.DeepEqual(result, wantResult) {
|
|
t.Errorf("result: %+v, want %+v", result, wantResult)
|
|
}
|
|
}
|
|
|
|
func TestUnshardedFail(t *testing.T) {
|
|
router, _, _, _ := createRouterEnv()
|
|
|
|
getSandbox(KsTestUnsharded).SrvKeyspaceMustFail = 1
|
|
_, err := routerExec(router, "select * from music_user_map where id = 1", nil)
|
|
want := "paramsUnsharded: keyspace TestUnsharded fetch error: topo error GetSrvKeyspace"
|
|
if err == nil || err.Error() != want {
|
|
t.Errorf("routerExec: %v, want %v", err, want)
|
|
}
|
|
|
|
_, err = routerExec(router, "select * from sharded_table where id = 1", nil)
|
|
want = "unsharded keyspace TestBadSharding has multiple shards"
|
|
if err == nil || err.Error() != want {
|
|
t.Errorf("routerExec: %v, want %v", err, want)
|
|
}
|
|
}
|
|
|
|
func TestStreamUnshardedFail(t *testing.T) {
|
|
router, _, _, _ := createRouterEnv()
|
|
|
|
getSandbox(KsTestUnsharded).SrvKeyspaceMustFail = 1
|
|
sql := "select * from music_user_map where id = 1"
|
|
_, err := routerStream(router, sql)
|
|
want := "paramsUnsharded: keyspace TestUnsharded fetch error: topo error GetSrvKeyspace"
|
|
if err == nil || err.Error() != want {
|
|
t.Errorf("routerExec: %v, want %v", err, want)
|
|
}
|
|
|
|
sql = "update music_user_map set a = 1 where id = 1"
|
|
_, err = routerStream(router, sql)
|
|
want = `query "update music_user_map set a = 1 where id = 1" cannot be used for streaming`
|
|
if err == nil || err.Error() != want {
|
|
t.Errorf("routerExec: %v, want %v", err, want)
|
|
}
|
|
}
|
|
|
|
func TestSelectBindvars(t *testing.T) {
|
|
router, sbc1, sbc2, _ := createRouterEnv()
|
|
|
|
_, err := routerExec(router, "select * from user where id = :id", map[string]interface{}{
|
|
"id": 1,
|
|
})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
wantQueries := []querytypes.BoundQuery{{
|
|
Sql: "select * from user where id = :id",
|
|
BindVariables: map[string]interface{}{"id": 1},
|
|
}}
|
|
if !reflect.DeepEqual(sbc1.Queries, wantQueries) {
|
|
t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries)
|
|
}
|
|
if sbc2.Queries != nil {
|
|
t.Errorf("sbc2.Queries: %+v, want nil\n", sbc2.Queries)
|
|
}
|
|
sbc1.Queries = nil
|
|
|
|
_, err = routerExec(router, "select * from user where name in (:name1, :name2)", map[string]interface{}{
|
|
"name1": "foo1",
|
|
"name2": "foo2",
|
|
})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
wantQueries = []querytypes.BoundQuery{{
|
|
Sql: "select * from user where name in ::_vals",
|
|
BindVariables: map[string]interface{}{
|
|
"name1": "foo1",
|
|
"name2": "foo2",
|
|
"_vals": []interface{}{"foo1", "foo2"},
|
|
},
|
|
}}
|
|
if !reflect.DeepEqual(sbc1.Queries, wantQueries) {
|
|
t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries)
|
|
}
|
|
sbc1.Queries = nil
|
|
|
|
_, err = routerExec(router, "select * from user where name in (:name1, :name2)", map[string]interface{}{
|
|
"name1": []byte("foo1"),
|
|
"name2": []byte("foo2"),
|
|
})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
wantQueries = []querytypes.BoundQuery{{
|
|
Sql: "select * from user where name in ::_vals",
|
|
BindVariables: map[string]interface{}{
|
|
"name1": []byte("foo1"),
|
|
"name2": []byte("foo2"),
|
|
"_vals": []interface{}{"foo1", "foo2"},
|
|
},
|
|
}}
|
|
if !reflect.DeepEqual(sbc1.Queries, wantQueries) {
|
|
t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries)
|
|
}
|
|
}
|
|
|
|
func TestSelectEqual(t *testing.T) {
|
|
router, sbc1, sbc2, sbclookup := createRouterEnv()
|
|
|
|
_, err := routerExec(router, "select * from user where id = 1", nil)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
wantQueries := []querytypes.BoundQuery{{
|
|
Sql: "select * from user where id = 1",
|
|
BindVariables: map[string]interface{}{},
|
|
}}
|
|
if !reflect.DeepEqual(sbc1.Queries, wantQueries) {
|
|
t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries)
|
|
}
|
|
if sbc2.Queries != nil {
|
|
t.Errorf("sbc2.Queries: %+v, want nil\n", sbc2.Queries)
|
|
}
|
|
sbc1.Queries = nil
|
|
|
|
_, err = routerExec(router, "select * from user where id = 3", nil)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
wantQueries = []querytypes.BoundQuery{{
|
|
Sql: "select * from user where id = 3",
|
|
BindVariables: map[string]interface{}{},
|
|
}}
|
|
if !reflect.DeepEqual(sbc2.Queries, wantQueries) {
|
|
t.Errorf("sbc2.Queries: %+v, want %+v\n", sbc2.Queries, wantQueries)
|
|
}
|
|
if execCount := sbc1.ExecCount.Get(); execCount != 1 {
|
|
t.Errorf("sbc1.ExecCount: %v, want 1\n", execCount)
|
|
}
|
|
if sbc1.Queries != nil {
|
|
t.Errorf("sbc1.Queries: %+v, want nil\n", sbc1.Queries)
|
|
}
|
|
sbc2.Queries = nil
|
|
|
|
_, err = routerExec(router, "select * from user where id = '3'", nil)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
wantQueries = []querytypes.BoundQuery{{
|
|
Sql: "select * from user where id = '3'",
|
|
BindVariables: map[string]interface{}{},
|
|
}}
|
|
if !reflect.DeepEqual(sbc2.Queries, wantQueries) {
|
|
t.Errorf("sbc2.Queries: %+v, want %+v\n", sbc2.Queries, wantQueries)
|
|
}
|
|
if execCount := sbc1.ExecCount.Get(); execCount != 1 {
|
|
t.Errorf("sbc1.ExecCount: %v, want 1\n", execCount)
|
|
}
|
|
if sbc1.Queries != nil {
|
|
t.Errorf("sbc1.Queries: %+v, want nil\n", sbc1.Queries)
|
|
}
|
|
sbc2.Queries = nil
|
|
|
|
_, err = routerExec(router, "select * from user where name = 'foo'", nil)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
wantQueries = []querytypes.BoundQuery{{
|
|
Sql: "select * from user where name = 'foo'",
|
|
BindVariables: map[string]interface{}{},
|
|
}}
|
|
if !reflect.DeepEqual(sbc1.Queries, wantQueries) {
|
|
t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries)
|
|
}
|
|
wantQueries = []querytypes.BoundQuery{{
|
|
Sql: "select user_id from name_user_map where name = :name",
|
|
BindVariables: map[string]interface{}{
|
|
"name": "foo",
|
|
},
|
|
}}
|
|
if !reflect.DeepEqual(sbclookup.Queries, wantQueries) {
|
|
t.Errorf("sbclookup.Queries: %+v, want %+v\n", sbclookup.Queries, wantQueries)
|
|
}
|
|
}
|
|
|
|
func TestSelectEqualNotFound(t *testing.T) {
|
|
router, _, _, sbclookup := createRouterEnv()
|
|
|
|
sbclookup.setResults([]*sqltypes.Result{{}})
|
|
result, err := routerExec(router, "select * from music where id = 1", nil)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
wantResult := &sqltypes.Result{}
|
|
if !reflect.DeepEqual(result, wantResult) {
|
|
t.Errorf("result: %+v, want %+v", result, wantResult)
|
|
}
|
|
|
|
sbclookup.setResults([]*sqltypes.Result{{}})
|
|
result, err = routerExec(router, "select * from user where name = 'foo'", nil)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
wantResult = &sqltypes.Result{}
|
|
if !reflect.DeepEqual(result, wantResult) {
|
|
t.Errorf("result: %+v, want %+v", result, wantResult)
|
|
}
|
|
}
|
|
|
|
func TestStreamSelectEqual(t *testing.T) {
|
|
router, _, _, _ := createRouterEnv()
|
|
|
|
sql := "select * from user where id = 1"
|
|
result, err := routerStream(router, sql)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
wantResult := singleRowResult
|
|
if !reflect.DeepEqual(result, wantResult) {
|
|
t.Errorf("result: %+v, want %+v", result, wantResult)
|
|
}
|
|
}
|
|
|
|
func TestSelectEqualFail(t *testing.T) {
|
|
router, _, _, sbclookup := createRouterEnv()
|
|
s := getSandbox("TestRouter")
|
|
|
|
_, err := routerExec(router, "select * from user where id = (select count(*) from music)", nil)
|
|
want := "cannot route query: select * from user where id = (select count(*) from music): has subquery"
|
|
if err == nil || err.Error() != want {
|
|
t.Errorf("routerExec: %v, want %v", err, want)
|
|
}
|
|
|
|
_, err = routerExec(router, "select * from user where id = :aa", nil)
|
|
want = "paramsSelectEqual: could not find bind var :aa"
|
|
if err == nil || err.Error() != want {
|
|
t.Errorf("routerExec: %v, want %v", err, want)
|
|
}
|
|
|
|
s.SrvKeyspaceMustFail = 1
|
|
_, err = routerExec(router, "select * from user where id = 1", nil)
|
|
want = "paramsSelectEqual: keyspace TestRouter fetch error: topo error GetSrvKeyspace"
|
|
if err == nil || err.Error() != want {
|
|
t.Errorf("routerExec: %v, want %v", err, want)
|
|
}
|
|
|
|
sbclookup.mustFailServer = 1
|
|
_, err = routerExec(router, "select * from music where id = 1", nil)
|
|
want = "paramsSelectEqual: lookup.Map"
|
|
if err == nil || !strings.HasPrefix(err.Error(), want) {
|
|
t.Errorf("routerExec: %v, want prefix %v", err, want)
|
|
}
|
|
|
|
s.ShardSpec = "80-"
|
|
_, err = routerExec(router, "select * from user where id = 1", nil)
|
|
want = "paramsSelectEqual: KeyspaceId 166b40b44aba4bd6 didn't match any shards"
|
|
if err == nil || !strings.HasPrefix(err.Error(), want) {
|
|
t.Errorf("routerExec: %v, want prefix %v", err, want)
|
|
}
|
|
s.ShardSpec = DefaultShardSpec
|
|
|
|
sbclookup.mustFailServer = 1
|
|
_, err = routerExec(router, "select * from user where name = 'foo'", nil)
|
|
want = "paramsSelectEqual: lookup.Map"
|
|
if err == nil || !strings.HasPrefix(err.Error(), want) {
|
|
t.Errorf("routerExec: %v, want prefix %v", err, want)
|
|
}
|
|
|
|
s.ShardSpec = "80-"
|
|
_, err = routerExec(router, "select * from user where name = 'foo'", nil)
|
|
want = "paramsSelectEqual: KeyspaceId 166b40b44aba4bd6 didn't match any shards"
|
|
if err == nil || !strings.HasPrefix(err.Error(), want) {
|
|
t.Errorf("routerExec: %v, want prefix %v", err, want)
|
|
}
|
|
s.ShardSpec = DefaultShardSpec
|
|
}
|
|
|
|
func TestSelectIN(t *testing.T) {
|
|
router, sbc1, sbc2, sbclookup := createRouterEnv()
|
|
|
|
_, err := routerExec(router, "select * from user where id in (1)", nil)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
wantQueries := []querytypes.BoundQuery{{
|
|
Sql: "select * from user where id in ::_vals",
|
|
BindVariables: map[string]interface{}{
|
|
"_vals": []interface{}{int64(1)},
|
|
},
|
|
}}
|
|
if !reflect.DeepEqual(sbc1.Queries, wantQueries) {
|
|
t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries)
|
|
}
|
|
if sbc2.Queries != nil {
|
|
t.Errorf("sbc2.Queries: %+v, want nil\n", sbc2.Queries)
|
|
}
|
|
|
|
sbc1.Queries = nil
|
|
_, err = routerExec(router, "select * from user where id in (1, 3)", nil)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
wantQueries = []querytypes.BoundQuery{{
|
|
Sql: "select * from user where id in ::_vals",
|
|
BindVariables: map[string]interface{}{
|
|
"_vals": []interface{}{int64(1)},
|
|
},
|
|
}}
|
|
if !reflect.DeepEqual(sbc1.Queries, wantQueries) {
|
|
t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries)
|
|
}
|
|
wantQueries = []querytypes.BoundQuery{{
|
|
Sql: "select * from user where id in ::_vals",
|
|
BindVariables: map[string]interface{}{
|
|
"_vals": []interface{}{int64(3)},
|
|
},
|
|
}}
|
|
if !reflect.DeepEqual(sbc2.Queries, wantQueries) {
|
|
t.Errorf("sbc2.Queries: %+v, want %+v\n", sbc2.Queries, wantQueries)
|
|
}
|
|
|
|
sbc1.Queries = nil
|
|
sbc2.Queries = nil
|
|
_, err = routerExec(router, "select * from user where name = 'foo'", nil)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
wantQueries = []querytypes.BoundQuery{{
|
|
Sql: "select * from user where name = 'foo'",
|
|
BindVariables: map[string]interface{}{},
|
|
}}
|
|
if !reflect.DeepEqual(sbc1.Queries, wantQueries) {
|
|
t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries)
|
|
}
|
|
wantQueries = []querytypes.BoundQuery{{
|
|
Sql: "select user_id from name_user_map where name = :name",
|
|
BindVariables: map[string]interface{}{
|
|
"name": "foo",
|
|
},
|
|
}}
|
|
if !reflect.DeepEqual(sbclookup.Queries, wantQueries) {
|
|
t.Errorf("sbclookup.Queries: %+v, want %+v\n", sbclookup.Queries, wantQueries)
|
|
}
|
|
}
|
|
|
|
func TestStreamSelectIN(t *testing.T) {
|
|
router, _, _, sbclookup := createRouterEnv()
|
|
|
|
sql := "select * from user where id in (1)"
|
|
result, err := routerStream(router, sql)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
wantResult := singleRowResult
|
|
if !reflect.DeepEqual(result, wantResult) {
|
|
t.Errorf("result: %+v, want %+v", result, wantResult)
|
|
}
|
|
|
|
sql = "select * from user where id in (1, 3)"
|
|
result, err = routerStream(router, sql)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
wantResult = &sqltypes.Result{
|
|
Fields: singleRowResult.Fields,
|
|
Rows: [][]sqltypes.Value{
|
|
singleRowResult.Rows[0],
|
|
singleRowResult.Rows[0],
|
|
},
|
|
RowsAffected: 2,
|
|
}
|
|
if !reflect.DeepEqual(result, wantResult) {
|
|
t.Errorf("result: %+v, want %+v", result, wantResult)
|
|
}
|
|
|
|
sql = "select * from user where name = 'foo'"
|
|
result, err = routerStream(router, sql)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
wantResult = singleRowResult
|
|
if !reflect.DeepEqual(result, wantResult) {
|
|
t.Errorf("result: %+v, want %+v", result, wantResult)
|
|
}
|
|
|
|
wantQueries := []querytypes.BoundQuery{{
|
|
Sql: "select user_id from name_user_map where name = :name",
|
|
BindVariables: map[string]interface{}{
|
|
"name": "foo",
|
|
},
|
|
}}
|
|
if !reflect.DeepEqual(sbclookup.Queries, wantQueries) {
|
|
t.Errorf("sbclookup.Queries: %+v, want %+v\n", sbclookup.Queries, wantQueries)
|
|
}
|
|
}
|
|
|
|
func TestSelectINFail(t *testing.T) {
|
|
router, _, _, _ := createRouterEnv()
|
|
|
|
_, err := routerExec(router, "select * from user where id in (:aa)", nil)
|
|
want := "paramsSelectIN: could not find bind var :aa"
|
|
if err == nil || err.Error() != want {
|
|
t.Errorf("routerExec: %v, want %v", err, want)
|
|
}
|
|
|
|
getSandbox("TestRouter").SrvKeyspaceMustFail = 1
|
|
_, err = routerExec(router, "select * from user where id in (1)", nil)
|
|
want = "paramsSelectEqual: keyspace TestRouter fetch error: topo error GetSrvKeyspace"
|
|
if err == nil || err.Error() != want {
|
|
t.Errorf("routerExec: %v, want %v", err, want)
|
|
}
|
|
}
|
|
|
|
func TestSelectKeyrange(t *testing.T) {
|
|
router, sbc1, sbc2, _ := createRouterEnv()
|
|
|
|
_, err := routerExec(router, "select * from user where keyrange('', '\x20')", nil)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
wantQueries := []querytypes.BoundQuery{{
|
|
Sql: "select * from user",
|
|
BindVariables: map[string]interface{}{},
|
|
}}
|
|
if !reflect.DeepEqual(sbc1.Queries, wantQueries) {
|
|
t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries)
|
|
}
|
|
if sbc2.Queries != nil {
|
|
t.Errorf("sbc2.Queries: %+v, want nil\n", sbc2.Queries)
|
|
}
|
|
|
|
sbc1.Queries = nil
|
|
_, err = routerExec(router, "select * from user where keyrange('\x40', '\x60')", nil)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
wantQueries = []querytypes.BoundQuery{{
|
|
Sql: "select * from user",
|
|
BindVariables: map[string]interface{}{},
|
|
}}
|
|
if !reflect.DeepEqual(sbc2.Queries, wantQueries) {
|
|
t.Errorf("sbc2.Queries: %+v, want %+v\n", sbc2.Queries, wantQueries)
|
|
}
|
|
if sbc1.Queries != nil {
|
|
t.Errorf("sbc1.Queries: %+v, want nil\n", sbc1.Queries)
|
|
}
|
|
}
|
|
|
|
func TestStreamSelectKeyrange(t *testing.T) {
|
|
router, _, _, _ := createRouterEnv()
|
|
|
|
sql := "select * from user where keyrange('', '\x20')"
|
|
result, err := routerStream(router, sql)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
wantResult := singleRowResult
|
|
if !reflect.DeepEqual(result, wantResult) {
|
|
t.Errorf("result: %+v, want %+v", result, wantResult)
|
|
}
|
|
|
|
sql = "select * from user where keyrange('\x40', '\x60')"
|
|
result, err = routerStream(router, sql)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
wantResult = singleRowResult
|
|
if !reflect.DeepEqual(result, wantResult) {
|
|
t.Errorf("result: %+v, want %+v", result, wantResult)
|
|
}
|
|
}
|
|
|
|
func TestSelectKeyrangeFail(t *testing.T) {
|
|
router, _, _, _ := createRouterEnv()
|
|
|
|
_, err := routerExec(router, "select * from user where keyrange('', :aa)", nil)
|
|
want := "paramsSelectKeyrange: could not find bind var :aa"
|
|
if err == nil || err.Error() != want {
|
|
t.Errorf("routerExec: %v, want %v", err, want)
|
|
}
|
|
|
|
_, err = routerExec(router, "select * from user where keyrange('', :aa)", map[string]interface{}{
|
|
"aa": 1,
|
|
})
|
|
want = "paramsSelectKeyrange: expecting strings for keyrange: [ 1]"
|
|
if err == nil || err.Error() != want {
|
|
t.Errorf("routerExec: %v, want %v", err, want)
|
|
}
|
|
|
|
_, err = routerExec(router, "select * from user where keyrange('', :aa)", map[string]interface{}{
|
|
"aa": "\x21",
|
|
})
|
|
want = "paramsSelectKeyrange: keyrange -21 does not exactly match shards"
|
|
if err == nil || err.Error() != want {
|
|
t.Errorf("routerExec: %v, want %v", err, want)
|
|
}
|
|
|
|
_, err = routerExec(router, "select * from user where keyrange('', :aa)", map[string]interface{}{
|
|
"aa": "\x40",
|
|
})
|
|
want = "keyrange must match exactly one shard: [ @]"
|
|
if err == nil || err.Error() != want {
|
|
t.Errorf("routerExec: %v, want %v", err, want)
|
|
}
|
|
}
|
|
|
|
func TestSelectScatter(t *testing.T) {
|
|
// Special setup: Don't use createRouterEnv.
|
|
s := createSandbox("TestRouter")
|
|
shards := []string{"-20", "20-40", "40-60", "60-80", "80-a0", "a0-c0", "c0-e0", "e0-"}
|
|
var conns []*sandboxConn
|
|
for _, shard := range shards {
|
|
sbc := &sandboxConn{}
|
|
conns = append(conns, sbc)
|
|
s.MapTestConn(shard, sbc)
|
|
}
|
|
serv := new(sandboxTopo)
|
|
scatterConn := NewScatterConn(nil, topo.Server{}, serv, "", "aa", 1*time.Second, 10, 2*time.Millisecond, 1*time.Millisecond, 24*time.Hour, nil, "")
|
|
router := NewRouter(serv, "aa", routerSchema, "", scatterConn)
|
|
|
|
_, err := routerExec(router, "select * from user", nil)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
wantQueries := []querytypes.BoundQuery{{
|
|
Sql: "select * from user",
|
|
BindVariables: map[string]interface{}{},
|
|
}}
|
|
for _, conn := range conns {
|
|
if !reflect.DeepEqual(conn.Queries, wantQueries) {
|
|
t.Errorf("conn.Queries = %#v, want %#v", conn.Queries, wantQueries)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestStreamSelectScatter(t *testing.T) {
|
|
// Special setup: Don't use createRouterEnv.
|
|
s := createSandbox("TestRouter")
|
|
shards := []string{"-20", "20-40", "40-60", "60-80", "80-a0", "a0-c0", "c0-e0", "e0-"}
|
|
var conns []*sandboxConn
|
|
for _, shard := range shards {
|
|
sbc := &sandboxConn{}
|
|
conns = append(conns, sbc)
|
|
s.MapTestConn(shard, sbc)
|
|
}
|
|
serv := new(sandboxTopo)
|
|
scatterConn := NewScatterConn(nil, topo.Server{}, serv, "", "aa", 1*time.Second, 10, 2*time.Millisecond, 1*time.Millisecond, 24*time.Hour, nil, "")
|
|
router := NewRouter(serv, "aa", routerSchema, "", scatterConn)
|
|
|
|
sql := "select * from user"
|
|
result, err := routerStream(router, sql)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
wantResult := &sqltypes.Result{
|
|
Fields: singleRowResult.Fields,
|
|
Rows: [][]sqltypes.Value{
|
|
singleRowResult.Rows[0],
|
|
singleRowResult.Rows[0],
|
|
singleRowResult.Rows[0],
|
|
singleRowResult.Rows[0],
|
|
singleRowResult.Rows[0],
|
|
singleRowResult.Rows[0],
|
|
singleRowResult.Rows[0],
|
|
singleRowResult.Rows[0],
|
|
},
|
|
RowsAffected: 8,
|
|
}
|
|
if !reflect.DeepEqual(result, wantResult) {
|
|
t.Errorf("result: %+v, want %+v", result, wantResult)
|
|
}
|
|
}
|
|
|
|
func TestSelectScatterFail(t *testing.T) {
|
|
// Special setup: Don't use createRouterEnv.
|
|
s := createSandbox("TestRouter")
|
|
s.SrvKeyspaceMustFail = 1
|
|
shards := []string{"-20", "20-40", "40-60", "60-80", "80-a0", "a0-c0", "c0-e0", "e0-"}
|
|
var conns []*sandboxConn
|
|
for _, shard := range shards {
|
|
sbc := &sandboxConn{}
|
|
conns = append(conns, sbc)
|
|
s.MapTestConn(shard, sbc)
|
|
}
|
|
serv := new(sandboxTopo)
|
|
scatterConn := NewScatterConn(nil, topo.Server{}, serv, "", "aa", 1*time.Second, 10, 2*time.Millisecond, 1*time.Millisecond, 24*time.Hour, nil, "")
|
|
router := NewRouter(serv, "aa", routerSchema, "", scatterConn)
|
|
|
|
_, err := routerExec(router, "select * from user", nil)
|
|
want := "paramsSelectScatter: keyspace TestRouter fetch error: topo error GetSrvKeyspace"
|
|
if err == nil || err.Error() != want {
|
|
t.Errorf("routerExec: %v, want %v", err, want)
|
|
}
|
|
}
|