Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gen4: Fast aggregations #13904

Merged
merged 8 commits into from
Sep 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions go/mysql/decimal/decimal.go
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,10 @@ func (d *Decimal) ensureInitialized() {
}
}

func (d Decimal) IsInitialized() bool {
return d.value != nil
}

// RescalePair rescales two decimals to common exponential value (minimal exp of both decimals)
func RescalePair(d1 Decimal, d2 Decimal) (Decimal, Decimal) {
d1.ensureInitialized()
Expand Down
127 changes: 127 additions & 0 deletions go/sqltypes/testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,14 @@ package sqltypes

import (
"bytes"
crand "crypto/rand"
"encoding/base64"
"encoding/hex"
"fmt"
"math/rand"
"strconv"
"strings"
"time"

querypb "vitess.io/vitess/go/vt/proto/query"
)
Expand Down Expand Up @@ -154,3 +160,124 @@ func PrintResults(results []*Result) string {
func split(str string) []string {
return strings.Split(str, "|")
}

func TestRandomValues() (Value, Value) {
if rand.Int()%2 == 0 {
// create a single value, and turn it into two different types
v := rand.Int()
return randomNumericType(v), randomNumericType(v)
}

// just produce two arbitrary random values and compare
return randomNumericType(rand.Int()), randomNumericType(rand.Int())
}

func randomNumericType(i int) Value {
r := rand.Intn(len(numericTypes))
return numericTypes[r](i)
}

var numericTypes = []func(int) Value{
func(i int) Value { return NULL },
func(i int) Value { return NewInt8(int8(i)) },
func(i int) Value { return NewInt32(int32(i)) },
func(i int) Value { return NewInt64(int64(i)) },
func(i int) Value { return NewUint64(uint64(i)) },
func(i int) Value { return NewUint32(uint32(i)) },
func(i int) Value { return NewFloat64(float64(i)) },
func(i int) Value { return NewDecimal(fmt.Sprintf("%d", i)) },
func(i int) Value { return NewVarChar(fmt.Sprintf("%d", i)) },
func(i int) Value { return NewVarChar(fmt.Sprintf(" %f aa", float64(i))) },
}

type RandomGenerator func() Value

func randomBytes() []byte {
b := make([]byte, rand.Intn(128))
_, _ = crand.Read(b)
return b
}

var RandomGenerators = map[Type]RandomGenerator{
Null: func() Value {
return NULL
},
Int8: func() Value {
return NewInt8(int8(rand.Intn(255)))
},
Int32: func() Value {
return NewInt32(rand.Int31())
},
Int64: func() Value {
return NewInt64(rand.Int63())
},
Uint32: func() Value {
return NewUint32(rand.Uint32())
},
Uint64: func() Value {
return NewUint64(rand.Uint64())
},
Float64: func() Value {
return NewFloat64(rand.ExpFloat64())
},
Decimal: func() Value {
dec := fmt.Sprintf("%d.%d", rand.Intn(9999999999), rand.Intn(9999999999))
if rand.Int()&0x1 == 1 {
dec = "-" + dec
}
return NewDecimal(dec)
},
VarChar: func() Value {
return NewVarChar(base64.StdEncoding.EncodeToString(randomBytes()))
},
VarBinary: func() Value {
return NewVarBinary(string(randomBytes()))
},
Date: func() Value {
return NewDate(randTime().Format(time.DateOnly))
},
Datetime: func() Value {
return NewDatetime(randTime().Format(time.DateTime))
},
Timestamp: func() Value {
return NewTimestamp(randTime().Format(time.DateTime))
},
Time: func() Value {
return NewTime(randTime().Format(time.TimeOnly))
},
TypeJSON: func() Value {
var j string
switch rand.Intn(6) {
case 0:
j = "null"
case 1:
i := rand.Int63()
if rand.Int()&0x1 == 1 {
i = -i
}
j = strconv.FormatInt(i, 10)
case 2:
j = strconv.FormatFloat(rand.NormFloat64(), 'g', -1, 64)
case 3:
j = strconv.Quote(hex.EncodeToString(randomBytes()))
case 4:
j = "true"
case 5:
j = "false"
}
v, err := NewJSON(j)
if err != nil {
panic(err)
}
return v
},
}

func randTime() time.Time {
min := time.Date(1970, 1, 0, 0, 0, 0, 0, time.UTC).Unix()
max := time.Date(2070, 1, 0, 0, 0, 0, 0, time.UTC).Unix()
delta := max - min

sec := rand.Int63n(delta) + min
return time.Unix(sec, 0)
}
5 changes: 3 additions & 2 deletions go/sqltypes/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"vitess.io/vitess/go/hack"
"vitess.io/vitess/go/mysql/decimal"
"vitess.io/vitess/go/mysql/fastparse"
"vitess.io/vitess/go/mysql/format"
querypb "vitess.io/vitess/go/vt/proto/query"
vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc"
"vitess.io/vitess/go/vt/vterrors"
Expand Down Expand Up @@ -186,12 +187,12 @@ func NewBoolean(v bool) Value {

// NewFloat64 builds an Float64 Value.
func NewFloat64(v float64) Value {
return MakeTrusted(Float64, strconv.AppendFloat(nil, v, 'g', -1, 64))
return MakeTrusted(Float64, format.FormatFloat(v))
}

// NewFloat32 builds a Float32 Value.
func NewFloat32(v float32) Value {
return MakeTrusted(Float32, strconv.AppendFloat(nil, float64(v), 'g', -1, 64))
return MakeTrusted(Float32, format.FormatFloat(float64(v)))
}

// NewVarChar builds a VarChar Value.
Expand Down
Loading