func TestQueryResult(t *testing.T) { // We can't do the reflection test because bson // doesn't do it correctly for embedded fields. want := "\x90\x01\x00\x00\x03Result\x00\x99\x00\x00\x00\x04Fields\x009\x00\x00\x00\x030\x001\x00\x00\x00\x05Name\x00\x04\x00\x00\x00\x00name\x12Type\x00\x01\x00\x00\x00\x00\x00\x00\x00\x12Flags\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?RowsAffected\x00\x02\x00\x00\x00\x00\x00\x00\x00?InsertId\x00\x03\x00\x00\x00\x00\x00\x00\x00\x04Rows\x00 \x00\x00\x00\x040\x00\x18\x00\x00\x00\x050\x00\x01\x00\x00\x00\x001\x051\x00\x02\x00\x00\x00\x00aa\x00\x00\nErr\x00\x00\x03Session\x00\xd0\x00\x00\x00\bInTransaction\x00\x01\x04ShardSessions\x00\xac\x00\x00\x00\x030\x00Q\x00\x00\x00\x05Keyspace\x00\x01\x00\x00\x00\x00a\x05Shard\x00\x01\x00\x00\x00\x000\x05TabletType\x00\a\x00\x00\x00\x00replica\x12TransactionId\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x031\x00P\x00\x00\x00\x05Keyspace\x00\x01\x00\x00\x00\x00b\x05Shard\x00\x01\x00\x00\x00\x001\x05TabletType\x00\x06\x00\x00\x00\x00master\x12TransactionId\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05Error\x00\x05\x00\x00\x00\x00error\x00" custom := QueryResult{ Result: &mproto.QueryResult{ Fields: []mproto.Field{{"name", 1, mproto.VT_ZEROVALUE_FLAG}}, RowsAffected: 2, InsertId: 3, Rows: [][]sqltypes.Value{ {{sqltypes.String("1")}, {sqltypes.String("aa")}}, }, }, Session: &commonSession, Error: "error", } encoded, err := bson.Marshal(&custom) if err != nil { t.Error(err) } got := string(encoded) if want != got { t.Errorf("want\n%#v, got\n%#v", want, got) } var unmarshalled QueryResult err = bson.Unmarshal(encoded, &unmarshalled) if err != nil { t.Error(err) } if !reflect.DeepEqual(custom, unmarshalled) { t.Errorf("want \n%+v, got \n%+v", custom, unmarshalled) } }
func TestQueryResultList(t *testing.T) { reflected, err := bson.Marshal(&reflectQueryResultList{ List: []mproto.QueryResult{{ Fields: []mproto.Field{{"name", 1}}, RowsAffected: 2, InsertId: 3, Rows: [][]sqltypes.Value{ {{sqltypes.String("1")}, {sqltypes.String("aa")}}, }, }}, Session: &commonSession, Error: "error", }) if err != nil { t.Error(err) } want := string(reflected) custom := QueryResultList{ List: []mproto.QueryResult{{ Fields: []mproto.Field{{"name", 1}}, RowsAffected: 2, InsertId: 3, Rows: [][]sqltypes.Value{ {{sqltypes.String("1")}, {sqltypes.String("aa")}}, }, }}, Session: &commonSession, Error: "error", } encoded, err := bson.Marshal(&custom) if err != nil { t.Error(err) } got := string(encoded) if want != got { t.Errorf("want\n%#v, got\n%#v", want, got) } var unmarshalled QueryResultList err = bson.Unmarshal(encoded, &unmarshalled) if err != nil { t.Error(err) } if !reflect.DeepEqual(custom, unmarshalled) { t.Errorf("want \n%#v, got \n%#v", custom, unmarshalled) } unexpected, err := bson.Marshal(&badQueryResultList{}) if err != nil { t.Error(err) } err = bson.Unmarshal(unexpected, &unmarshalled) want = "Unrecognized tag Extra" if err == nil || want != err.Error() { t.Errorf("want %v, got %v", want, err) } }
func TestQueryResultList(t *testing.T) { reflected, err := bson.Marshal(&reflectQueryResultList{ List: []mproto.QueryResult{{ Fields: []mproto.Field{{"name", 1, mproto.VT_ZEROVALUE_FLAG}}, RowsAffected: 2, InsertId: 3, Rows: [][]sqltypes.Value{ {{sqltypes.String("1")}, {sqltypes.String("aa")}}, }, }}, Session: &commonSession, Error: "error", }) if err != nil { t.Error(err) } want := string(reflected) custom := QueryResultList{ List: []mproto.QueryResult{{ Fields: []mproto.Field{{"name", 1, mproto.VT_ZEROVALUE_FLAG}}, RowsAffected: 2, InsertId: 3, Rows: [][]sqltypes.Value{ {{sqltypes.String("1")}, {sqltypes.String("aa")}}, }, }}, Session: &commonSession, Error: "error", } encoded, err := bson.Marshal(&custom) if err != nil { t.Error(err) } got := string(encoded) if want != got { t.Errorf("want\n%+v, got\n%+v", want, got) } var unmarshalled QueryResultList err = bson.Unmarshal(encoded, &unmarshalled) if err != nil { t.Error(err) } if !reflect.DeepEqual(custom, unmarshalled) { t.Errorf("want \n%+v, got \n%+v", custom, unmarshalled) } extra, err := bson.Marshal(&extraQueryResultList{}) if err != nil { t.Error(err) } err = bson.Unmarshal(extra, &unmarshalled) if err != nil { t.Error(err) } }
func TestQueryResult(t *testing.T) { want := "\xcb\x00\x00\x00\x04Fields\x009\x00\x00\x00\x030\x001\x00\x00\x00\x05Name\x00\x04\x00\x00\x00\x00name\x12Type\x00\x01\x00\x00\x00\x00\x00\x00\x00\x12Flags\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12RowsAffected\x00\x02\x00\x00\x00\x00\x00\x00\x00\x12InsertId\x00\x03\x00\x00\x00\x00\x00\x00\x00\x04Rows\x00 \x00\x00\x00\x040\x00\x18\x00\x00\x00\x050\x00\x01\x00\x00\x00\x001\x051\x00\x02\x00\x00\x00\x00aa\x00\x00\x03Err\x002\x00\x00\x00\x12Code\x00\xe8\x03\x00\x00\x00\x00\x00\x00\x05Message\x00\x11\x00\x00\x00\x00failed due to err\x00\x00" custom := QueryResult{ Fields: []Field{{"name", 1, VT_ZEROVALUE_FLAG}}, RowsAffected: 2, InsertId: 3, Rows: [][]sqltypes.Value{ {{sqltypes.Numeric("1")}, {sqltypes.String("aa")}}, }, Err: &RPCError{1000, "failed due to err"}, } encoded, err := bson.Marshal(&custom) if err != nil { t.Error(err) } got := string(encoded) if want != got { t.Errorf("want\n%#v, got\n%#v", want, got) } var unmarshalled QueryResult err = bson.Unmarshal(encoded, &unmarshalled) if err != nil { t.Error(err) } if unmarshalled.Err == nil { t.Errorf("want %#v, got %#v", custom.Err, unmarshalled.Err) } else { if *custom.Err != *unmarshalled.Err { t.Errorf("want %#v, got %#v", custom.Err, unmarshalled.Err) } } if custom.RowsAffected != unmarshalled.RowsAffected { t.Errorf("want %v, got %#v", custom.RowsAffected, unmarshalled.RowsAffected) } if custom.InsertId != unmarshalled.InsertId { t.Errorf("want %v, got %#v", custom.InsertId, unmarshalled.InsertId) } if custom.Fields[0].Name != unmarshalled.Fields[0].Name { t.Errorf("want %v, got %#v", custom.Fields[0].Name, unmarshalled.Fields[0].Name) } if custom.Fields[0].Type != unmarshalled.Fields[0].Type { t.Errorf("want %v, got %#v", custom.Fields[0].Type, unmarshalled.Fields[0].Type) } if !bytes.Equal(custom.Rows[0][0].Raw(), unmarshalled.Rows[0][0].Raw()) { t.Errorf("want %s, got %s", custom.Rows[0][0].Raw(), unmarshalled.Rows[0][0].Raw()) } if !bytes.Equal(custom.Rows[0][1].Raw(), unmarshalled.Rows[0][1].Raw()) { t.Errorf("want %s, got %s", custom.Rows[0][0].Raw(), unmarshalled.Rows[0][0].Raw()) } extra, err := bson.Marshal(&extraQueryResult{}) if err != nil { t.Error(err) } err = bson.Unmarshal(extra, &unmarshalled) if err != nil { t.Error(err) } }
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.Value{Inner: sqltypes.String("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 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.Value{Inner: sqltypes.String(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 TestDeleteVindexFail(t *testing.T) { router, sbc, _, sbclookup := createRouterEnv() sbc.mustFailServer = 1 _, err := routerExec(router, "delete from user where id = 1", nil) want := "execDeleteEqual: shard, host: TestRouter.-20.master" if err == nil || !strings.HasPrefix(err.Error(), want) { t.Errorf("routerExec: %v, want prefix %v", err, want) } sbc.setResults([]*mproto.QueryResult{&mproto.QueryResult{ Fields: []mproto.Field{ {"id", 3, mproto.VT_ZEROVALUE_FLAG}, {"name", 253, mproto.VT_ZEROVALUE_FLAG}, }, RowsAffected: 1, InsertId: 0, Rows: [][]sqltypes.Value{{ {sqltypes.String("foo")}, {sqltypes.String("myname")}, }}, }}) _, err = routerExec(router, "delete from user where id = 1", nil) want = `execDeleteEqual: strconv.ParseInt: parsing "foo": invalid syntax` if err == nil || err.Error() != want { t.Errorf("routerExec: %v, want %v", err, want) } sbclookup.mustFailServer = 1 _, err = routerExec(router, "delete from user where id = 1", nil) want = "execDeleteEqual: hash.Delete: shard, host: TestUnsharded.0.master" if err == nil || !strings.HasPrefix(err.Error(), want) { t.Errorf("routerExec: %v, want prefix %v", err, want) } sbclookup.mustFailServer = 1 _, err = routerExec(router, "delete from music where user_id = 1", nil) want = "execDeleteEqual: lookup.Delete: shard, host: TestUnsharded.0.master" if err == nil || !strings.HasPrefix(err.Error(), want) { t.Errorf("routerExec: %v, want prefix %v", err, want) } }
func TestQueryResult(t *testing.T) { want := "\x85\x00\x00\x00\x04Fields\x00*\x00\x00\x00\x030\x00\"\x00\x00\x00\x05Name\x00\x04\x00\x00\x00\x00name\x12Type\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12RowsAffected\x00\x02\x00\x00\x00\x00\x00\x00\x00\x12InsertId\x00\x03\x00\x00\x00\x00\x00\x00\x00\x04Rows\x00 \x00\x00\x00\x040\x00\x18\x00\x00\x00\x050\x00\x01\x00\x00\x00\x001\x051\x00\x02\x00\x00\x00\x00aa\x00\x00\x00" custom := QueryResult{ Fields: []Field{{"name", 1}}, RowsAffected: 2, InsertId: 3, Rows: [][]sqltypes.Value{ {{sqltypes.Numeric("1")}, {sqltypes.String("aa")}}, }, } encoded, err := bson.Marshal(&custom) if err != nil { t.Error(err) } got := string(encoded) if want != got { t.Errorf("want\n%#v, got\n%#v", want, got) } var unmarshalled QueryResult err = bson.Unmarshal(encoded, &unmarshalled) if err != nil { t.Error(err) } if custom.RowsAffected != unmarshalled.RowsAffected { t.Errorf("want %v, got %#v", custom.RowsAffected, unmarshalled.RowsAffected) } if custom.InsertId != unmarshalled.InsertId { t.Errorf("want %v, got %#v", custom.InsertId, unmarshalled.InsertId) } if custom.Fields[0].Name != unmarshalled.Fields[0].Name { t.Errorf("want %v, got %#v", custom.Fields[0].Name, unmarshalled.Fields[0].Name) } if custom.Fields[0].Type != unmarshalled.Fields[0].Type { t.Errorf("want %v, got %#v", custom.Fields[0].Type, unmarshalled.Fields[0].Type) } if !bytes.Equal(custom.Rows[0][0].Raw(), unmarshalled.Rows[0][0].Raw()) { t.Errorf("want %s, got %s", custom.Rows[0][0].Raw(), unmarshalled.Rows[0][0].Raw()) } if !bytes.Equal(custom.Rows[0][1].Raw(), unmarshalled.Rows[0][1].Raw()) { t.Errorf("want %s, got %s", custom.Rows[0][0].Raw(), unmarshalled.Rows[0][0].Raw()) } unexpected, err := bson.Marshal(&badQueryResult{}) if err != nil { t.Error(err) } err = bson.Unmarshal(unexpected, &unmarshalled) want = "Unrecognized tag Extra" if err == nil || want != err.Error() { t.Errorf("want %v, got %v", want, err) } }
func TestCharaterSet(t *testing.T) { qr, err := framework.NewDefaultClient().Execute("select * from vtocc_test where intval=1", nil) if err != nil { t.Error(err) return } want := mproto.QueryResult{ Fields: []mproto.Field{ { Name: "intval", Type: 3, Flags: 0, }, { Name: "floatval", Type: 4, Flags: 0, }, { Name: "charval", Type: 253, Flags: 0, }, { Name: "binval", Type: 253, Flags: mysql.FlagBinary, }, }, RowsAffected: 1, Rows: [][]sqltypes.Value{ []sqltypes.Value{ sqltypes.Value{Inner: sqltypes.Numeric("1")}, sqltypes.Value{Inner: sqltypes.Fractional("1.12345")}, sqltypes.Value{Inner: sqltypes.String("\xc2\xa2")}, sqltypes.Value{Inner: sqltypes.String("\x00\xff")}, }, }, } if !reflect.DeepEqual(*qr, want) { t.Errorf("Execute: \n%#v, want \n%#v", *qr, want) } }
func (sbc *sandboxConn) Rollback(transactionId int64) error { sbc.ExecCount.Add(1) sbc.RollbackCount.Add(1) if sbc.mustDelay != 0 { time.Sleep(sbc.mustDelay) } return sbc.getError() } // Close does not change ExecCount func (sbc *sandboxConn) Close() { sbc.CloseCount.Add(1) } func (sbc *sandboxConn) EndPoint() topo.EndPoint { return sbc.endPoint } var singleRowResult = &mproto.QueryResult{ Fields: []mproto.Field{ {"id", 3}, {"value", 253}}, RowsAffected: 1, InsertId: 0, Rows: [][]sqltypes.Value{{ {sqltypes.Numeric("1")}, {sqltypes.String("foo")}, }}, }
func TestMiscTypes(t *testing.T) { client := framework.NewDefaultClient() defer client.Execute("delete from vtocc_misc", nil) _, err := client.Execute( "insert into vtocc_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 vtocc_misc where id = 1", nil) if err != nil { t.Error(err) return } want := mproto.QueryResult{ Fields: []mproto.Field{ { Name: "id", Type: mysql.TypeLong, Flags: 0, }, { Name: "b", Type: mysql.TypeBit, Flags: mysql.FlagUnsigned, }, { Name: "d", Type: mysql.TypeDate, Flags: mysql.FlagBinary, }, { Name: "dt", Type: mysql.TypeDatetime, Flags: mysql.FlagBinary, }, { Name: "t", Type: mysql.TypeTime, Flags: mysql.FlagBinary, }, }, RowsAffected: 1, Rows: [][]sqltypes.Value{ []sqltypes.Value{ sqltypes.Value{Inner: sqltypes.Numeric("1")}, sqltypes.Value{Inner: sqltypes.String("\x01")}, sqltypes.Value{Inner: sqltypes.String("2012-01-01")}, sqltypes.Value{Inner: sqltypes.String("2012-01-01 15:45:45")}, sqltypes.Value{Inner: sqltypes.String("15:45:45")}, }, }, } if !reflect.DeepEqual(*qr, want) { t.Errorf("Execute: \n%#v, want \n%#v", *qr, want) } }
func TestStrings(t *testing.T) { client := framework.NewDefaultClient() defer client.Execute("delete from vtocc_strings", nil) _, err := client.Execute( "insert into vtocc_strings values "+ "(:vb, :c, :vc, :b, :tb, :bl, :ttx, :tx, :en, :s)", map[string]interface{}{ "vb": "a", "c": "b", "vc": "c", "b": "d", "tb": "e", "bl": "f", "ttx": "g", "tx": "h", "en": "a", "s": "a,b", }, ) if err != nil { t.Error(err) return } qr, err := client.Execute("select * from vtocc_strings where vb = 'a'", nil) if err != nil { t.Error(err) return } want := mproto.QueryResult{ Fields: []mproto.Field{ { Name: "vb", Type: mysql.TypeVarString, Flags: mysql.FlagBinary, }, { Name: "c", Type: mysql.TypeString, Flags: 0, }, { Name: "vc", Type: mysql.TypeVarString, Flags: 0, }, { Name: "b", Type: mysql.TypeString, Flags: mysql.FlagBinary, }, { Name: "tb", Type: mysql.TypeBlob, Flags: mysql.FlagBinary, }, { Name: "bl", Type: mysql.TypeBlob, Flags: mysql.FlagBinary, }, { Name: "ttx", Type: mysql.TypeBlob, Flags: 0, }, { Name: "tx", Type: mysql.TypeBlob, Flags: 0, }, { Name: "en", Type: mysql.TypeString, Flags: mysql.FlagEnum, }, { Name: "s", Type: mysql.TypeString, Flags: mysql.FlagSet, }, }, RowsAffected: 1, Rows: [][]sqltypes.Value{ []sqltypes.Value{ sqltypes.Value{Inner: sqltypes.String("a")}, sqltypes.Value{Inner: sqltypes.String("b")}, sqltypes.Value{Inner: sqltypes.String("c")}, sqltypes.Value{Inner: sqltypes.String("d\x00\x00\x00")}, sqltypes.Value{Inner: sqltypes.String("e")}, sqltypes.Value{Inner: sqltypes.String("f")}, sqltypes.Value{Inner: sqltypes.String("g")}, sqltypes.Value{Inner: sqltypes.String("h")}, sqltypes.Value{Inner: sqltypes.String("a")}, sqltypes.Value{Inner: sqltypes.String("a,b")}, }, }, } 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 := mproto.QueryResult{ Fields: []mproto.Field{ { Name: "id", Type: mysql.TypeLong, Flags: 0, }, { Name: "b", Type: mysql.TypeBit, Flags: mysql.FlagUnsigned, }, { Name: "d", Type: mysql.TypeDate, Flags: mysql.FlagBinary, }, { Name: "dt", Type: mysql.TypeDatetime, Flags: mysql.FlagBinary, }, { Name: "t", Type: mysql.TypeTime, Flags: mysql.FlagBinary, }, }, RowsAffected: 1, Rows: [][]sqltypes.Value{ []sqltypes.Value{ sqltypes.Value{Inner: sqltypes.Numeric("1")}, sqltypes.Value{Inner: sqltypes.String("\x01")}, sqltypes.Value{Inner: sqltypes.String("2012-01-01")}, sqltypes.Value{Inner: sqltypes.String("2012-01-01 15:45:45")}, sqltypes.Value{Inner: sqltypes.String("15:45:45")}, }, }, } if !reflect.DeepEqual(*qr, want) { t.Errorf("Execute: \n%#v, want \n%#v", *qr, want) } wantTypes := []query.Type{ sqltypes.Int32, sqltypes.Bit, sqltypes.Date, sqltypes.Datetime, sqltypes.Time, } for i, field := range qr.Fields { got, err := sqltypes.MySQLToType(field.Type, field.Flags) if err != nil { t.Errorf("col: %d, err: %v", i, err) continue } if got != wantTypes[i] { t.Errorf("Unexpected type: col: %d, %d, want %d", i, got, wantTypes[i]) } } }
func TestBatchRead(t *testing.T) { client := framework.NewClient() queries := []proto.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 := mproto.QueryResult{ Fields: []mproto.Field{{ Name: "eid", Type: mysql.TypeLonglong, Flags: 0, }, { Name: "id", Type: mysql.TypeLong, Flags: 0, }, { Name: "name", Type: mysql.TypeVarString, Flags: 0, }, { Name: "foo", Type: mysql.TypeVarString, Flags: mysql.FlagBinary, }}, RowsAffected: 1, Rows: [][]sqltypes.Value{ []sqltypes.Value{ sqltypes.Value{Inner: sqltypes.Numeric("1")}, sqltypes.Value{Inner: sqltypes.Numeric("2")}, sqltypes.Value{Inner: sqltypes.String("bcde")}, sqltypes.Value{Inner: sqltypes.String("fghi")}, }, }, } qr2 := mproto.QueryResult{ Fields: []mproto.Field{{ Name: "eid", Type: mysql.TypeLonglong, Flags: 0, }, { Name: "id", Type: mysql.TypeLong, Flags: 0, }}, RowsAffected: 1, Rows: [][]sqltypes.Value{ []sqltypes.Value{ sqltypes.Value{Inner: sqltypes.Numeric("1")}, sqltypes.Value{Inner: sqltypes.Numeric("2")}, }, }, } want := &proto.QueryResultList{ List: []mproto.QueryResult{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 TestDeleteEqual(t *testing.T) { router, sbc, _, sbclookup := createRouterEnv() sbc.setResults([]*mproto.QueryResult{&mproto.QueryResult{ Fields: []mproto.Field{ {"id", 3, mproto.VT_ZEROVALUE_FLAG}, {"name", 253, mproto.VT_ZEROVALUE_FLAG}, }, RowsAffected: 1, InsertId: 0, Rows: [][]sqltypes.Value{{ {sqltypes.Numeric("1")}, {sqltypes.String("myname")}, }}, }}) _, err := routerExec(router, "delete from user where id = 1", nil) if err != nil { t.Error(err) } wantQueries := []tproto.BoundQuery{{ Sql: "select id, name from user where id = 1 for update", BindVariables: map[string]interface{}{}, }, { Sql: "delete from user where id = 1 /* _routing keyspace_id:166b40b44aba4bd6 */", BindVariables: map[string]interface{}{ "keyspace_id": "\x16k@\xb4J\xbaK\xd6", }, }} if !reflect.DeepEqual(sbc.Queries, wantQueries) { t.Errorf("sbc.Queries: %+v, want %+v\n", sbc.Queries, wantQueries) } wantQueries = []tproto.BoundQuery{{ Sql: "delete from user_idx where id in ::id", BindVariables: map[string]interface{}{ "id": []interface{}{int64(1)}, }, }, { Sql: "delete from name_user_map where name in ::name and user_id = :user_id", BindVariables: map[string]interface{}{ "user_id": int64(1), "name": []interface{}{"myname"}, }, }} if !reflect.DeepEqual(sbclookup.Queries, wantQueries) { t.Errorf("sbclookup.Queries: %+v, want %+v\n", sbclookup.Queries, wantQueries) } sbc.Queries = nil sbclookup.Queries = nil sbc.setResults([]*mproto.QueryResult{&mproto.QueryResult{}}) _, err = routerExec(router, "delete from user where id = 1", nil) if err != nil { t.Error(err) } wantQueries = []tproto.BoundQuery{{ Sql: "select id, name from user where id = 1 for update", BindVariables: map[string]interface{}{}, }, { Sql: "delete from user where id = 1 /* _routing keyspace_id:166b40b44aba4bd6 */", BindVariables: map[string]interface{}{ "keyspace_id": "\x16k@\xb4J\xbaK\xd6", }, }} if !reflect.DeepEqual(sbc.Queries, wantQueries) { t.Errorf("sbc.Queries: %+v, want %+v\n", sbc.Queries, wantQueries) } if sbclookup.Queries != nil { t.Errorf("sbclookup.Queries: %+v, want nil\n", sbclookup.Queries) } sbc.Queries = nil sbclookup.Queries = nil sbclookup.setResults([]*mproto.QueryResult{&mproto.QueryResult{}}) _, err = routerExec(router, "delete from music where id = 1", nil) if err != nil { t.Error(err) } wantQueries = []tproto.BoundQuery{{ Sql: "select user_id from music_user_map where music_id = :music_id", BindVariables: map[string]interface{}{ "music_id": int64(1), }, }} if !reflect.DeepEqual(sbclookup.Queries, wantQueries) { t.Errorf("sbclookup.Queries: %+v, want %+v\n", sbclookup.Queries, wantQueries) } if sbc.Queries != nil { t.Errorf("sbc.Queries: %+v, want nil\n", sbc.Queries) } }
func TestStrings(t *testing.T) { client := framework.NewClient() defer client.Execute("delete from vitess_strings", nil) _, err := client.Execute( "insert into vitess_strings values "+ "(:vb, :c, :vc, :b, :tb, :bl, :ttx, :tx, :en, :s)", map[string]interface{}{ "vb": "a", "c": "b", "vc": "c", "b": "d", "tb": "e", "bl": "f", "ttx": "g", "tx": "h", "en": "a", "s": "a,b", }, ) if err != nil { t.Error(err) return } qr, err := client.Execute("select * from vitess_strings where vb = 'a'", nil) if err != nil { t.Error(err) return } want := mproto.QueryResult{ Fields: []mproto.Field{ { Name: "vb", Type: mysql.TypeVarString, Flags: mysql.FlagBinary, }, { Name: "c", Type: mysql.TypeString, Flags: 0, }, { Name: "vc", Type: mysql.TypeVarString, Flags: 0, }, { Name: "b", Type: mysql.TypeString, Flags: mysql.FlagBinary, }, { Name: "tb", Type: mysql.TypeBlob, Flags: mysql.FlagBinary, }, { Name: "bl", Type: mysql.TypeBlob, Flags: mysql.FlagBinary, }, { Name: "ttx", Type: mysql.TypeBlob, Flags: 0, }, { Name: "tx", Type: mysql.TypeBlob, Flags: 0, }, { Name: "en", Type: mysql.TypeString, Flags: mysql.FlagEnum, }, { Name: "s", Type: mysql.TypeString, Flags: mysql.FlagSet, }, }, RowsAffected: 1, Rows: [][]sqltypes.Value{ []sqltypes.Value{ sqltypes.Value{Inner: sqltypes.String("a")}, sqltypes.Value{Inner: sqltypes.String("b")}, sqltypes.Value{Inner: sqltypes.String("c")}, sqltypes.Value{Inner: sqltypes.String("d\x00\x00\x00")}, sqltypes.Value{Inner: sqltypes.String("e")}, sqltypes.Value{Inner: sqltypes.String("f")}, sqltypes.Value{Inner: sqltypes.String("g")}, sqltypes.Value{Inner: sqltypes.String("h")}, sqltypes.Value{Inner: sqltypes.String("a")}, sqltypes.Value{Inner: sqltypes.String("a,b")}, }, }, } if !reflect.DeepEqual(*qr, want) { t.Errorf("Execute: \n%#v, want \n%#v", *qr, want) } wantTypes := []query.Type{ sqltypes.VarBinary, sqltypes.Char, sqltypes.VarChar, sqltypes.Binary, sqltypes.Blob, sqltypes.Blob, sqltypes.Text, sqltypes.Text, sqltypes.Enum, sqltypes.Set, } for i, field := range qr.Fields { got, err := sqltypes.MySQLToType(field.Type, field.Flags) if err != nil { t.Errorf("col: %d, err: %v", i, err) continue } if got != wantTypes[i] { t.Errorf("Unexpected type: col: %d, %d, want %d", i, got, wantTypes[i]) } } }
func TestBindInSelect(t *testing.T) { client := framework.NewClient() // Int bind var. qr, err := client.Execute( "select :bv from dual", map[string]interface{}{"bv": 1}, ) if err != nil { t.Error(err) return } want := &mproto.QueryResult{ Fields: []mproto.Field{{ Name: "1", Type: mysql.TypeLonglong, Flags: mysql.FlagBinary, }}, RowsAffected: 1, Rows: [][]sqltypes.Value{ []sqltypes.Value{ sqltypes.Value{Inner: sqltypes.Numeric("1")}, }, }, } if !reflect.DeepEqual(qr, want) { t.Errorf("Execute: \n%#v, want \n%#v", qr, want) } // String bind var. qr, err = client.Execute( "select :bv from dual", map[string]interface{}{"bv": "abcd"}, ) if err != nil { t.Error(err) return } want = &mproto.QueryResult{ Fields: []mproto.Field{{ Name: "abcd", Type: mysql.TypeVarString, Flags: 0, }}, RowsAffected: 1, Rows: [][]sqltypes.Value{ []sqltypes.Value{ sqltypes.Value{Inner: sqltypes.String("abcd")}, }, }, } if !reflect.DeepEqual(qr, want) { t.Errorf("Execute: \n%#v, want \n%#v", qr, want) } // Binary bind var. qr, err = client.Execute( "select :bv from dual", map[string]interface{}{"bv": "\x00\xff"}, ) if err != nil { t.Error(err) return } want = &mproto.QueryResult{ Fields: []mproto.Field{{ Name: "", Type: mysql.TypeVarString, Flags: 0, }}, RowsAffected: 1, Rows: [][]sqltypes.Value{ []sqltypes.Value{ sqltypes.Value{Inner: sqltypes.String("\x00\xff")}, }, }, } if !reflect.DeepEqual(qr, want) { t.Errorf("Execute: \n%#v, want \n%#v", qr, want) } }
func TestCompareRows(t *testing.T) { table := []struct { fields []mproto.Field left, right []sqltypes.Value want int }{ { fields: []mproto.Field{{"a", mproto.VT_LONG, mproto.VT_ZEROVALUE_FLAG}}, left: []sqltypes.Value{{sqltypes.Numeric("123")}}, right: []sqltypes.Value{{sqltypes.Numeric("14")}}, want: 1, }, { fields: []mproto.Field{ {"a", mproto.VT_LONG, mproto.VT_ZEROVALUE_FLAG}, {"b", mproto.VT_LONG, mproto.VT_ZEROVALUE_FLAG}, }, left: []sqltypes.Value{ {sqltypes.Numeric("555")}, {sqltypes.Numeric("12")}, }, right: []sqltypes.Value{ {sqltypes.Numeric("555")}, {sqltypes.Numeric("144")}, }, want: -1, }, { fields: []mproto.Field{{"a", mproto.VT_LONG, mproto.VT_ZEROVALUE_FLAG}}, left: []sqltypes.Value{{sqltypes.Numeric("144")}}, right: []sqltypes.Value{{sqltypes.Numeric("144")}}, want: 0, }, { fields: []mproto.Field{{"a", mproto.VT_LONGLONG, mproto.VT_UNSIGNED_FLAG}}, left: []sqltypes.Value{{sqltypes.Numeric("9223372036854775809")}}, right: []sqltypes.Value{{sqltypes.Numeric("9223372036854775810")}}, want: -1, }, { fields: []mproto.Field{{"a", mproto.VT_LONGLONG, mproto.VT_UNSIGNED_FLAG}}, left: []sqltypes.Value{{sqltypes.Numeric("9223372036854775819")}}, right: []sqltypes.Value{{sqltypes.Numeric("9223372036854775810")}}, want: 1, }, { fields: []mproto.Field{{"a", mproto.VT_DOUBLE, mproto.VT_ZEROVALUE_FLAG}}, left: []sqltypes.Value{{sqltypes.Fractional("3.14")}}, right: []sqltypes.Value{{sqltypes.Fractional("3.2")}}, want: -1, }, { fields: []mproto.Field{{"a", mproto.VT_DOUBLE, mproto.VT_ZEROVALUE_FLAG}}, left: []sqltypes.Value{{sqltypes.Fractional("123.4")}}, right: []sqltypes.Value{{sqltypes.Fractional("123.2")}}, want: 1, }, { fields: []mproto.Field{{"a", mproto.VT_STRING, mproto.VT_ZEROVALUE_FLAG}}, left: []sqltypes.Value{{sqltypes.String("abc")}}, right: []sqltypes.Value{{sqltypes.String("abb")}}, want: 1, }, { fields: []mproto.Field{{"a", mproto.VT_STRING, mproto.VT_ZEROVALUE_FLAG}}, left: []sqltypes.Value{{sqltypes.String("abc")}}, right: []sqltypes.Value{{sqltypes.String("abd")}}, want: -1, }, } for _, tc := range table { got, err := CompareRows(tc.fields, len(tc.fields), tc.left, tc.right) if err != nil { t.Errorf("CompareRows error: %v", err) continue } if got != tc.want { t.Errorf("CompareRows(%v, %v, %v) = %v, want %v", tc.fields, tc.left, tc.right, got, tc.want) } } }