Beispiel #1
0
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])
		}
	}
}
Beispiel #2
0
// FetchNext returns the next row for a query
func (conn *Connection) FetchNext() (row []sqltypes.Value, err error) {
	vtrow := C.vt_fetch_next(&conn.c)
	if vtrow.has_error != 0 {
		return nil, conn.lastError("")
	}
	rowPtr := (*[maxSize]*[maxSize]byte)(unsafe.Pointer(vtrow.mysql_row))
	if rowPtr == nil {
		return nil, nil
	}
	colCount := int(conn.c.num_fields)
	cfields := (*[maxSize]C.MYSQL_FIELD)(unsafe.Pointer(conn.c.fields))
	row = make([]sqltypes.Value, colCount)
	lengths := (*[maxSize]uint64)(unsafe.Pointer(vtrow.lengths))
	totalLength := uint64(0)
	for i := 0; i < colCount; i++ {
		totalLength += lengths[i]
	}
	arena := make([]byte, 0, int(totalLength))
	for i := 0; i < colCount; i++ {
		colLength := lengths[i]
		colPtr := rowPtr[i]
		if colPtr == nil {
			continue
		}
		start := len(arena)
		arena = append(arena, colPtr[:colLength]...)
		// MySQL values can be trusted.
		row[i] = sqltypes.MakeTrusted(
			sqltypes.MySQLToType(int64(cfields[i]._type), int64(cfields[i].flags)),
			arena[start:start+int(colLength)],
		)
	}
	return row, nil
}
Beispiel #3
0
// FieldsToProto3 converts an internal []Field to the proto3 version
func FieldsToProto3(f []Field) []*pbq.Field {
	if len(f) == 0 {
		return nil
	}

	result := make([]*pbq.Field, len(f))
	for i, f := range f {
		result[i] = &pbq.Field{
			Name: f.Name,
			Type: sqltypes.MySQLToType(f.Type, f.Flags),
		}
	}
	return result
}
Beispiel #4
0
// FieldsToProto3 converts an internal []Field to the proto3 version
func FieldsToProto3(f []Field) ([]*pbq.Field, error) {
	if len(f) == 0 {
		return nil, nil
	}

	result := make([]*pbq.Field, len(f))
	for i, f := range f {
		vitessType, err := sqltypes.MySQLToType(f.Type, f.Flags)
		if err != nil {
			return nil, err
		}
		result[i] = &pbq.Field{
			Name: f.Name,
			Type: vitessType,
		}
	}
	return result, nil
}
Beispiel #5
0
// Fields returns the current fields description for the query
func (conn *Connection) Fields() (fields []*querypb.Field) {
	nfields := int(conn.c.num_fields)
	if nfields == 0 {
		return nil
	}
	cfields := (*[maxSize]C.MYSQL_FIELD)(unsafe.Pointer(conn.c.fields))
	totalLength := uint64(0)
	for i := 0; i < nfields; i++ {
		totalLength += uint64(cfields[i].name_length)
	}
	fields = make([]*querypb.Field, nfields)
	fvals := make([]querypb.Field, nfields)
	for i := 0; i < nfields; i++ {
		length := cfields[i].name_length
		fname := (*[maxSize]byte)(unsafe.Pointer(cfields[i].name))[:length]
		fvals[i].Name = string(fname)
		fvals[i].Type = sqltypes.MySQLToType(int64(cfields[i]._type), int64(cfields[i].flags))
		fields[i] = &fvals[i]
	}
	return fields
}
Beispiel #6
0
func (ti *TableInfo) fetchColumns(conn *DBConn) error {
	qr, err := conn.Exec(context.Background(), fmt.Sprintf("select * from `%s` where 1 != 1", ti.Name), 10000, true)
	if err != nil {
		return err
	}
	fieldTypes := make(map[string]query.Type, len(qr.Fields))
	for _, field := range qr.Fields {
		fieldTypes[field.Name] = sqltypes.MySQLToType(field.Type, field.Flags)
	}
	columns, err := conn.Exec(context.Background(), fmt.Sprintf("describe `%s`", ti.Name), 10000, false)
	if err != nil {
		return err
	}
	for _, row := range columns.Rows {
		name := row[0].String()
		columnType, ok := fieldTypes[name]
		if !ok {
			log.Warningf("Table: %s, column %s not found in select list, skipping.", ti.Name, name)
			continue
		}
		ti.AddColumn(name, columnType, row[4], row[5].String())
	}
	return nil
}
Beispiel #7
0
func TestInts(t *testing.T) {
	client := framework.NewClient()
	defer client.Execute("delete from vitess_ints", nil)

	_, err := client.Execute(
		"insert into vitess_ints values(:tiny, :tinyu, :small, "+
			":smallu, :medium, :mediumu, :normal, :normalu, :big, :bigu, :year)",
		map[string]interface{}{
			"tiny":    int32(-128),
			"tinyu":   uint32(255),
			"small":   int32(-32768),
			"smallu":  uint32(65535),
			"medium":  int32(-8388608),
			"mediumu": uint32(16777215),
			"normal":  int64(-2147483648),
			"normalu": uint64(4294967295),
			"big":     int64(-9223372036854775808),
			"bigu":    uint64(18446744073709551615),
			"year":    2012,
		},
	)
	if err != nil {
		t.Error(err)
		return
	}
	qr, err := client.Execute("select * from vitess_ints where tiny = -128", nil)
	if err != nil {
		t.Error(err)
		return
	}
	want := mproto.QueryResult{
		Fields: []mproto.Field{
			{
				Name:  "tiny",
				Type:  mysql.TypeTiny,
				Flags: 0,
			}, {
				Name:  "tinyu",
				Type:  mysql.TypeTiny,
				Flags: mysql.FlagUnsigned,
			}, {
				Name:  "small",
				Type:  mysql.TypeShort,
				Flags: 0,
			}, {
				Name:  "smallu",
				Type:  mysql.TypeShort,
				Flags: mysql.FlagUnsigned,
			}, {
				Name:  "medium",
				Type:  mysql.TypeInt24,
				Flags: 0,
			}, {
				Name:  "mediumu",
				Type:  mysql.TypeInt24,
				Flags: mysql.FlagUnsigned,
			}, {
				Name:  "normal",
				Type:  mysql.TypeLong,
				Flags: 0,
			}, {
				Name:  "normalu",
				Type:  mysql.TypeLong,
				Flags: mysql.FlagUnsigned,
			}, {
				Name:  "big",
				Type:  mysql.TypeLonglong,
				Flags: 0,
			}, {
				Name:  "bigu",
				Type:  mysql.TypeLonglong,
				Flags: mysql.FlagUnsigned,
			}, {
				Name:  "y",
				Type:  mysql.TypeYear,
				Flags: mysql.FlagUnsigned,
			},
		},
		RowsAffected: 1,
		Rows: [][]sqltypes.Value{
			[]sqltypes.Value{
				sqltypes.MakeNumeric([]byte("-128")),
				sqltypes.MakeNumeric([]byte("255")),
				sqltypes.MakeNumeric([]byte("-32768")),
				sqltypes.MakeNumeric([]byte("65535")),
				sqltypes.MakeNumeric([]byte("-8388608")),
				sqltypes.MakeNumeric([]byte("16777215")),
				sqltypes.MakeNumeric([]byte("-2147483648")),
				sqltypes.MakeNumeric([]byte("4294967295")),
				sqltypes.MakeNumeric([]byte("-9223372036854775808")),
				sqltypes.MakeNumeric([]byte("18446744073709551615")),
				sqltypes.MakeNumeric([]byte("2012")),
			},
		},
	}
	if !reflect.DeepEqual(*qr, want) {
		t.Errorf("Execute: \n%#v, want \n%#v", *qr, want)
	}
	wantTypes := []query.Type{
		sqltypes.Int8,
		sqltypes.Uint8,
		sqltypes.Int16,
		sqltypes.Uint16,
		sqltypes.Int24,
		sqltypes.Uint24,
		sqltypes.Int32,
		sqltypes.Uint32,
		sqltypes.Int64,
		sqltypes.Uint64,
		sqltypes.Year,
	}
	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])
		}
	}
}
Beispiel #8
0
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.MakeNumeric([]byte("1")),
				sqltypes.MakeString([]byte("\x01")),
				sqltypes.MakeString([]byte("2012-01-01")),
				sqltypes.MakeString([]byte("2012-01-01 15:45:45")),
				sqltypes.MakeString([]byte("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 := sqltypes.MySQLToType(field.Type, field.Flags)
		if got != wantTypes[i] {
			t.Errorf("Unexpected type: col: %d, %d, want %d", i, got, wantTypes[i])
		}
	}
}
Beispiel #9
0
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.MakeString([]byte("a")),
				sqltypes.MakeString([]byte("b")),
				sqltypes.MakeString([]byte("c")),
				sqltypes.MakeString([]byte("d\x00\x00\x00")),
				sqltypes.MakeString([]byte("e")),
				sqltypes.MakeString([]byte("f")),
				sqltypes.MakeString([]byte("g")),
				sqltypes.MakeString([]byte("h")),
				sqltypes.MakeString([]byte("a")),
				sqltypes.MakeString([]byte("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 := sqltypes.MySQLToType(field.Type, field.Flags)
		if got != wantTypes[i] {
			t.Errorf("Unexpected type: col: %d, %d, want %d", i, got, wantTypes[i])
		}
	}
}
Beispiel #10
0
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 := mproto.QueryResult{
		Fields: []mproto.Field{
			{
				Name:  "id",
				Type:  mysql.TypeLong,
				Flags: 0,
			}, {
				Name:  "deci",
				Type:  mysql.TypeNewDecimal,
				Flags: 0,
			}, {
				Name:  "num",
				Type:  mysql.TypeNewDecimal,
				Flags: 0,
			}, {
				Name:  "f",
				Type:  mysql.TypeFloat,
				Flags: 0,
			}, {
				Name:  "d",
				Type:  mysql.TypeDouble,
				Flags: 0,
			},
		},
		RowsAffected: 1,
		Rows: [][]sqltypes.Value{
			[]sqltypes.Value{
				sqltypes.MakeNumeric([]byte("1")),
				sqltypes.MakeFractional([]byte("1.99")),
				sqltypes.MakeFractional([]byte("2.99")),
				sqltypes.MakeFractional([]byte("3.99")),
				sqltypes.MakeFractional([]byte("4.99")),
			},
		},
	}
	if !reflect.DeepEqual(*qr, want) {
		t.Errorf("Execute: \n%#v, want \n%#v", *qr, want)
	}
	wantTypes := []query.Type{
		sqltypes.Int32,
		sqltypes.Decimal,
		sqltypes.Decimal,
		sqltypes.Float32,
		sqltypes.Float64,
	}
	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])
		}
	}
}
Beispiel #11
0
// UnmarshalBson bson-decodes into QueryResult.
func (queryResult *QueryResult) UnmarshalBson(buf *bytes.Buffer, kind byte) {
	switch kind {
	case bson.EOO, bson.Object:
		// valid
	case bson.Null:
		return
	default:
		panic(bson.NewBsonError("unexpected kind %v for QueryResult", kind))
	}
	bson.Next(buf, 4)

	for kind := bson.NextByte(buf); kind != bson.EOO; kind = bson.NextByte(buf) {
		switch bson.ReadCString(buf) {
		case "Fields":
			// []*query.Field
			if kind != bson.Null {
				if kind != bson.Array {
					panic(bson.NewBsonError("unexpected kind %v for queryResult.Fields", kind))
				}
				bson.Next(buf, 4)
				queryResult.Fields = make([]*querypb.Field, 0, 8)
				var f BSONField
				for kind := bson.NextByte(buf); kind != bson.EOO; kind = bson.NextByte(buf) {
					bson.SkipIndex(buf)
					var _v1 *querypb.Field
					// *query.Field
					_v1 = new(querypb.Field)
					bson.UnmarshalFromBuffer(buf, &f)
					_v1.Name = f.Name
					_v1.Type = sqltypes.MySQLToType(f.Type, f.Flags)
					queryResult.Fields = append(queryResult.Fields, _v1)
				}
			}
		case "RowsAffected":
			queryResult.RowsAffected = bson.DecodeUint64(buf, kind)
		case "InsertId":
			queryResult.InsertId = bson.DecodeUint64(buf, kind)
		case "Rows":
			// [][]sqltypes.Value
			if kind != bson.Null {
				if kind != bson.Array {
					panic(bson.NewBsonError("unexpected kind %v for queryResult.Rows", kind))
				}
				bson.Next(buf, 4)
				queryResult.Rows = make([][]sqltypes.Value, 0, 8)
				for kind := bson.NextByte(buf); kind != bson.EOO; kind = bson.NextByte(buf) {
					bson.SkipIndex(buf)
					var _v2 []sqltypes.Value
					// []sqltypes.Value
					if kind != bson.Null {
						if kind != bson.Array {
							panic(bson.NewBsonError("unexpected kind %v for _v2", kind))
						}
						bson.Next(buf, 4)
						_v2 = make([]sqltypes.Value, 0, 8)
						for kind := bson.NextByte(buf); kind != bson.EOO; kind = bson.NextByte(buf) {
							bson.SkipIndex(buf)
							var _v3 sqltypes.Value
							_v3.UnmarshalBson(buf, kind)
							_v2 = append(_v2, _v3)
						}
					}
					queryResult.Rows = append(queryResult.Rows, _v2)
				}
			}
		case "Err":
			// *RPCError
			if kind != bson.Null {
				queryResult.Err = new(RPCError)
				(*queryResult.Err).UnmarshalBson(buf, kind)
			}
		default:
			bson.Skip(buf, kind)
		}
	}
}