Skip to content

Commit

Permalink
gen4: Fast aggregations (#13904)
Browse files Browse the repository at this point in the history
Signed-off-by: Vicent Marti <vmg@strn.cat>
  • Loading branch information
vmg authored Sep 4, 2023
1 parent 3bdb574 commit 1126480
Show file tree
Hide file tree
Showing 17 changed files with 1,447 additions and 825 deletions.
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

0 comments on commit 1126480

Please sign in to comment.