Skip to content

Commit

Permalink
tuple: serialized form
Browse files Browse the repository at this point in the history
Signed-off-by: Vicent Marti <[email protected]>
  • Loading branch information
vmg committed Oct 30, 2023
1 parent 54f2daf commit 21b1744
Show file tree
Hide file tree
Showing 10 changed files with 1,008 additions and 1,115 deletions.
15 changes: 9 additions & 6 deletions go/sqltypes/bind_variables.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,21 @@ var (
NullBindVariable = &querypb.BindVariable{Type: querypb.Type_NULL_TYPE}
)

func TupleToProto(v []Value) *querypb.Value {
return &querypb.Value{
Type: querypb.Type_TUPLE,
Value: encodeTuple(v),
}
}

// ValueToProto converts Value to a *querypb.Value.
func ValueToProto(v Value) *querypb.Value {
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}
return &querypb.Value{Type: v.typ, Value: v.val}
}

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

// BuildBindVariables builds a map[string]*querypb.BindVariable from a map[string]any
Expand Down
7 changes: 0 additions & 7 deletions go/sqltypes/cached_size.go

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

69 changes: 53 additions & 16 deletions go/sqltypes/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import (
"strconv"
"strings"

"google.golang.org/protobuf/encoding/protowire"

"vitess.io/vitess/go/bytes2"
"vitess.io/vitess/go/hack"
"vitess.io/vitess/go/mysql/decimal"
Expand Down Expand Up @@ -63,9 +65,8 @@ 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
values []Value
typ querypb.Type
val []byte
}

Row = []Value
Expand Down Expand Up @@ -110,19 +111,10 @@ 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
}
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}
return Value{typ: typ, val: val}
}

// NewHexNum builds an Hex Value.
Expand Down Expand Up @@ -454,12 +446,12 @@ func (v Value) EncodeSQLStringBuilder(b *strings.Builder) {
encodeBytesSQLBits(v.val, b)
case v.typ == Tuple:
b.WriteByte('(')
for i, bv := range v.values {
if i != 0 {
_ = v.ForEachValue(func(i int, bv Value) {
if i > 0 {
b.WriteString(", ")
}
bv.EncodeSQLStringBuilder(b)
}
})
b.WriteByte(')')
default:
b.Write(v.val)
Expand Down Expand Up @@ -658,6 +650,51 @@ func (v *Value) decodeBitNum() ([]byte, error) {
return i.Bytes(), nil
}

var ErrBadTupleEncoding = errors.New("bad tuple encoding in sqltypes.Value")

func encodeTuple(tuple []Value) []byte {
var total int
for _, v := range tuple {
total += len(v.val) + 3
}

buf := make([]byte, 0, total)
for _, v := range tuple {
buf = protowire.AppendVarint(buf, uint64(v.typ))
buf = protowire.AppendVarint(buf, uint64(len(v.val)))
buf = append(buf, v.val...)
}
return buf
}

func (v *Value) ForEachValue(each func(i int, bv Value)) error {
if v.typ != Tuple {
panic("Value.ForEachValue on non-tuple")
}

var sz, ty uint64
var varlen, i int
buf := v.val
for len(buf) > 0 {
ty, varlen = protowire.ConsumeVarint(buf)
if varlen < 0 {
return ErrBadTupleEncoding
}

buf = buf[varlen:]
sz, varlen = protowire.ConsumeVarint(buf)
if varlen < 0 {
return ErrBadTupleEncoding
}

buf = buf[varlen:]
each(i, Value{val: buf[:sz], typ: Type(ty)})

buf = buf[sz:]
}
return nil
}

func encodeBytesSQL(val []byte, b BinWriter) {
buf := &bytes2.Buffer{}
encodeBytesSQLBytes2(val, buf)
Expand Down
7 changes: 0 additions & 7 deletions go/vt/proto/query/cached_size.go

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

1,893 changes: 940 additions & 953 deletions go/vt/proto/query/query.pb.go

Large diffs are not rendered by default.

59 changes: 0 additions & 59 deletions go/vt/proto/query/query_vtproto.pb.go

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

20 changes: 6 additions & 14 deletions go/vt/vtgate/engine/fk_cascade.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,11 @@ func (fkc *FkCascade) TryExecute(ctx context.Context, vcursor VCursor, bindVars
Type: querypb.Type_TUPLE,
}
for _, row := range selectionRes.Rows {
// Create a tuple from each Row.
tuple := &querypb.Value{
Type: querypb.Type_TUPLE,
}
var tupleValues []sqltypes.Value
for _, colIdx := range child.Cols {
tuple.Values = append(tuple.Values,
sqltypes.ValueToProto(row[colIdx]))
tupleValues = append(tupleValues, row[colIdx])
}
bv.Values = append(bv.Values, tuple)
bv.Values = append(bv.Values, sqltypes.TupleToProto(tupleValues))
}
// Execute the child primitive, and bail out incase of failure.
// Since this Primitive is always executed in a transaction, the changes should
Expand Down Expand Up @@ -132,15 +128,11 @@ func (fkc *FkCascade) TryStreamExecute(ctx context.Context, vcursor VCursor, bin
}
for idx, child := range fkc.Children {
for _, row := range result.Rows {
// Create a tuple from each Row.
tuple := &querypb.Value{
Type: querypb.Type_TUPLE,
}
var tupleValues []sqltypes.Value
for _, colIdx := range child.Cols {
tuple.Values = append(tuple.Values,
sqltypes.ValueToProto(row[colIdx]))
tupleValues = append(tupleValues, row[colIdx])
}
bindVariables[idx].Values = append(bindVariables[idx].Values, tuple)
bindVariables[idx].Values = append(bindVariables[idx].Values, sqltypes.TupleToProto(tupleValues))
}
}
return nil
Expand Down
2 changes: 0 additions & 2 deletions proto/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,6 @@ enum Type {
message Value {
Type type = 1;
bytes value = 2;
// values are set if type is TUPLE.
repeated Value values = 3;
}

// BindVariable represents a single bind variable in a Query.
Expand Down
6 changes: 0 additions & 6 deletions web/vtadmin/src/proto/vtadmin.d.ts

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

Loading

0 comments on commit 21b1744

Please sign in to comment.