Skip to content

Commit

Permalink
Add support for tuple as value type (#13800)
Browse files Browse the repository at this point in the history
Signed-off-by: Harshit Gangal <harshit@planetscale.com>
Signed-off-by: Manan Gupta <manan@planetscale.com>
Co-authored-by: Manan Gupta <manan@planetscale.com>
  • Loading branch information
harshit-gangal and GuptaManan100 authored Aug 18, 2023
1 parent e84a2db commit e0c1bf3
Show file tree
Hide file tree
Showing 12 changed files with 1,247 additions and 959 deletions.
8 changes: 6 additions & 2 deletions go/sqltypes/bind_variables.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,16 @@ var (

// ValueToProto converts Value to a *querypb.Value.
func ValueToProto(v Value) *querypb.Value {
return &querypb.Value{Type: v.typ, Value: v.val}
var protoValues []*querypb.Value
for _, value := range v.values {
protoValues = append(protoValues, ValueToProto(value))
}
return &querypb.Value{Type: v.typ, Value: v.val, Values: protoValues}
}

// ProtoToValue converts a *querypb.Value to a Value.
func ProtoToValue(v *querypb.Value) Value {
return MakeTrusted(v.Type, v.Value)
return MakeTrustedValues(v.Type, v.Value, v.Values)
}

// BuildBindVariables builds a map[string]*querypb.BindVariable from a map[string]any
Expand Down
84 changes: 75 additions & 9 deletions go/sqltypes/bind_variables_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package sqltypes

import (
"fmt"
"reflect"
"strings"
"testing"

Expand All @@ -30,16 +29,83 @@ import (
querypb "vitess.io/vitess/go/vt/proto/query"
)

// TestProtoConversions checks coverting to and fro between querypb.Value and sqltypes.Value.
func TestProtoConversions(t *testing.T) {
v := TestValue(Int64, "1")
got := ValueToProto(v)
want := &querypb.Value{Type: Int64, Value: []byte("1")}
if !proto.Equal(got, want) {
t.Errorf("ValueToProto: %v, want %v", got, want)
tcases := []struct {
name string
val Value
protoVal *querypb.Value
}{
{
name: "integer value",
val: TestValue(Int64, "1"),
protoVal: &querypb.Value{Type: Int64, Value: []byte("1")},
}, {
name: "tuple value",
val: Value{
typ: Tuple,
values: []Value{
TestValue(VarChar, "1"),
TestValue(Int64, "3"),
},
},
protoVal: &querypb.Value{
Type: Tuple,
Values: []*querypb.Value{
{
Type: VarChar,
Value: []byte("1"),
}, {
Type: Int64,
Value: []byte("3"),
},
},
},
}, {
name: "tuple of tuple as a value",
val: Value{
typ: Tuple,
values: []Value{
{
typ: Tuple,
values: []Value{
TestValue(VarChar, "1"),
TestValue(Int64, "3"),
},
},
TestValue(Int64, "5"),
},
},
protoVal: &querypb.Value{
Type: Tuple,
Values: []*querypb.Value{
{
Type: Tuple,
Values: []*querypb.Value{
{
Type: VarChar,
Value: []byte("1"),
}, {
Type: Int64,
Value: []byte("3"),
},
},
}, {
Type: Int64,
Value: []byte("5"),
},
},
},
},
}
gotback := ProtoToValue(got)
if !reflect.DeepEqual(gotback, v) {
t.Errorf("ProtoToValue: %v, want %v", gotback, v)

for _, tcase := range tcases {
t.Run(tcase.name, func(t *testing.T) {
got := ValueToProto(tcase.val)
require.True(t, proto.Equal(got, tcase.protoVal), "ValueToProto: %v, want %v", got, tcase.protoVal)
gotback := ProtoToValue(got)
require.EqualValues(t, tcase.val, gotback)
})
}
}

Expand Down
11 changes: 9 additions & 2 deletions go/sqltypes/cached_size.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 21 additions & 4 deletions go/sqltypes/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,9 @@ type (
// an integral type, the bytes are always stored as a canonical
// representation that matches how MySQL returns such values.
Value struct {
typ querypb.Type
val []byte
typ querypb.Type
val []byte
values []Value
}

Row = []Value
Expand Down Expand Up @@ -109,12 +110,19 @@ func NewValue(typ querypb.Type, val []byte) (v Value, err error) {
// comments. Other packages can also use the function to create
// VarBinary or VarChar values.
func MakeTrusted(typ querypb.Type, val []byte) Value {
return MakeTrustedValues(typ, val, nil)
}

func MakeTrustedValues(typ querypb.Type, val []byte, values []*querypb.Value) Value {
if typ == Null {
return NULL
}

return Value{typ: typ, val: val}
var sqlValues []Value
for _, v := range values {
sqlValues = append(sqlValues,
MakeTrustedValues(v.Type, v.Value, v.Values))
}
return Value{typ: typ, val: val, values: sqlValues}
}

// NewHexNum builds an Hex Value.
Expand Down Expand Up @@ -419,6 +427,15 @@ func (v Value) EncodeSQLStringBuilder(b *strings.Builder) {
encodeBytesSQLStringBuilder(v.val, b)
case v.typ == Bit:
encodeBytesSQLBits(v.val, b)
case v.typ == Tuple:
b.WriteByte('(')
for i, bv := range v.values {
if i != 0 {
b.WriteString(", ")
}
bv.EncodeSQLStringBuilder(b)
}
b.WriteByte(')')
default:
b.Write(v.val)
}
Expand Down
9 changes: 8 additions & 1 deletion go/vt/proto/query/cached_size.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit e0c1bf3

Please sign in to comment.