Пример #1
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 := 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.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)
	}
}
Пример #2
0
func TestLookupHashAutoMapBadData(t *testing.T) {
	result := &mproto.QueryResult{
		Fields: []mproto.Field{{
			Type: mproto.VT_INT24,
		}},
		Rows: [][]sqltypes.Value{
			[]sqltypes.Value{
				sqltypes.MakeFractional([]byte("1.1")),
			},
		},
		RowsAffected: 1,
	}
	vc := &vcursor{result: result}
	_, err := lha.(planbuilder.NonUnique).Map(vc, []interface{}{1, int32(2)})
	want := `lookup.Map: strconv.ParseInt: parsing "1.1": invalid syntax`
	if err == nil || err.Error() != want {
		t.Errorf("lha.Map: %v, want %v", err, want)
	}

	result.Fields = []mproto.Field{{
		Type: mproto.VT_FLOAT,
	}}
	vc = &vcursor{result: result}
	_, err = lha.(planbuilder.NonUnique).Map(vc, []interface{}{1, int32(2)})
	want = `lookup.Map: unexpected type for 1.1: float64`
	if err == nil || err.Error() != want {
		t.Errorf("lha.Map: %v, want %v", err, want)
	}
}
Пример #3
0
// makeValueString returns a string that contains all the passed-in rows
// as an insert SQL command's parameters.
func makeValueString(fields []mproto.Field, rows [][]sqltypes.Value) string {
	buf := bytes.Buffer{}
	for i, row := range rows {
		if i > 0 {
			buf.Write([]byte(",("))
		} else {
			buf.WriteByte('(')
		}
		for j, value := range row {
			if j > 0 {
				buf.WriteByte(',')
			}
			// convert value back to its original type
			if !value.IsNull() {
				switch fields[j].Type {
				case mproto.VT_TINY, mproto.VT_SHORT, mproto.VT_LONG, mproto.VT_LONGLONG, mproto.VT_INT24:
					value = sqltypes.MakeNumeric(value.Raw())
				case mproto.VT_FLOAT, mproto.VT_DOUBLE:
					value = sqltypes.MakeFractional(value.Raw())
				}
			}
			value.EncodeSql(&buf)
		}
		buf.WriteByte(')')
	}
	return buf.String()
}
Пример #4
0
// makeValueString returns a string that contains all the passed-in rows
// as an insert SQL command's parameters.
func makeValueString(fields []*query.Field, rows [][]sqltypes.Value) string {
	buf := bytes.Buffer{}
	for i, row := range rows {
		if i > 0 {
			buf.Write([]byte(",("))
		} else {
			buf.WriteByte('(')
		}
		for j, value := range row {
			if j > 0 {
				buf.WriteByte(',')
			}
			// convert value back to its original type
			if !value.IsNull() {
				switch {
				case sqltypes.IsIntegral(fields[j].Type):
					value = sqltypes.MakeNumeric(value.Raw())
				case sqltypes.IsFloat(fields[j].Type):
					value = sqltypes.MakeFractional(value.Raw())
				}
			}
			value.EncodeSQL(&buf)
		}
		buf.WriteByte(')')
	}
	return buf.String()
}
Пример #5
0
func BuildValue(bytes []byte, fieldType uint32) sqltypes.Value {
	switch fieldType {
	case C.MYSQL_TYPE_DECIMAL, C.MYSQL_TYPE_FLOAT, C.MYSQL_TYPE_DOUBLE, C.MYSQL_TYPE_NEWDECIMAL:
		return sqltypes.MakeFractional(bytes)
	case C.MYSQL_TYPE_TIMESTAMP:
		return sqltypes.MakeString(bytes)
	}
	// The below condition represents the following list of values:
	// C.MYSQL_TYPE_TINY, C.MYSQL_TYPE_SHORT, C.MYSQL_TYPE_LONG, C.MYSQL_TYPE_LONGLONG, C.MYSQL_TYPE_INT24, C.MYSQL_TYPE_YEAR:
	if fieldType <= C.MYSQL_TYPE_INT24 || fieldType == C.MYSQL_TYPE_YEAR {
		return sqltypes.MakeNumeric(bytes)
	}
	return sqltypes.MakeString(bytes)
}
Пример #6
0
// BuildValue returns a sqltypes.Value from the passed in fields
func BuildValue(bytes []byte, fieldType uint32) sqltypes.Value {
	if bytes == nil {
		return sqltypes.NULL
	}
	switch fieldType {
	case typeDecimal, TypeFloat, TypeDouble, TypeNewDecimal:
		return sqltypes.MakeFractional(bytes)
	case TypeTimestamp:
		return sqltypes.MakeString(bytes)
	}
	// The below condition represents the following list of values:
	// TypeTiny, TypeShort, TypeLong, TypeLonglong, TypeInt24, TypeYear:
	if fieldType <= TypeInt24 || fieldType == TypeYear {
		return sqltypes.MakeNumeric(bytes)
	}
	return sqltypes.MakeString(bytes)
}
Пример #7
0
func TestCharaterSet(t *testing.T) {
	qr, err := framework.NewClient().Execute("select * from vitess_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.MakeNumeric([]byte("1")),
				sqltypes.MakeFractional([]byte("1.12345")),
				sqltypes.MakeString([]byte("\xc2\xa2")),
				sqltypes.MakeString([]byte("\x00\xff")),
			},
		},
	}
	if !reflect.DeepEqual(*qr, want) {
		t.Errorf("Execute: \n%#v, want \n%#v", *qr, want)
	}
}
Пример #8
0
func TestLookupHashUniqueAutoMapBadData(t *testing.T) {
	result := &sqltypes.Result{
		Fields: []*query.Field{{
			Type: sqltypes.Int24,
		}},
		Rows: [][]sqltypes.Value{
			[]sqltypes.Value{
				sqltypes.MakeFractional([]byte("1.1")),
			},
		},
		RowsAffected: 1,
	}
	vc := &vcursor{result: result}
	_, err := lhua.(planbuilder.Unique).Map(vc, []interface{}{1, int32(2)})
	want := `lookup.Map: strconv.ParseInt: parsing "1.1": invalid syntax`
	if err == nil || err.Error() != want {
		t.Errorf("lhua.Map: %v, want %v", err, want)
	}

	result.Fields = []*query.Field{{
		Type: sqltypes.Float32,
	}}
	vc = &vcursor{result: result}
	_, err = lhua.(planbuilder.Unique).Map(vc, []interface{}{1, int32(2)})
	want = `lookup.Map: unexpected type for 1.1: float64`
	if err == nil || err.Error() != want {
		t.Errorf("lhua.Map: %v, want %v", err, want)
	}

	vc = &vcursor{numRows: 2}
	_, err = lhua.(planbuilder.Unique).Map(vc, []interface{}{1, int32(2)})
	want = `lookup.Map: unexpected multiple results from vindex t: 1`
	if err == nil || err.Error() != want {
		t.Errorf("lhua.Map: %v, want %v", err, want)
	}
}
Пример #9
0
func TestBindVariablesToProto3(t *testing.T) {
	testcases := []struct {
		name string
		in   interface{}
		out  *query.BindVariable
	}{{
		name: "string",
		in:   "aa",
		out: &query.BindVariable{
			Type:  sqltypes.VarChar,
			Value: []byte("aa"),
		},
	}, {
		name: "[]byte",
		in:   []byte("aa"),
		out: &query.BindVariable{
			Type:  sqltypes.VarBinary,
			Value: []byte("aa"),
		},
	}, {
		name: "int",
		in:   int(1),
		out: &query.BindVariable{
			Type:  sqltypes.Int64,
			Value: []byte("1"),
		},
	}, {
		name: "int8",
		in:   int8(-1),
		out: &query.BindVariable{
			Type:  sqltypes.Int64,
			Value: []byte("-1"),
		},
	}, {
		name: "int16",
		in:   int16(-1),
		out: &query.BindVariable{
			Type:  sqltypes.Int64,
			Value: []byte("-1"),
		},
	}, {
		name: "int32",
		in:   int32(-1),
		out: &query.BindVariable{
			Type:  sqltypes.Int64,
			Value: []byte("-1"),
		},
	}, {
		name: "int64",
		in:   int64(-1),
		out: &query.BindVariable{
			Type:  sqltypes.Int64,
			Value: []byte("-1"),
		},
	}, {
		name: "uint",
		in:   uint(1),
		out: &query.BindVariable{
			Type:  sqltypes.Uint64,
			Value: []byte("1"),
		},
	}, {
		name: "uint8",
		in:   uint8(1),
		out: &query.BindVariable{
			Type:  sqltypes.Uint64,
			Value: []byte("1"),
		},
	}, {
		name: "uint16",
		in:   uint16(1),
		out: &query.BindVariable{
			Type:  sqltypes.Uint64,
			Value: []byte("1"),
		},
	}, {
		name: "uint32",
		in:   uint32(1),
		out: &query.BindVariable{
			Type:  sqltypes.Uint64,
			Value: []byte("1"),
		},
	}, {
		name: "uint64",
		in:   uint64(1),
		out: &query.BindVariable{
			Type:  sqltypes.Uint64,
			Value: []byte("1"),
		},
	}, {
		name: "float32",
		in:   float32(1.5),
		out: &query.BindVariable{
			Type:  sqltypes.Float64,
			Value: []byte("1.5"),
		},
	}, {
		name: "float64",
		in:   float64(1.5),
		out: &query.BindVariable{
			Type:  sqltypes.Float64,
			Value: []byte("1.5"),
		},
	}, {
		name: "sqltypes.NULL",
		in:   sqltypes.NULL,
		out:  &query.BindVariable{},
	}, {
		name: "nil",
		in:   nil,
		out:  &query.BindVariable{},
	}, {
		name: "sqltypes.Integral",
		in:   sqltypes.MakeNumeric([]byte("1")),
		out: &query.BindVariable{
			Type:  sqltypes.Int64,
			Value: []byte("1"),
		},
	}, {
		name: "sqltypes.Fractional",
		in:   sqltypes.MakeFractional([]byte("1.5")),
		out: &query.BindVariable{
			Type:  sqltypes.Float64,
			Value: []byte("1.5"),
		},
	}, {
		name: "sqltypes.String",
		in:   sqltypes.MakeString([]byte("aa")),
		out: &query.BindVariable{
			Type:  sqltypes.VarBinary,
			Value: []byte("aa"),
		},
	}, {
		name: "[]interface{}",
		in:   []interface{}{1, "aa", sqltypes.MakeFractional([]byte("1.5"))},
		out: &query.BindVariable{
			Type: sqltypes.Tuple,
			Values: []*query.Value{
				&query.Value{
					Type:  sqltypes.Int64,
					Value: []byte("1"),
				},
				&query.Value{
					Type:  sqltypes.VarChar,
					Value: []byte("aa"),
				},
				&query.Value{
					Type:  sqltypes.Float64,
					Value: []byte("1.5"),
				},
			},
		},
	}, {
		name: "[]string",
		in:   []string{"aa", "bb"},
		out: &query.BindVariable{
			Type: sqltypes.Tuple,
			Values: []*query.Value{
				&query.Value{
					Type:  sqltypes.VarChar,
					Value: []byte("aa"),
				},
				&query.Value{
					Type:  sqltypes.VarChar,
					Value: []byte("bb"),
				},
			},
		},
	}, {
		name: "[][]byte",
		in:   [][]byte{[]byte("aa"), []byte("bb")},
		out: &query.BindVariable{
			Type: sqltypes.Tuple,
			Values: []*query.Value{
				&query.Value{
					Type:  sqltypes.VarBinary,
					Value: []byte("aa"),
				},
				&query.Value{
					Type:  sqltypes.VarBinary,
					Value: []byte("bb"),
				},
			},
		},
	}, {
		name: "[]int",
		in:   []int{1, 2},
		out: &query.BindVariable{
			Type: sqltypes.Tuple,
			Values: []*query.Value{
				&query.Value{
					Type:  sqltypes.Int64,
					Value: []byte("1"),
				},
				&query.Value{
					Type:  sqltypes.Int64,
					Value: []byte("2"),
				},
			},
		},
	}, {
		name: "[]int64",
		in:   []int64{1, 2},
		out: &query.BindVariable{
			Type: sqltypes.Tuple,
			Values: []*query.Value{
				&query.Value{
					Type:  sqltypes.Int64,
					Value: []byte("1"),
				},
				&query.Value{
					Type:  sqltypes.Int64,
					Value: []byte("2"),
				},
			},
		},
	}, {
		name: "[]uint64",
		in:   []uint64{1, 2},
		out: &query.BindVariable{
			Type: sqltypes.Tuple,
			Values: []*query.Value{
				&query.Value{
					Type:  sqltypes.Uint64,
					Value: []byte("1"),
				},
				&query.Value{
					Type:  sqltypes.Uint64,
					Value: []byte("2"),
				},
			},
		},
	}}
	for _, tcase := range testcases {
		bv := map[string]interface{}{
			"bv": tcase.in,
		}
		p3, err := BindVariablesToProto3(bv)
		if err != nil {
			t.Errorf("Error on %v: %v", tcase.name, err)
		}
		if !reflect.DeepEqual(p3["bv"], tcase.out) {
			t.Errorf("Mismatch on %v: %+v, want %+v", tcase.name, p3["bv"], tcase.out)
		}
	}
}
Пример #10
0
func TestCompareRows(t *testing.T) {
	table := []struct {
		fields      []*querypb.Field
		left, right []sqltypes.Value
		want        int
	}{
		{
			fields: []*querypb.Field{{"a", sqltypes.Int32}},
			left:   []sqltypes.Value{sqltypes.MakeNumeric([]byte("123"))},
			right:  []sqltypes.Value{sqltypes.MakeNumeric([]byte("14"))},
			want:   1,
		},
		{
			fields: []*querypb.Field{
				{"a", sqltypes.Int32},
				{"b", sqltypes.Int32},
			},
			left: []sqltypes.Value{
				sqltypes.MakeNumeric([]byte("555")),
				sqltypes.MakeNumeric([]byte("12")),
			},
			right: []sqltypes.Value{
				sqltypes.MakeNumeric([]byte("555")),
				sqltypes.MakeNumeric([]byte("144")),
			},
			want: -1,
		},
		{
			fields: []*querypb.Field{{"a", sqltypes.Int32}},
			left:   []sqltypes.Value{sqltypes.MakeNumeric([]byte("144"))},
			right:  []sqltypes.Value{sqltypes.MakeNumeric([]byte("144"))},
			want:   0,
		},
		{
			fields: []*querypb.Field{{"a", sqltypes.Uint64}},
			left:   []sqltypes.Value{sqltypes.MakeNumeric([]byte("9223372036854775809"))},
			right:  []sqltypes.Value{sqltypes.MakeNumeric([]byte("9223372036854775810"))},
			want:   -1,
		},
		{
			fields: []*querypb.Field{{"a", sqltypes.Uint64}},
			left:   []sqltypes.Value{sqltypes.MakeNumeric([]byte("9223372036854775819"))},
			right:  []sqltypes.Value{sqltypes.MakeNumeric([]byte("9223372036854775810"))},
			want:   1,
		},
		{
			fields: []*querypb.Field{{"a", sqltypes.Float64}},
			left:   []sqltypes.Value{sqltypes.MakeFractional([]byte("3.14"))},
			right:  []sqltypes.Value{sqltypes.MakeFractional([]byte("3.2"))},
			want:   -1,
		},
		{
			fields: []*querypb.Field{{"a", sqltypes.Float64}},
			left:   []sqltypes.Value{sqltypes.MakeFractional([]byte("123.4"))},
			right:  []sqltypes.Value{sqltypes.MakeFractional([]byte("123.2"))},
			want:   1,
		},
		{
			fields: []*querypb.Field{{"a", sqltypes.Char}},
			left:   []sqltypes.Value{sqltypes.MakeString([]byte("abc"))},
			right:  []sqltypes.Value{sqltypes.MakeString([]byte("abb"))},
			want:   1,
		},
		{
			fields: []*querypb.Field{{"a", sqltypes.Char}},
			left:   []sqltypes.Value{sqltypes.MakeString([]byte("abc"))},
			right:  []sqltypes.Value{sqltypes.MakeString([]byte("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)
		}
	}
}
Пример #11
0
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.MakeNumeric([]byte("123"))},
			right:  []sqltypes.Value{sqltypes.MakeNumeric([]byte("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.MakeNumeric([]byte("555")),
				sqltypes.MakeNumeric([]byte("12")),
			},
			right: []sqltypes.Value{
				sqltypes.MakeNumeric([]byte("555")),
				sqltypes.MakeNumeric([]byte("144")),
			},
			want: -1,
		},
		{
			fields: []mproto.Field{{"a", mproto.VT_LONG, mproto.VT_ZEROVALUE_FLAG}},
			left:   []sqltypes.Value{sqltypes.MakeNumeric([]byte("144"))},
			right:  []sqltypes.Value{sqltypes.MakeNumeric([]byte("144"))},
			want:   0,
		},
		{
			fields: []mproto.Field{{"a", mproto.VT_LONGLONG, mproto.VT_UNSIGNED_FLAG}},
			left:   []sqltypes.Value{sqltypes.MakeNumeric([]byte("9223372036854775809"))},
			right:  []sqltypes.Value{sqltypes.MakeNumeric([]byte("9223372036854775810"))},
			want:   -1,
		},
		{
			fields: []mproto.Field{{"a", mproto.VT_LONGLONG, mproto.VT_UNSIGNED_FLAG}},
			left:   []sqltypes.Value{sqltypes.MakeNumeric([]byte("9223372036854775819"))},
			right:  []sqltypes.Value{sqltypes.MakeNumeric([]byte("9223372036854775810"))},
			want:   1,
		},
		{
			fields: []mproto.Field{{"a", mproto.VT_DOUBLE, mproto.VT_ZEROVALUE_FLAG}},
			left:   []sqltypes.Value{sqltypes.MakeFractional([]byte("3.14"))},
			right:  []sqltypes.Value{sqltypes.MakeFractional([]byte("3.2"))},
			want:   -1,
		},
		{
			fields: []mproto.Field{{"a", mproto.VT_DOUBLE, mproto.VT_ZEROVALUE_FLAG}},
			left:   []sqltypes.Value{sqltypes.MakeFractional([]byte("123.4"))},
			right:  []sqltypes.Value{sqltypes.MakeFractional([]byte("123.2"))},
			want:   1,
		},
		{
			fields: []mproto.Field{{"a", mproto.VT_STRING, mproto.VT_ZEROVALUE_FLAG}},
			left:   []sqltypes.Value{sqltypes.MakeString([]byte("abc"))},
			right:  []sqltypes.Value{sqltypes.MakeString([]byte("abb"))},
			want:   1,
		},
		{
			fields: []mproto.Field{{"a", mproto.VT_STRING, mproto.VT_ZEROVALUE_FLAG}},
			left:   []sqltypes.Value{sqltypes.MakeString([]byte("abc"))},
			right:  []sqltypes.Value{sqltypes.MakeString([]byte("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)
		}
	}
}
Пример #12
0
		encoded: "E\x00\x00\x00\x04Fields\x00\x05\x00\x00\x00\x00\x12RowsAffected\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12InsertId\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04Rows\x00\x05\x00\x00\x00\x00\x00",
	},
	// Only fields set
	{
		qr: QueryResult{
			Fields: []Field{
				{Name: "foo", Type: 1},
			},
		},
		encoded: "i\x00\x00\x00\x04Fields\x00)\x00\x00\x00\x030\x00!\x00\x00\x00\x05Name\x00\x03\x00\x00\x00\x00foo\x12Type\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12RowsAffected\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12InsertId\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04Rows\x00\x05\x00\x00\x00\x00\x00",
	},
	// Only rows, no fields
	{
		qr: QueryResult{
			Rows: [][]sqltypes.Value{
				{sqltypes.MakeString([]byte("abcd")), sqltypes.MakeNumeric([]byte("1234")), sqltypes.MakeFractional([]byte("1.234"))},
			},
		},
		encoded: "r\x00\x00\x00\x04Fields\x00\x05\x00\x00\x00\x00\x12RowsAffected\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12InsertId\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04Rows\x002\x00\x00\x00\x040\x00*\x00\x00\x00\x050\x00\x04\x00\x00\x00\x00abcd\x051\x00\x04\x00\x00\x00\x001234\x052\x00\x05\x00\x00\x00\x001.234\x00\x00\x00",
	},
	// one row and one field
	{
		qr: QueryResult{
			Fields: []Field{
				{Name: "foo", Type: 1},
			},
			Rows: [][]sqltypes.Value{
				{sqltypes.MakeString([]byte("abcd")), sqltypes.MakeNumeric([]byte("1234")), sqltypes.MakeFractional([]byte("1.234")), sqltypes.Value{}},
			},
		},
		encoded: "",
Пример #13
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])
		}
	}
}