Skip to content

Commit

Permalink
expression: implement vectorized evaluation for builtinGetFormatSig (
Browse files Browse the repository at this point in the history
  • Loading branch information
b41sh authored and sre-bot committed Nov 11, 2019
1 parent b918b95 commit ea01910
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 45 deletions.
48 changes: 48 additions & 0 deletions expression/bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,54 @@ func (g *randDurInt) gen() interface{} {
return int64(rand.Intn(types.TimeMaxHour)*10000 + rand.Intn(60)*100 + rand.Intn(60))
}

// locationGener is used to generate location for the built-in function GetFormat.
type locationGener struct {
nullRation float64
}

func (g *locationGener) gen() interface{} {
if rand.Float64() < g.nullRation {
return nil
}
switch rand.Uint32() % 5 {
case 0:
return usaLocation
case 1:
return jisLocation
case 2:
return isoLocation
case 3:
return eurLocation
case 4:
return internalLocation
default:
return nil
}
}

// formatGener is used to generate a format for the built-in function GetFormat.
type formatGener struct {
nullRation float64
}

func (g *formatGener) gen() interface{} {
if rand.Float64() < g.nullRation {
return nil
}
switch rand.Uint32() % 4 {
case 0:
return dateFormat
case 1:
return datetimeFormat
case 2:
return timestampFormat
case 3:
return timeFormat
default:
return nil
}
}

type vecExprBenchCase struct {
// retEvalType is the EvalType of the expression result.
// This field is required.
Expand Down
44 changes: 1 addition & 43 deletions expression/builtin_time.go
Original file line number Diff line number Diff line change
Expand Up @@ -1747,49 +1747,7 @@ func (b *builtinGetFormatSig) evalString(row chunk.Row) (string, bool, error) {
return "", isNull, err
}

var res string
switch t {
case dateFormat:
switch l {
case usaLocation:
res = "%m.%d.%Y"
case jisLocation:
res = "%Y-%m-%d"
case isoLocation:
res = "%Y-%m-%d"
case eurLocation:
res = "%d.%m.%Y"
case internalLocation:
res = "%Y%m%d"
}
case datetimeFormat, timestampFormat:
switch l {
case usaLocation:
res = "%Y-%m-%d %H.%i.%s"
case jisLocation:
res = "%Y-%m-%d %H:%i:%s"
case isoLocation:
res = "%Y-%m-%d %H:%i:%s"
case eurLocation:
res = "%Y-%m-%d %H.%i.%s"
case internalLocation:
res = "%Y%m%d%H%i%s"
}
case timeFormat:
switch l {
case usaLocation:
res = "%h:%i:%s %p"
case jisLocation:
res = "%H:%i:%s"
case isoLocation:
res = "%H:%i:%s"
case eurLocation:
res = "%H.%i.%s"
case internalLocation:
res = "%H%i%s"
}
}

res := b.getFormat(t, l)
return res, false, nil
}

Expand Down
81 changes: 79 additions & 2 deletions expression/builtin_time_vec.go
Original file line number Diff line number Diff line change
Expand Up @@ -545,11 +545,88 @@ func (b *builtinNullTimeDiffSig) vecEvalDuration(input *chunk.Chunk, result *chu
}

func (b *builtinGetFormatSig) vectorized() bool {
return false
return true
}

// vecEvalString evals a builtinGetFormatSig.
// See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_get-format
func (b *builtinGetFormatSig) vecEvalString(input *chunk.Chunk, result *chunk.Column) error {
return errors.Errorf("not implemented")
n := input.NumRows()
buf0, err := b.bufAllocator.get(types.ETString, n)
if err != nil {
return err
}
defer b.bufAllocator.put(buf0)
if err = b.args[0].VecEvalString(b.ctx, input, buf0); err != nil {
return err
}
buf1, err := b.bufAllocator.get(types.ETString, n)
if err != nil {
return err
}
defer b.bufAllocator.put(buf1)
if err = b.args[1].VecEvalString(b.ctx, input, buf1); err != nil {
return err
}

result.ReserveString(n)
for i := 0; i < n; i++ {
if buf0.IsNull(i) || buf1.IsNull(i) {
result.AppendNull()
continue
}
format := buf0.GetString(i)
location := buf1.GetString(i)
res := b.getFormat(format, location)
result.AppendString(res)
}
return nil
}

func (b *builtinGetFormatSig) getFormat(format, location string) string {
res := ""
switch format {
case dateFormat:
switch location {
case usaLocation:
res = "%m.%d.%Y"
case jisLocation:
res = "%Y-%m-%d"
case isoLocation:
res = "%Y-%m-%d"
case eurLocation:
res = "%d.%m.%Y"
case internalLocation:
res = "%Y%m%d"
}
case datetimeFormat, timestampFormat:
switch location {
case usaLocation:
res = "%Y-%m-%d %H.%i.%s"
case jisLocation:
res = "%Y-%m-%d %H:%i:%s"
case isoLocation:
res = "%Y-%m-%d %H:%i:%s"
case eurLocation:
res = "%Y-%m-%d %H.%i.%s"
case internalLocation:
res = "%Y%m%d%H%i%s"
}
case timeFormat:
switch location {
case usaLocation:
res = "%h:%i:%s %p"
case jisLocation:
res = "%H:%i:%s"
case isoLocation:
res = "%H:%i:%s"
case eurLocation:
res = "%H.%i.%s"
case internalLocation:
res = "%H%i%s"
}
}
return res
}

func (b *builtinLastDaySig) vectorized() bool {
Expand Down
7 changes: 7 additions & 0 deletions expression/builtin_time_vec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,13 @@ var vecBuiltinTimeCases = map[string][]vecExprBenchCase{
geners: []dataGenerator{&timeStrGener{}, &constStrGener{"%y-%m-%d"}},
},
},
ast.GetFormat: {
{
retEvalType: types.ETString,
childrenTypes: []types.EvalType{types.ETString, types.ETString},
geners: []dataGenerator{&formatGener{0.2}, &locationGener{0.2}},
},
},
}

func (s *testEvaluatorSuite) TestVectorizedBuiltinTimeEvalOneVec(c *C) {
Expand Down

0 comments on commit ea01910

Please sign in to comment.