func TestPoolSize(t *testing.T) { vstart := framework.DebugVars() defer framework.Server.SetPoolSize(framework.Server.PoolSize()) framework.Server.SetPoolSize(1) var wg sync.WaitGroup wg.Add(2) go func() { framework.NewClient().Execute("select sleep(0.5) from dual", nil) wg.Done() }() // The queries have to be different so consolidator doesn't kick in. go func() { framework.NewClient().Execute("select sleep(0.49) from dual", nil) wg.Done() }() wg.Wait() vend := framework.DebugVars() if err := verifyIntValue(vend, "ConnPoolCapacity", 1); err != nil { t.Error(err) } if err := compareIntDiff(vend, "ConnPoolWaitCount", vstart, 1); err != nil { t.Error(err) } }
func TestConsolidation(t *testing.T) { vstart := framework.DebugVars() defer framework.Server.SetPoolSize(framework.Server.PoolSize()) framework.Server.SetPoolSize(1) var wg sync.WaitGroup wg.Add(2) go func() { framework.NewClient().Execute("select sleep(0.25) from dual", nil) wg.Done() }() go func() { framework.NewClient().Execute("select sleep(0.25) from dual", nil) wg.Done() }() wg.Wait() vend := framework.DebugVars() if err := compareIntDiff(vend, "Waits/TotalCount", vstart, 1); err != nil { t.Error(err) } if err := compareIntDiff(vend, "Waits/Histograms/Consolidations/Count", vstart, 1); err != nil { t.Error(err) } }
func TestStrictMode(t *testing.T) { queries := []string{ "insert into vitess_a(eid, id, name, foo) values (7, 1+1, '', '')", "insert into vitess_d(eid, id) values (1, 1)", "update vitess_a set eid = 1+1 where eid = 1 and id = 1", "insert into vitess_d(eid, id) values (1, 1)", "insert into upsert_test(id1, id2) values " + "(1, 1), (2, 2) on duplicate key update id1 = 1", "insert into upsert_test(id1, id2) select eid, id " + "from vitess_a limit 1 on duplicate key update id2 = id1", "insert into upsert_test(id1, id2) values " + "(1, 1) on duplicate key update id1 = 2+1", } // Strict mode on. func() { client := framework.NewClient() err := client.Begin() if err != nil { t.Error(err) return } defer client.Rollback() want := "error: DML too complex" for _, query := range queries { _, err = client.Execute(query, nil) if err == nil || err.Error() != want { t.Errorf("Execute(%s): %v, want %s", query, err, want) } } }() // Strict mode off. func() { framework.Server.SetStrictMode(false) defer framework.Server.SetStrictMode(true) for _, query := range queries { client := framework.NewClient() err := client.Begin() if err != nil { t.Error(err) return } _, err = client.Execute(query, nil) if err != nil { t.Error(err) } client.Rollback() } }() }
func TestNull(t *testing.T) { client := framework.NewClient() qr, err := client.Execute("select null from dual", nil) if err != nil { t.Error(err) return } want := mproto.QueryResult{ Fields: []mproto.Field{ { Name: "NULL", Type: mysql.TypeNull, Flags: mysql.FlagBinary, }, }, RowsAffected: 1, Rows: [][]sqltypes.Value{ []sqltypes.Value{ sqltypes.Value{}, }, }, } if !reflect.DeepEqual(*qr, want) { t.Errorf("Execute: \n%#v, want \n%#v", *qr, want) } }
func TestQueryTimeout(t *testing.T) { vstart := framework.DebugVars() defer framework.Server.QueryTimeout.Set(framework.Server.QueryTimeout.Get()) framework.Server.QueryTimeout.Set(100 * time.Millisecond) client := framework.NewClient() err := client.Begin() if err != nil { t.Error(err) return } _, err = client.Execute("select sleep(1) from vitess_test", nil) want := "error: the query was killed" if err == nil || !strings.HasPrefix(err.Error(), want) { t.Errorf("Error: %v, must start with %s", err, want) } _, err = client.Execute("select 1 from dual", nil) want = "not_in_tx: Transaction" if err == nil || !strings.HasPrefix(err.Error(), want) { t.Errorf("Error: %v, must start with %s", err, want) } vend := framework.DebugVars() if err := verifyIntValue(vend, "QueryTimeout", int(100*time.Millisecond)); err != nil { t.Error(err) } if err := compareIntDiff(vend, "Kills/Queries", vstart, 1); err != nil { t.Error(err) } }
func TestNull(t *testing.T) { client := framework.NewClient() qr, err := client.Execute("select null from dual", nil) if err != nil { t.Error(err) return } want := mproto.QueryResult{ Fields: []mproto.Field{ { Name: "NULL", Type: mysql.TypeNull, Flags: mysql.FlagBinary, }, }, RowsAffected: 1, Rows: [][]sqltypes.Value{ []sqltypes.Value{ sqltypes.Value{}, }, }, } if !reflect.DeepEqual(*qr, want) { t.Errorf("Execute: \n%#v, want \n%#v", *qr, want) } wantTypes := []query.Type{ sqltypes.Null, } for i, field := range qr.Fields { got := sqltypes.MySQLToType(field.Type, field.Flags) if got != wantTypes[i] { t.Errorf("Unexpected type: col: %d, %d, want %d", i, got, wantTypes[i]) } } }
func TestUncacheableTables(t *testing.T) { client := framework.NewClient() nocacheTables := []struct { name string create string drop string }{{ create: "create table vitess_nocache(eid int, primary key (eid)) comment 'vitess_nocache'", drop: "drop table vitess_nocache", }, { create: "create table vitess_nocache(somecol int)", drop: "drop table vitess_nocache", }, { create: "create table vitess_nocache(charcol varchar(10), primary key(charcol))", drop: "drop table vitess_nocache", }} for _, tcase := range nocacheTables { _, err := client.Execute(tcase.create, nil) if err != nil { t.Error(err) return } table, ok := framework.DebugSchema()["vitess_nocache"] client.Execute(tcase.drop, nil) if !ok { t.Errorf("%s: table vitess_nocache not found in schema", tcase.create) continue } if table.Type != schema.CacheNone { t.Errorf("Type: %d, want %d", table.Type, schema.CacheNone) } } }
func TestCacheTypes(t *testing.T) { client := framework.NewClient() badRequests := []struct { query string bv map[string]interface{} }{{ query: "select * from vitess_cached2 where eid = 'str' and bid = 'str'", }, { query: "select * from vitess_cached2 where eid = :str and bid = :str", bv: map[string]interface{}{"str": "str"}, }, { query: "select * from vitess_cached2 where eid = 1 and bid = 1", }, { query: "select * from vitess_cached2 where eid = :id and bid = :id", bv: map[string]interface{}{"id": 1}, }, { query: "select * from vitess_cached2 where eid = 1.2 and bid = 1.2", }, { query: "select * from vitess_cached2 where eid = :fl and bid = :fl", bv: map[string]interface{}{"fl": 1.2}, }} want := "error: type mismatch" for _, request := range badRequests { _, err := client.Execute(request.query, request.bv) if err == nil || !strings.HasPrefix(err.Error(), want) { t.Errorf("Error: %v, want %s", err, want) } } }
func TestCacheListArgs(t *testing.T) { client := framework.NewClient() query := "select * from vitess_cached1 where eid in ::list" successCases := []struct { bv map[string]interface{} rowcount uint64 }{{ bv: map[string]interface{}{"list": []interface{}{3, 4, 32768}}, rowcount: 2, }, { bv: map[string]interface{}{"list": []interface{}{3, 4}}, rowcount: 2, }, { bv: map[string]interface{}{"list": []interface{}{3}}, rowcount: 1, }} for _, success := range successCases { qr, err := client.Execute(query, success.bv) if err != nil { t.Error(err) continue } if qr.RowsAffected != success.rowcount { t.Errorf("RowsAffected: %d, want %d", qr.RowsAffected, success.rowcount) } } _, err := client.Execute(query, map[string]interface{}{"list": []interface{}{}}) want := "error: empty list supplied" if err == nil || !strings.HasPrefix(err.Error(), want) { t.Errorf("Error: %v, want %s", err, want) return } }
func TestCacheStats(t *testing.T) { client := framework.NewClient() query := "select * from vitess_cached2 where eid = 2 and bid = 'foo'" _, err := client.Execute(query, nil) if err != nil { t.Error(err) return } vstart := framework.DebugVars() _, err = client.Execute(query, nil) if err != nil { t.Error(err) return } if err := compareIntDiff(framework.DebugVars(), "RowcacheStats/vitess_cached2.Hits", vstart, 1); err != nil { t.Error(err) } vstart = framework.DebugVars() _, err = client.Execute("update vitess_part2 set data2 = 2 where key3 = 1", nil) if err != nil { t.Error(err) return } _, err = client.Execute("select * from vitess_view where key2 = 1", nil) if err != nil { t.Error(err) return } if err := compareIntDiff(framework.DebugVars(), "RowcacheStats/vitess_view.Misses", vstart, 1); err != nil { t.Error(err) } }
func TestCacheTypes(t *testing.T) { client := framework.NewClient() badRequests := []struct { query string bv map[string]interface{} out string }{{ query: "select * from vitess_cached2 where eid = 'str' and bid = 'str'", out: "error: strconv.ParseInt", }, { query: "select * from vitess_cached2 where eid = :str and bid = :str", bv: map[string]interface{}{"str": "str"}, out: "error: strconv.ParseInt", }, { query: "select * from vitess_cached2 where eid = 1 and bid = 1", out: "error: type mismatch", }, { query: "select * from vitess_cached2 where eid = :id and bid = :id", bv: map[string]interface{}{"id": 1}, out: "error: type mismatch", }, { query: "select * from vitess_cached2 where eid = 1.2 and bid = 1.2", out: "error: type mismatch", }, { query: "select * from vitess_cached2 where eid = :fl and bid = :fl", bv: map[string]interface{}{"fl": 1.2}, out: "error: type mismatch", }} for _, tcase := range badRequests { _, err := client.Execute(tcase.query, tcase.bv) if err == nil || !strings.HasPrefix(err.Error(), tcase.out) { t.Errorf("%s: %v, want %s", tcase.query, err, tcase.out) } } }
func TestDBAStatements(t *testing.T) { client := framework.NewClient() qr, err := client.Execute("show variables like 'version'", nil) if err != nil { t.Error(err) return } wantCol := sqltypes.MakeTrusted(sqltypes.VarChar, []byte("version")) if !reflect.DeepEqual(qr.Rows[0][0], wantCol) { t.Errorf("Execute: \n%#v, want \n%#v", qr.Rows[0][0], wantCol) } qr, err = client.Execute("describe vitess_a", nil) if err != nil { t.Error(err) return } if qr.RowsAffected != 4 { t.Errorf("RowsAffected: %d, want 4", qr.RowsAffected) } qr, err = client.Execute("explain vitess_a", nil) if err != nil { t.Error(err) return } if qr.RowsAffected != 4 { t.Errorf("RowsAffected: %d, want 4", qr.RowsAffected) } }
func TestSchemaReload(t *testing.T) { conn, err := mysql.Connect(connParams) if err != nil { t.Error(err) return } _, err = conn.ExecuteFetch("create table vitess_temp(intval int)", 10, false) if err != nil { t.Error(err) return } defer func() { _, _ = conn.ExecuteFetch("drop table vitess_temp", 10, false) conn.Close() }() framework.Server.ReloadSchema() client := framework.NewClient() waitTime := 50 * time.Millisecond for i := 0; i < 10; i++ { time.Sleep(waitTime) waitTime += 50 * time.Millisecond _, err = client.Execute("select * from vitess_temp", nil) if err == nil { return } want := "error: table vitess_temp not found in schema" if err.Error() != want { t.Errorf("Error: %v, want %s", err, want) return } } t.Error("schema did not reload") }
func TestNull(t *testing.T) { client := framework.NewClient() qr, err := client.Execute("select null from dual", nil) if err != nil { t.Error(err) return } want := sqltypes.Result{ Fields: []*querypb.Field{ { Name: "NULL", Type: sqltypes.Null, }, }, RowsAffected: 1, Rows: [][]sqltypes.Value{ { {}, }, }, } if !reflect.DeepEqual(*qr, want) { t.Errorf("Execute: \n%#v, want \n%#v", *qr, want) } }
func TestStreamTerminate(t *testing.T) { client := framework.NewClient() err := populateBigData(client) if err != nil { t.Error(err) return } defer client.Execute("delete from vitess_big", nil) called := false err = client.Stream( "select * from vitess_big b1, vitess_big b2 order by b1.id, b2.id", nil, func(*mproto.QueryResult) error { if !called { queries := framework.StreamQueryz() if l := len(queries); l != 1 { t.Errorf("len(queries): %d, want 1", l) return errors.New("no queries from StreamQueryz") } err := framework.StreamTerminate(queries[0].ConnID) if err != nil { return err } called = true } time.Sleep(10 * time.Millisecond) return nil }, ) want := "error: the query was killed" if err == nil || !strings.HasPrefix(err.Error(), want) { t.Errorf("Error: %v, must start with %s", err, want) } }
func TestStreamError(t *testing.T) { _, err := framework.NewClient().StreamExecute("select count(abcd) from vitess_big", nil) want := "error: Unknown column" if err == nil || !strings.HasPrefix(err.Error(), want) { t.Errorf("Error: %v, must start with %s", err, want) } }
func TestForUpdate(t *testing.T) { for _, mode := range []string{"for update", "lock in share mode"} { client := framework.NewClient() query := fmt.Sprintf("select * from vitess_test where intval=2 %s", mode) _, err := client.Execute(query, nil) want := "error: Disallowed" if err == nil || !strings.HasPrefix(err.Error(), want) { t.Errorf("Error: %v, must have prefix %s", err, want) } // We should not get errors here err = client.Begin() if err != nil { t.Error(err) return } _, err = client.Execute(query, nil) if err != nil { t.Error(err) return } err = client.Commit() if err != nil { t.Error(err) return } } }
func TestUncache(t *testing.T) { // Verify rowcache is working vitess_cached2 err := verifyvitessCached2(t, "vitess_cached2") if err != nil { t.Error(err) return } // Disable rowcache for vitess_cached2 client := framework.NewClient() _, err = client.Execute("alter table vitess_cached2 comment 'vitess_nocache'", nil) if err != nil { t.Error(err) return } _, err = client.Execute("select * from vitess_cached2 where eid = 2 and bid = 'foo'", nil) if err != nil { t.Error(err) } if tstat, ok := framework.TableStats()["vitess_cached2"]; ok { t.Errorf("table stats was found: %v, want not found", tstat) } // Re-enable rowcache and verify it's working _, err = client.Execute("alter table vitess_cached2 comment ''", nil) if err != nil { t.Error(err) return } err = verifyvitessCached2(t, "vitess_cached2") if err != nil { t.Error(err) return } }
func TestBatchRead(t *testing.T) { client := framework.NewClient() queries := []querytypes.BoundQuery{{ Sql: "select * from vitess_a where id = :a", BindVariables: map[string]interface{}{"a": 2}, }, { Sql: "select * from vitess_b where id = :b", BindVariables: map[string]interface{}{"b": 2}, }} qr1 := sqltypes.Result{ Fields: []*querypb.Field{{ Name: "eid", Type: sqltypes.Int64, }, { Name: "id", Type: sqltypes.Int32, }, { Name: "name", Type: sqltypes.VarChar, }, { Name: "foo", Type: sqltypes.VarBinary, }}, RowsAffected: 1, Rows: [][]sqltypes.Value{ { sqltypes.MakeTrusted(sqltypes.Int64, []byte("1")), sqltypes.MakeTrusted(sqltypes.Int32, []byte("2")), sqltypes.MakeTrusted(sqltypes.VarChar, []byte("bcde")), sqltypes.MakeTrusted(sqltypes.VarBinary, []byte("fghi")), }, }, } qr2 := sqltypes.Result{ Fields: []*querypb.Field{{ Name: "eid", Type: sqltypes.Int64, }, { Name: "id", Type: sqltypes.Int32, }}, RowsAffected: 1, Rows: [][]sqltypes.Value{ { sqltypes.MakeTrusted(sqltypes.Int64, []byte("1")), sqltypes.MakeTrusted(sqltypes.Int32, []byte("2")), }, }, } want := []sqltypes.Result{qr1, qr2} qrl, err := client.ExecuteBatch(queries, false) if err != nil { t.Error(err) return } if !reflect.DeepEqual(qrl, want) { t.Errorf("ExecueBatch: \n%#v, want \n%#v", qrl, want) } }
func TestNocacheListArgs(t *testing.T) { client := framework.NewClient() query := "select * from vitess_test where intval in ::list" qr, err := client.Execute( query, map[string]interface{}{ "list": []interface{}{2, 3, 4}, }, ) if err != nil { t.Error(err) return } if qr.RowsAffected != 2 { t.Errorf("rows affected: %d, want 2", qr.RowsAffected) } qr, err = client.Execute( query, map[string]interface{}{ "list": []interface{}{3, 4}, }, ) if err != nil { t.Error(err) return } if qr.RowsAffected != 1 { t.Errorf("rows affected: %d, want 1", qr.RowsAffected) } qr, err = client.Execute( query, map[string]interface{}{ "list": []interface{}{3}, }, ) if err != nil { t.Error(err) return } if qr.RowsAffected != 1 { t.Errorf("rows affected: %d, want 1", qr.RowsAffected) } // Error case _, err = client.Execute( query, map[string]interface{}{ "list": []interface{}{}, }, ) want := "error: empty list supplied for list" if err == nil || err.Error() != want { t.Errorf("Error: %v, want %s", err, want) return } }
func TestMMRollbackFlow(t *testing.T) { client := framework.NewClient() defer client.Execute("delete from vitess_test where intval=4", nil) query := "insert into vitess_test (intval, floatval, charval, binval) " + "values(4, null, null, null)" err := client.Begin() if err != nil { t.Error(err) } _, err = client.Execute(query, nil) if err != nil { t.Error(err) } err = client.CreateTransaction("aa", []*querypb.Target{{ Keyspace: "test1", Shard: "0", }, { Keyspace: "test2", Shard: "1", }}) if err != nil { t.Error(err) } client.Rollback() err = client.SetRollback("aa", 0) if err != nil { t.Error(err) } info, err := client.ReadTransaction("aa") if err != nil { t.Error(err) } info.TimeCreated = 0 info.TimeUpdated = 0 wantInfo := &querypb.TransactionMetadata{ Dtid: "aa", State: 3, Participants: []*querypb.Target{{ Keyspace: "test1", Shard: "0", }, { Keyspace: "test2", Shard: "1", }}, } if !reflect.DeepEqual(info, wantInfo) { t.Errorf("ReadTransaction: %#v, want %#v", info, wantInfo) } err = client.ResolveTransaction("aa") if err != nil { t.Error(err) } }
func TestQueryStats(t *testing.T) { client := framework.NewClient() vstart := framework.DebugVars() start := time.Now() query := "select /* query_stats */ eid from vitess_a where eid = :eid" bv := map[string]interface{}{"eid": 1} _, _ = client.Execute(query, bv) stat := framework.QueryStats()[query] duration := int(time.Now().Sub(start)) if stat.Time <= 0 || stat.Time > duration { t.Errorf("stat.Time: %d, must be between 0 and %d", stat.Time, duration) } if stat.MysqlTime <= 0 || stat.MysqlTime > duration { t.Errorf("stat.MysqlTime: %d, must be between 0 and %d", stat.MysqlTime, duration) } stat.Time = 0 stat.MysqlTime = 0 want := framework.QueryStat{ Query: query, Table: "vitess_a", Plan: "PASS_SELECT", QueryCount: 1, RowCount: 2, ErrorCount: 0, } if stat != want { t.Errorf("stat: %+v, want %+v", stat, want) } query = "select /* query_stats */ eid from vitess_a where dontexist(eid) = :eid" _, _ = client.Execute(query, bv) stat = framework.QueryStats()[query] stat.Time = 0 stat.MysqlTime = 0 want = framework.QueryStat{ Query: query, Table: "vitess_a", Plan: "PASS_SELECT", QueryCount: 1, RowCount: 0, ErrorCount: 1, } if stat != want { t.Errorf("stat: %+v, want %+v", stat, want) } vend := framework.DebugVars() if err := compareIntDiff(vend, "QueryCounts/vitess_a.PASS_SELECT", vstart, 2); err != nil { t.Error(err) } if err := compareIntDiff(vend, "QueryRowCounts/vitess_a.PASS_SELECT", vstart, 2); err != nil { t.Error(err) } if err := compareIntDiff(vend, "QueryErrorCounts/vitess_a.PASS_SELECT", vstart, 1); err != nil { t.Error(err) } }
func TestBinary(t *testing.T) { client := framework.NewClient() defer client.Execute("delete from vitess_test where intval in (4,5)", nil) binaryData := "\x00'\"\b\n\r\t\x1a\\\x00\x0f\xf0\xff" // Test without bindvars. _, err := client.Execute( "insert into vitess_test values "+ "(4, null, null, '\\0\\'\\\"\\b\\n\\r\\t\\Z\\\\\x00\x0f\xf0\xff')", nil, ) if err != nil { t.Error(err) return } qr, err := client.Execute("select binval from vitess_test where intval=4", nil) if err != nil { t.Error(err) return } want := mproto.QueryResult{ Fields: []mproto.Field{ { Name: "binval", Type: mysql.TypeVarString, Flags: mysql.FlagBinary, }, }, RowsAffected: 1, Rows: [][]sqltypes.Value{ []sqltypes.Value{ sqltypes.MakeString([]byte(binaryData)), }, }, } if !reflect.DeepEqual(*qr, want) { t.Errorf("Execute: \n%#v, want \n%#v", *qr, want) } // Test with bindvars. _, err = client.Execute( "insert into vitess_test values(5, null, null, :bindata)", map[string]interface{}{"bindata": binaryData}, ) if err != nil { t.Error(err) return } qr, err = client.Execute("select binval from vitess_test where intval=5", nil) if err != nil { t.Error(err) return } if !reflect.DeepEqual(*qr, want) { t.Errorf("Execute: \n%#v, want \n%#v", *qr, want) } }
func TestMiscTypes(t *testing.T) { client := framework.NewClient() defer client.Execute("delete from vitess_misc", nil) _, err := client.Execute( "insert into vitess_misc values(:id, :b, :d, :dt, :t)", map[string]interface{}{ "id": 1, "b": "\x01", "d": "2012-01-01", "dt": "2012-01-01 15:45:45", "t": "15:45:45", }, ) if err != nil { t.Error(err) return } qr, err := client.Execute("select * from vitess_misc where id = 1", nil) if err != nil { t.Error(err) return } want := sqltypes.Result{ Fields: []*querypb.Field{ { Name: "id", Type: sqltypes.Int32, }, { Name: "b", Type: sqltypes.Bit, }, { Name: "d", Type: sqltypes.Date, }, { Name: "dt", Type: sqltypes.Datetime, }, { Name: "t", Type: sqltypes.Time, }, }, RowsAffected: 1, Rows: [][]sqltypes.Value{ { sqltypes.MakeTrusted(sqltypes.Int32, []byte("1")), sqltypes.MakeTrusted(sqltypes.Bit, []byte("\x01")), sqltypes.MakeTrusted(sqltypes.Date, []byte("2012-01-01")), sqltypes.MakeTrusted(sqltypes.Datetime, []byte("2012-01-01 15:45:45")), sqltypes.MakeTrusted(sqltypes.Time, []byte("15:45:45")), }, }, } if !reflect.DeepEqual(*qr, want) { t.Errorf("Execute: \n%#v, want \n%#v", *qr, want) } }
func TestFractionals(t *testing.T) { client := framework.NewClient() defer client.Execute("delete from vitess_fracts", nil) _, err := client.Execute( "insert into vitess_fracts values(:id, :deci, :num, :f, :d)", map[string]interface{}{ "id": 1, "deci": "1.99", "num": "2.99", "f": 3.99, "d": 4.99, }, ) if err != nil { t.Error(err) return } qr, err := client.Execute("select * from vitess_fracts where id = 1", nil) if err != nil { t.Error(err) return } want := sqltypes.Result{ Fields: []*querypb.Field{ { Name: "id", Type: sqltypes.Int32, }, { Name: "deci", Type: sqltypes.Decimal, }, { Name: "num", Type: sqltypes.Decimal, }, { Name: "f", Type: sqltypes.Float32, }, { Name: "d", Type: sqltypes.Float64, }, }, RowsAffected: 1, Rows: [][]sqltypes.Value{ { sqltypes.MakeTrusted(sqltypes.Int32, []byte("1")), sqltypes.MakeTrusted(sqltypes.Decimal, []byte("1.99")), sqltypes.MakeTrusted(sqltypes.Decimal, []byte("2.99")), sqltypes.MakeTrusted(sqltypes.Float32, []byte("3.99")), sqltypes.MakeTrusted(sqltypes.Float64, []byte("4.99")), }, }, } if !reflect.DeepEqual(*qr, want) { t.Errorf("Execute: \n%#v, want \n%#v", *qr, want) } }
func TestStreamUnion(t *testing.T) { qr, err := framework.NewClient().StreamExecute("select 1 from dual union select 1 from dual", nil) if err != nil { t.Error(err) return } if qr.RowsAffected != 1 { t.Errorf("RowsAffected: %d, want 1", qr.RowsAffected) } }
func TestNoData(t *testing.T) { qr, err := framework.NewClient().Execute("select * from vitess_cached2 where eid = 6 and name = 'bar'", nil) if err != nil { t.Error(err) return } if qr.RowsAffected != 0 { t.Errorf("RowsAffected: %d, want 0", qr.RowsAffected) } }
func TestAutoCommitOff(t *testing.T) { framework.Server.SetAutoCommit(false) defer framework.Server.SetAutoCommit(true) _, err := framework.NewClient().Execute("insert into vitess_test values(4, null, null, null)", nil) want := "error: unsupported query" if err == nil || !strings.HasPrefix(err.Error(), want) { t.Errorf("Error: %v, must start with %s", err, want) } }
func TestSequence(t *testing.T) { want := sqltypes.Result{ Fields: []*querypb.Field{{ Name: "nextval", Type: sqltypes.Int64, }}, RowsAffected: 1, Rows: [][]sqltypes.Value{{ sqltypes.MakeTrusted(sqltypes.Int64, []byte("0")), }}, } for wantval := int64(1); wantval < 10; wantval += 2 { want.Rows[0][0] = sqltypes.MakeTrusted(sqltypes.Int64, strconv.AppendInt(nil, wantval, 10)) qr, err := framework.NewClient().Execute("select next value from vitess_seq", nil) if err != nil { t.Error(err) return } if !reflect.DeepEqual(*qr, want) { t.Errorf("Execute: \n%#v, want \n%#v", *qr, want) } } // Verify that the table got updated according to chunk size. want = sqltypes.Result{ RowsAffected: 1, Rows: [][]sqltypes.Value{{ sqltypes.MakeTrusted(sqltypes.Int64, []byte("13")), sqltypes.MakeTrusted(sqltypes.Int64, []byte("3")), sqltypes.MakeTrusted(sqltypes.Int64, []byte("2")), }}, } qr, err := framework.NewClient().Execute("select next_id, cache, increment from vitess_seq", nil) if err != nil { t.Error(err) return } qr.Fields = nil if !reflect.DeepEqual(*qr, want) { t.Errorf("Execute: \n%#v, want \n%#v", *qr, want) } }
func TestIntegrityError(t *testing.T) { vstart := framework.DebugVars() client := framework.NewClient() _, err := client.Execute("insert into vitess_test values(1, null, null, null)", nil) want := "error: Duplicate entry '1'" if err == nil || !strings.HasPrefix(err.Error(), want) { t.Errorf("Error: %v, want prefix %s", err, want) } if err := compareIntDiff(framework.DebugVars(), "InfoErrors/DupKey", vstart, 1); err != nil { t.Error(err) } }