diff --git a/expression/builtin_compare_vec.go b/expression/builtin_compare_vec.go index 884526d62613d..bd20496d9b27d 100644 --- a/expression/builtin_compare_vec.go +++ b/expression/builtin_compare_vec.go @@ -163,6 +163,14 @@ func (b *builtinGreatestIntSig) vectorized() bool { return true } +func (b *builtinGEIntSig) vectorized() bool { + return false +} + +func (b *builtinGEIntSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error { + return errors.Errorf("not implemented") +} + func (b *builtinLeastRealSig) vectorized() bool { return true } @@ -250,6 +258,86 @@ func (b *builtinLeastStringSig) vecEvalString(input *chunk.Chunk, result *chunk. return nil } +func (b *builtinEQIntSig) vectorized() bool { + return true +} + +func (b *builtinEQIntSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error { + n := input.NumRows() + var err error + var buf0, buf1 *chunk.Column + buf0, err = b.bufAllocator.get(types.ETInt, n) + if err != nil { + return err + } + defer b.bufAllocator.put(buf0) + if err := b.args[0].VecEvalInt(b.ctx, input, buf0); err != nil { + return err + } + buf1, err = b.bufAllocator.get(types.ETInt, n) + if err != nil { + return err + } + defer b.bufAllocator.put(buf1) + if err := b.args[1].VecEvalInt(b.ctx, input, buf1); err != nil { + return err + } + + result.ResizeInt64(n, false) + vecCompareInt(mysql.HasUnsignedFlag(b.args[0].GetType().Flag), mysql.HasUnsignedFlag(b.args[1].GetType().Flag), buf0, buf1, result) + result.MergeNulls(buf0, buf1) + vecResOfEQ(result.Int64s()) + return nil +} + +func (b *builtinNEIntSig) vectorized() bool { + return false +} + +func (b *builtinNEIntSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error { + return errors.Errorf("not implemented") +} + +func (b *builtinGTIntSig) vectorized() bool { + return true +} + +func (b *builtinGTIntSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error { + n := input.NumRows() + var err error + var buf0, buf1 *chunk.Column + buf0, err = b.bufAllocator.get(types.ETInt, n) + if err != nil { + return err + } + defer b.bufAllocator.put(buf0) + if err := b.args[0].VecEvalInt(b.ctx, input, buf0); err != nil { + return err + } + buf1, err = b.bufAllocator.get(types.ETInt, n) + if err != nil { + return err + } + defer b.bufAllocator.put(buf1) + if err := b.args[1].VecEvalInt(b.ctx, input, buf1); err != nil { + return err + } + + result.ResizeInt64(n, false) + vecCompareInt(mysql.HasUnsignedFlag(b.args[0].GetType().Flag), mysql.HasUnsignedFlag(b.args[1].GetType().Flag), buf0, buf1, result) + result.MergeNulls(buf0, buf1) + vecResOfGT(result.Int64s()) + return nil +} + +func (b *builtinNullEQIntSig) vectorized() bool { + return false +} + +func (b *builtinNullEQIntSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error { + return errors.Errorf("not implemented") +} + func (b *builtinIntervalIntSig) vectorized() bool { return true } @@ -309,6 +397,70 @@ func (b *builtinIntervalRealSig) vecEvalInt(input *chunk.Chunk, result *chunk.Co return nil } +func (b *builtinLEIntSig) vectorized() bool { + return true +} + +func (b *builtinLEIntSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error { + n := input.NumRows() + var err error + var buf0, buf1 *chunk.Column + buf0, err = b.bufAllocator.get(types.ETInt, n) + if err != nil { + return err + } + defer b.bufAllocator.put(buf0) + if err := b.args[0].VecEvalInt(b.ctx, input, buf0); err != nil { + return err + } + buf1, err = b.bufAllocator.get(types.ETInt, n) + if err != nil { + return err + } + defer b.bufAllocator.put(buf1) + if err := b.args[1].VecEvalInt(b.ctx, input, buf1); err != nil { + return err + } + + result.ResizeInt64(n, false) + vecCompareInt(mysql.HasUnsignedFlag(b.args[0].GetType().Flag), mysql.HasUnsignedFlag(b.args[1].GetType().Flag), buf0, buf1, result) + result.MergeNulls(buf0, buf1) + vecResOfLE(result.Int64s()) + return nil +} + +func (b *builtinLTIntSig) vectorized() bool { + return true +} + +func (b *builtinLTIntSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error { + n := input.NumRows() + var err error + var buf0, buf1 *chunk.Column + buf0, err = b.bufAllocator.get(types.ETInt, n) + if err != nil { + return err + } + defer b.bufAllocator.put(buf0) + if err := b.args[0].VecEvalInt(b.ctx, input, buf0); err != nil { + return err + } + buf1, err = b.bufAllocator.get(types.ETInt, n) + if err != nil { + return err + } + defer b.bufAllocator.put(buf1) + if err := b.args[1].VecEvalInt(b.ctx, input, buf1); err != nil { + return err + } + + result.ResizeInt64(n, false) + vecCompareInt(mysql.HasUnsignedFlag(b.args[0].GetType().Flag), mysql.HasUnsignedFlag(b.args[1].GetType().Flag), buf0, buf1, result) + result.MergeNulls(buf0, buf1) + vecResOfLT(result.Int64s()) + return nil +} + func vecResOfLT(res []int64) { n := len(res) for i := 0; i < n; i++ { diff --git a/expression/builtin_compare_vec_generated.go b/expression/builtin_compare_vec_generated.go index e257258fc0800..b87562858d4ac 100644 --- a/expression/builtin_compare_vec_generated.go +++ b/expression/builtin_compare_vec_generated.go @@ -21,51 +21,6 @@ import ( "github.com/pingcap/tidb/util/chunk" ) -func (b *builtinLTIntSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error { - n := input.NumRows() - buf0, err := b.bufAllocator.get(types.ETInt, n) - if err != nil { - return err - } - defer b.bufAllocator.put(buf0) - if err := b.args[0].VecEvalInt(b.ctx, input, buf0); err != nil { - return err - } - buf1, err := b.bufAllocator.get(types.ETInt, n) - if err != nil { - return err - } - defer b.bufAllocator.put(buf1) - if err := b.args[1].VecEvalInt(b.ctx, input, buf1); err != nil { - return err - } - - arg0 := buf0.Int64s() - arg1 := buf1.Int64s() - - result.ResizeInt64(n, false) - result.MergeNulls(buf0, buf1) - i64s := result.Int64s() - for i := 0; i < n; i++ { - if result.IsNull(i) { - continue - } - - val := types.CompareInt64(arg0[i], arg1[i]) - - if val < 0 { - i64s[i] = 1 - } else { - i64s[i] = 0 - } - } - return nil -} - -func (b *builtinLTIntSig) vectorized() bool { - return true -} - func (b *builtinLTRealSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error { n := input.NumRows() buf0, err := b.bufAllocator.get(types.ETReal, n) @@ -314,51 +269,6 @@ func (b *builtinLTJSONSig) vectorized() bool { return true } -func (b *builtinLEIntSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error { - n := input.NumRows() - buf0, err := b.bufAllocator.get(types.ETInt, n) - if err != nil { - return err - } - defer b.bufAllocator.put(buf0) - if err := b.args[0].VecEvalInt(b.ctx, input, buf0); err != nil { - return err - } - buf1, err := b.bufAllocator.get(types.ETInt, n) - if err != nil { - return err - } - defer b.bufAllocator.put(buf1) - if err := b.args[1].VecEvalInt(b.ctx, input, buf1); err != nil { - return err - } - - arg0 := buf0.Int64s() - arg1 := buf1.Int64s() - - result.ResizeInt64(n, false) - result.MergeNulls(buf0, buf1) - i64s := result.Int64s() - for i := 0; i < n; i++ { - if result.IsNull(i) { - continue - } - - val := types.CompareInt64(arg0[i], arg1[i]) - - if val <= 0 { - i64s[i] = 1 - } else { - i64s[i] = 0 - } - } - return nil -} - -func (b *builtinLEIntSig) vectorized() bool { - return true -} - func (b *builtinLERealSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error { n := input.NumRows() buf0, err := b.bufAllocator.get(types.ETReal, n) @@ -607,51 +517,6 @@ func (b *builtinLEJSONSig) vectorized() bool { return true } -func (b *builtinGTIntSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error { - n := input.NumRows() - buf0, err := b.bufAllocator.get(types.ETInt, n) - if err != nil { - return err - } - defer b.bufAllocator.put(buf0) - if err := b.args[0].VecEvalInt(b.ctx, input, buf0); err != nil { - return err - } - buf1, err := b.bufAllocator.get(types.ETInt, n) - if err != nil { - return err - } - defer b.bufAllocator.put(buf1) - if err := b.args[1].VecEvalInt(b.ctx, input, buf1); err != nil { - return err - } - - arg0 := buf0.Int64s() - arg1 := buf1.Int64s() - - result.ResizeInt64(n, false) - result.MergeNulls(buf0, buf1) - i64s := result.Int64s() - for i := 0; i < n; i++ { - if result.IsNull(i) { - continue - } - - val := types.CompareInt64(arg0[i], arg1[i]) - - if val > 0 { - i64s[i] = 1 - } else { - i64s[i] = 0 - } - } - return nil -} - -func (b *builtinGTIntSig) vectorized() bool { - return true -} - func (b *builtinGTRealSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error { n := input.NumRows() buf0, err := b.bufAllocator.get(types.ETReal, n) @@ -900,51 +765,6 @@ func (b *builtinGTJSONSig) vectorized() bool { return true } -func (b *builtinGEIntSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error { - n := input.NumRows() - buf0, err := b.bufAllocator.get(types.ETInt, n) - if err != nil { - return err - } - defer b.bufAllocator.put(buf0) - if err := b.args[0].VecEvalInt(b.ctx, input, buf0); err != nil { - return err - } - buf1, err := b.bufAllocator.get(types.ETInt, n) - if err != nil { - return err - } - defer b.bufAllocator.put(buf1) - if err := b.args[1].VecEvalInt(b.ctx, input, buf1); err != nil { - return err - } - - arg0 := buf0.Int64s() - arg1 := buf1.Int64s() - - result.ResizeInt64(n, false) - result.MergeNulls(buf0, buf1) - i64s := result.Int64s() - for i := 0; i < n; i++ { - if result.IsNull(i) { - continue - } - - val := types.CompareInt64(arg0[i], arg1[i]) - - if val >= 0 { - i64s[i] = 1 - } else { - i64s[i] = 0 - } - } - return nil -} - -func (b *builtinGEIntSig) vectorized() bool { - return true -} - func (b *builtinGERealSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error { n := input.NumRows() buf0, err := b.bufAllocator.get(types.ETReal, n) @@ -1193,51 +1013,6 @@ func (b *builtinGEJSONSig) vectorized() bool { return true } -func (b *builtinEQIntSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error { - n := input.NumRows() - buf0, err := b.bufAllocator.get(types.ETInt, n) - if err != nil { - return err - } - defer b.bufAllocator.put(buf0) - if err := b.args[0].VecEvalInt(b.ctx, input, buf0); err != nil { - return err - } - buf1, err := b.bufAllocator.get(types.ETInt, n) - if err != nil { - return err - } - defer b.bufAllocator.put(buf1) - if err := b.args[1].VecEvalInt(b.ctx, input, buf1); err != nil { - return err - } - - arg0 := buf0.Int64s() - arg1 := buf1.Int64s() - - result.ResizeInt64(n, false) - result.MergeNulls(buf0, buf1) - i64s := result.Int64s() - for i := 0; i < n; i++ { - if result.IsNull(i) { - continue - } - - val := types.CompareInt64(arg0[i], arg1[i]) - - if val == 0 { - i64s[i] = 1 - } else { - i64s[i] = 0 - } - } - return nil -} - -func (b *builtinEQIntSig) vectorized() bool { - return true -} - func (b *builtinEQRealSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error { n := input.NumRows() buf0, err := b.bufAllocator.get(types.ETReal, n) @@ -1486,51 +1261,6 @@ func (b *builtinEQJSONSig) vectorized() bool { return true } -func (b *builtinNEIntSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error { - n := input.NumRows() - buf0, err := b.bufAllocator.get(types.ETInt, n) - if err != nil { - return err - } - defer b.bufAllocator.put(buf0) - if err := b.args[0].VecEvalInt(b.ctx, input, buf0); err != nil { - return err - } - buf1, err := b.bufAllocator.get(types.ETInt, n) - if err != nil { - return err - } - defer b.bufAllocator.put(buf1) - if err := b.args[1].VecEvalInt(b.ctx, input, buf1); err != nil { - return err - } - - arg0 := buf0.Int64s() - arg1 := buf1.Int64s() - - result.ResizeInt64(n, false) - result.MergeNulls(buf0, buf1) - i64s := result.Int64s() - for i := 0; i < n; i++ { - if result.IsNull(i) { - continue - } - - val := types.CompareInt64(arg0[i], arg1[i]) - - if val != 0 { - i64s[i] = 1 - } else { - i64s[i] = 0 - } - } - return nil -} - -func (b *builtinNEIntSig) vectorized() bool { - return true -} - func (b *builtinNERealSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error { n := input.NumRows() buf0, err := b.bufAllocator.get(types.ETReal, n) @@ -1779,51 +1509,6 @@ func (b *builtinNEJSONSig) vectorized() bool { return true } -func (b *builtinNullEQIntSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error { - n := input.NumRows() - buf0, err := b.bufAllocator.get(types.ETInt, n) - if err != nil { - return err - } - defer b.bufAllocator.put(buf0) - if err := b.args[0].VecEvalInt(b.ctx, input, buf0); err != nil { - return err - } - buf1, err := b.bufAllocator.get(types.ETInt, n) - if err != nil { - return err - } - defer b.bufAllocator.put(buf1) - if err := b.args[1].VecEvalInt(b.ctx, input, buf1); err != nil { - return err - } - - arg0 := buf0.Int64s() - arg1 := buf1.Int64s() - - result.ResizeInt64(n, false) - i64s := result.Int64s() - for i := 0; i < n; i++ { - isNull0 := buf0.IsNull(i) - isNull1 := buf1.IsNull(i) - switch { - case isNull0 && isNull1: - i64s[i] = 1 - case isNull0 != isNull1: - i64s[i] = 0 - - case types.CompareInt64(arg0[i], arg1[i]) == 0: - - i64s[i] = 1 - } - } - return nil -} - -func (b *builtinNullEQIntSig) vectorized() bool { - return true -} - func (b *builtinNullEQRealSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error { n := input.NumRows() buf0, err := b.bufAllocator.get(types.ETReal, n) @@ -2072,61 +1757,71 @@ func (b *builtinNullEQJSONSig) vectorized() bool { return true } -func (b *builtinCoalesceIntSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error { +func (b *builtinCoalesceRealSig) vecEvalReal(input *chunk.Chunk, result *chunk.Column) error { n := input.NumRows() - result.ResizeInt64(n, true) - i64s := result.Int64s() - buf1, err := b.bufAllocator.get(types.ETInt, n) + result.ResizeFloat64(n, true) + i64s := result.Float64s() + buf1, err := b.bufAllocator.get(types.ETReal, n) if err != nil { return err } defer b.bufAllocator.put(buf1) for j := 0; j < len(b.args); j++ { - if err := b.args[j].VecEvalInt(b.ctx, input, buf1); err != nil { + if err := b.args[j].VecEvalReal(b.ctx, input, buf1); err != nil { return err } - args := buf1.Int64s() + args := buf1.Float64s() for i := 0; i < n; i++ { if !buf1.IsNull(i) && result.IsNull(i) { i64s[i] = args[i] - result.SetNull(i, false) + result.SetNull(i, buf1.IsNull(i)) + continue } + if !result.IsNull(i) { + continue + } + result.SetNull(i, true) } } return nil } -func (b *builtinCoalesceIntSig) vectorized() bool { +func (b *builtinCoalesceRealSig) vectorized() bool { return true } -func (b *builtinCoalesceRealSig) vecEvalReal(input *chunk.Chunk, result *chunk.Column) error { +func (b *builtinCoalesceIntSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error { n := input.NumRows() - result.ResizeFloat64(n, true) - i64s := result.Float64s() - buf1, err := b.bufAllocator.get(types.ETReal, n) + result.ResizeInt64(n, true) + i64s := result.Int64s() + buf1, err := b.bufAllocator.get(types.ETInt, n) if err != nil { return err } defer b.bufAllocator.put(buf1) for j := 0; j < len(b.args); j++ { - if err := b.args[j].VecEvalReal(b.ctx, input, buf1); err != nil { + if err := b.args[j].VecEvalInt(b.ctx, input, buf1); err != nil { return err } - args := buf1.Float64s() + args := buf1.Int64s() for i := 0; i < n; i++ { if !buf1.IsNull(i) && result.IsNull(i) { i64s[i] = args[i] - result.SetNull(i, false) + result.SetNull(i, buf1.IsNull(i)) + continue } + if !result.IsNull(i) { + continue + } + result.SetNull(i, true) } } return nil } -func (b *builtinCoalesceRealSig) vectorized() bool { +func (b *builtinCoalesceIntSig) vectorized() bool { return true } @@ -2148,8 +1843,13 @@ func (b *builtinCoalesceDecimalSig) vecEvalDecimal(input *chunk.Chunk, result *c for i := 0; i < n; i++ { if !buf1.IsNull(i) && result.IsNull(i) { i64s[i] = args[i] - result.SetNull(i, false) + result.SetNull(i, buf1.IsNull(i)) + continue } + if !result.IsNull(i) { + continue + } + result.SetNull(i, true) } } return nil @@ -2161,31 +1861,42 @@ func (b *builtinCoalesceDecimalSig) vectorized() bool { func (b *builtinCoalesceStringSig) vecEvalString(input *chunk.Chunk, result *chunk.Column) error { n := input.NumRows() - argLen := len(b.args) - bufs := make([]*chunk.Column, argLen) + result.ReserveString(n) + + buf1, err := b.bufAllocator.get(types.ETString, n) + if err != nil { + return err + } + defer b.bufAllocator.put(buf1) + + buf2, err := b.bufAllocator.get(types.ETString, n) + if err != nil { + return err + } + defer b.bufAllocator.put(buf2) - for i := 0; i < argLen; i++ { - buf, err := b.bufAllocator.get(types.ETInt, n) - if err != nil { + buf2.ReserveString(len(b.args) * n) + for j := 0; j < len(b.args); j++ { + if err := b.args[j].VecEvalString(b.ctx, input, buf1); err != nil { return err } - defer b.bufAllocator.put(buf) - err = b.args[i].VecEvalString(b.ctx, input, buf) - if err != nil { - return err + for i := 0; i < n; i++ { + if buf1.IsNull(i) { + buf2.AppendNull() + continue + } + buf2.AppendString(buf1.GetString(i)) } - bufs[i] = buf } - result.ReserveString(n) - for i := 0; i < n; i++ { - for j := 0; j < argLen; j++ { - if !bufs[j].IsNull(i) { - result.AppendString(bufs[j].GetString(i)) + for j := 0; j < len(b.args); j++ { + index := i + j*n + if !buf2.IsNull(index) { + result.AppendString(buf2.GetString(index)) break } - if j == argLen-1 && bufs[j].IsNull(i) { + if j == len(b.args)-1 && buf2.IsNull(index) { result.AppendNull() } } @@ -2215,8 +1926,13 @@ func (b *builtinCoalesceTimeSig) vecEvalTime(input *chunk.Chunk, result *chunk.C for i := 0; i < n; i++ { if !buf1.IsNull(i) && result.IsNull(i) { i64s[i] = args[i] - result.SetNull(i, false) + result.SetNull(i, buf1.IsNull(i)) + continue + } + if !result.IsNull(i) { + continue } + result.SetNull(i, true) } } return nil @@ -2244,8 +1960,13 @@ func (b *builtinCoalesceDurationSig) vecEvalDuration(input *chunk.Chunk, result for i := 0; i < n; i++ { if !buf1.IsNull(i) && result.IsNull(i) { i64s[i] = args[i] - result.SetNull(i, false) + result.SetNull(i, buf1.IsNull(i)) + continue + } + if !result.IsNull(i) { + continue } + result.SetNull(i, true) } } return nil @@ -2257,31 +1978,42 @@ func (b *builtinCoalesceDurationSig) vectorized() bool { func (b *builtinCoalesceJSONSig) vecEvalJSON(input *chunk.Chunk, result *chunk.Column) error { n := input.NumRows() - argLen := len(b.args) - bufs := make([]*chunk.Column, argLen) + result.ReserveJSON(n) + + buf1, err := b.bufAllocator.get(types.ETJson, n) + if err != nil { + return err + } + defer b.bufAllocator.put(buf1) + + buf2, err := b.bufAllocator.get(types.ETJson, n) + if err != nil { + return err + } + defer b.bufAllocator.put(buf2) - for i := 0; i < argLen; i++ { - buf, err := b.bufAllocator.get(types.ETInt, n) - if err != nil { + buf2.ReserveJSON(len(b.args) * n) + for j := 0; j < len(b.args); j++ { + if err := b.args[j].VecEvalJSON(b.ctx, input, buf1); err != nil { return err } - defer b.bufAllocator.put(buf) - err = b.args[i].VecEvalJSON(b.ctx, input, buf) - if err != nil { - return err + for i := 0; i < n; i++ { + if buf1.IsNull(i) { + buf2.AppendNull() + continue + } + buf2.AppendJSON(buf1.GetJSON(i)) } - bufs[i] = buf } - result.ReserveJSON(n) - for i := 0; i < n; i++ { - for j := 0; j < argLen; j++ { - if !bufs[j].IsNull(i) { - result.AppendJSON(bufs[j].GetJSON(i)) + for j := 0; j < len(b.args); j++ { + index := i + j*n + if !buf2.IsNull(index) { + result.AppendJSON(buf2.GetJSON(index)) break } - if j == argLen-1 && bufs[j].IsNull(i) { + if j == len(b.args)-1 && buf2.IsNull(index) { result.AppendNull() } } diff --git a/expression/builtin_compare_vec_generated_test.go b/expression/builtin_compare_vec_generated_test.go index 2a8aafd749000..a30a5fd603dc3 100644 --- a/expression/builtin_compare_vec_generated_test.go +++ b/expression/builtin_compare_vec_generated_test.go @@ -25,7 +25,6 @@ import ( var vecGeneratedBuiltinCompareCases = map[string][]vecExprBenchCase{ ast.LT: { - {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETInt, types.ETInt}}, {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETReal, types.ETReal}}, {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETDecimal, types.ETDecimal}}, {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETString, types.ETString}}, @@ -34,7 +33,6 @@ var vecGeneratedBuiltinCompareCases = map[string][]vecExprBenchCase{ {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETJson, types.ETJson}}, }, ast.LE: { - {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETInt, types.ETInt}}, {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETReal, types.ETReal}}, {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETDecimal, types.ETDecimal}}, {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETString, types.ETString}}, @@ -43,7 +41,6 @@ var vecGeneratedBuiltinCompareCases = map[string][]vecExprBenchCase{ {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETJson, types.ETJson}}, }, ast.GT: { - {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETInt, types.ETInt}}, {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETReal, types.ETReal}}, {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETDecimal, types.ETDecimal}}, {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETString, types.ETString}}, @@ -52,7 +49,6 @@ var vecGeneratedBuiltinCompareCases = map[string][]vecExprBenchCase{ {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETJson, types.ETJson}}, }, ast.GE: { - {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETInt, types.ETInt}}, {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETReal, types.ETReal}}, {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETDecimal, types.ETDecimal}}, {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETString, types.ETString}}, @@ -61,7 +57,6 @@ var vecGeneratedBuiltinCompareCases = map[string][]vecExprBenchCase{ {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETJson, types.ETJson}}, }, ast.EQ: { - {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETInt, types.ETInt}}, {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETReal, types.ETReal}}, {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETDecimal, types.ETDecimal}}, {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETString, types.ETString}}, @@ -70,7 +65,6 @@ var vecGeneratedBuiltinCompareCases = map[string][]vecExprBenchCase{ {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETJson, types.ETJson}}, }, ast.NE: { - {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETInt, types.ETInt}}, {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETReal, types.ETReal}}, {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETDecimal, types.ETDecimal}}, {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETString, types.ETString}}, @@ -79,7 +73,6 @@ var vecGeneratedBuiltinCompareCases = map[string][]vecExprBenchCase{ {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETJson, types.ETJson}}, }, ast.NullEQ: { - {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETInt, types.ETInt}}, {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETReal, types.ETReal}}, {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETDecimal, types.ETDecimal}}, {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETString, types.ETString}}, @@ -89,16 +82,6 @@ var vecGeneratedBuiltinCompareCases = map[string][]vecExprBenchCase{ }, ast.Coalesce: { - { - retEvalType: types.ETInt, - childrenTypes: []types.EvalType{types.ETInt, types.ETInt, types.ETInt}, - geners: []dataGenerator{ - gener{defaultGener{eType: types.ETInt, nullRation: 0.2}}, - gener{defaultGener{eType: types.ETInt, nullRation: 0.2}}, - gener{defaultGener{eType: types.ETInt, nullRation: 0.2}}, - }, - }, - { retEvalType: types.ETReal, childrenTypes: []types.EvalType{types.ETReal, types.ETReal, types.ETReal}, @@ -158,6 +141,16 @@ var vecGeneratedBuiltinCompareCases = map[string][]vecExprBenchCase{ gener{defaultGener{eType: types.ETJson, nullRation: 0.2}}, }, }, + + { + retEvalType: types.ETInt, + childrenTypes: []types.EvalType{types.ETInt, types.ETInt, types.ETInt}, + geners: []dataGenerator{ + gener{defaultGener{eType: types.ETInt, nullRation: 0.2}}, + gener{defaultGener{eType: types.ETInt, nullRation: 0.2}}, + gener{defaultGener{eType: types.ETInt, nullRation: 0.2}}, + }, + }, }, } diff --git a/expression/builtin_compare_vec_test.go b/expression/builtin_compare_vec_test.go index 3f46d362a7f5e..8bc6af5c68339 100644 --- a/expression/builtin_compare_vec_test.go +++ b/expression/builtin_compare_vec_test.go @@ -18,20 +18,72 @@ import ( . "github.com/pingcap/check" "github.com/pingcap/parser/ast" + "github.com/pingcap/parser/mysql" "github.com/pingcap/tidb/types" ) var vecBuiltinCompareCases = map[string][]vecExprBenchCase{ - ast.NE: {}, - ast.IsNull: {}, - ast.LE: {}, - ast.LT: {}, + ast.NE: {}, + ast.IsNull: {}, + ast.LE: { + {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETInt, types.ETInt}}, + {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETInt, types.ETInt}, + childrenFieldTypes: []*types.FieldType{{Tp: mysql.TypeLonglong, Flag: mysql.UnsignedFlag}, + {Tp: mysql.TypeLonglong, Flag: mysql.UnsignedFlag}, + }, + }, + {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETInt, types.ETInt}, + childrenFieldTypes: []*types.FieldType{{Tp: mysql.TypeLonglong}, + {Tp: mysql.TypeLonglong, Flag: mysql.UnsignedFlag}, + }, + }, + {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETInt, types.ETInt}, + childrenFieldTypes: []*types.FieldType{{Tp: mysql.TypeLonglong, Flag: mysql.UnsignedFlag}, + {Tp: mysql.TypeLonglong}, + }, + }, + }, + ast.LT: { + {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETInt, types.ETInt}}, + {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETInt, types.ETInt}, + childrenFieldTypes: []*types.FieldType{{Tp: mysql.TypeLonglong, Flag: mysql.UnsignedFlag}, + {Tp: mysql.TypeLonglong, Flag: mysql.UnsignedFlag}, + }, + }, + {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETInt, types.ETInt}, + childrenFieldTypes: []*types.FieldType{{Tp: mysql.TypeLonglong}, + {Tp: mysql.TypeLonglong, Flag: mysql.UnsignedFlag}, + }, + }, + {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETInt, types.ETInt}, + childrenFieldTypes: []*types.FieldType{{Tp: mysql.TypeLonglong, Flag: mysql.UnsignedFlag}, + {Tp: mysql.TypeLonglong}, + }, + }, + }, ast.Coalesce: {}, ast.NullEQ: {}, - ast.GT: {}, - ast.EQ: {}, - ast.GE: {}, - ast.Date: {}, + ast.GT: { + {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETInt, types.ETInt}}, + {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETInt, types.ETInt}, + childrenFieldTypes: []*types.FieldType{{Tp: mysql.TypeLonglong, Flag: mysql.UnsignedFlag}, + {Tp: mysql.TypeLonglong, Flag: mysql.UnsignedFlag}, + }, + }, + {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETInt, types.ETInt}, + childrenFieldTypes: []*types.FieldType{{Tp: mysql.TypeLonglong}, + {Tp: mysql.TypeLonglong, Flag: mysql.UnsignedFlag}, + }, + }, + {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETInt, types.ETInt}, + childrenFieldTypes: []*types.FieldType{{Tp: mysql.TypeLonglong, Flag: mysql.UnsignedFlag}, + {Tp: mysql.TypeLonglong}, + }, + }, + }, + ast.EQ: {}, + ast.GE: {}, + ast.Date: {}, ast.Greatest: { {retEvalType: types.ETDecimal, childrenTypes: []types.EvalType{types.ETDecimal, types.ETDecimal, types.ETDecimal}}, {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETInt, types.ETInt, types.ETInt}}, diff --git a/expression/generator/compare_vec.go b/expression/generator/compare_vec.go index 42151672af019..84b8ec22d42df 100644 --- a/expression/generator/compare_vec.go +++ b/expression/generator/compare_vec.go @@ -87,8 +87,6 @@ func (b *builtin{{ .compare.CompareName }}{{ .type.TypeName }}Sig) vecEvalInt(in } {{- if eq .type.ETName "Json" }} val := json.CompareBinary(buf0.GetJSON(i), buf1.GetJSON(i)) -{{ else if eq .type.ETName "Int" }} - val := types.CompareInt64(arg0[i],arg1[i]) {{ else if eq .type.ETName "Real" }} val := types.CompareFloat64(arg0[i], arg1[i]) {{- else if eq .type.ETName "String" }} @@ -150,8 +148,6 @@ func (b *builtin{{ .compare.CompareName }}{{ .type.TypeName }}Sig) vecEvalInt(in i64s[i] = 0 {{- if eq .type.ETName "Json" }} case json.CompareBinary(buf0.GetJSON(i), buf1.GetJSON(i)) == 0: -{{ else if eq .type.ETName "Int" }} - case types.CompareInt64(arg0[i], arg1[i]) == 0: {{ else if eq .type.ETName "Real" }} case types.CompareFloat64(arg0[i], arg1[i]) == 0: {{- else if eq .type.ETName "String" }} @@ -194,8 +190,13 @@ func (b *builtin{{ .compare.CompareName }}{{ .type.TypeName }}Sig) vecEval{{ .ty for i := 0; i < n; i++ { if !buf1.IsNull(i) && result.IsNull(i) { i64s[i] = args[i] - result.SetNull(i, false) + result.SetNull(i, buf1.IsNull(i)) + continue } + if !result.IsNull(i) { + continue + } + result.SetNull(i, true) } } return nil @@ -203,31 +204,42 @@ func (b *builtin{{ .compare.CompareName }}{{ .type.TypeName }}Sig) vecEval{{ .ty {{ else }} func (b *builtin{{ .compare.CompareName }}{{ .type.TypeName }}Sig) vecEval{{ .type.TypeName }}(input *chunk.Chunk, result *chunk.Column) error { n := input.NumRows() - argLen := len(b.args) - bufs := make([]*chunk.Column, argLen) + result.Reserve{{ .type.TypeNameInColumn }}(n) - for i := 0; i < argLen; i++ { - buf, err := b.bufAllocator.get(types.ETInt, n) - if err != nil { + buf1, err := b.bufAllocator.get(types.ET{{ .type.ETName }}, n) + if err != nil { + return err + } + defer b.bufAllocator.put(buf1) + + buf2, err := b.bufAllocator.get(types.ET{{ .type.ETName }}, n) + if err != nil { + return err + } + defer b.bufAllocator.put(buf2) + + buf2.Reserve{{ .type.TypeNameInColumn }}(len(b.args) * n) + for j := 0; j < len(b.args); j++ { + if err := b.args[j].VecEval{{ .type.TypeName }}(b.ctx, input, buf1); err != nil { return err } - defer b.bufAllocator.put(buf) - err = b.args[i].VecEval{{ .type.TypeName }}(b.ctx, input, buf) - if err != nil { - return err + for i := 0; i < n; i++ { + if buf1.IsNull(i) { + buf2.AppendNull() + continue + } + buf2.Append{{ .type.TypeName }}(buf1.Get{{ .type.TypeName }}(i)) } - bufs[i]=buf } - result.Reserve{{ .type.TypeName }}(n) - for i := 0; i < n; i++ { - for j := 0; j < argLen; j++ { - if !bufs[j].IsNull(i) { - result.Append{{ .type.TypeName }}(bufs[j].Get{{ .type.TypeName }}(i)) + for j := 0; j < len(b.args); j++ { + index := i + j*n + if !buf2.IsNull(index) { + result.Append{{ .type.TypeName }}(buf2.Get{{ .type.TypeName }}(index)) break } - if j == argLen-1 && bufs[j].IsNull(i) { + if j == len(b.args)-1 && buf2.IsNull(index) { result.AppendNull() } } @@ -316,7 +328,6 @@ var comparesMap = []CompareContext{ } var typesMap = []TypeContext{ - TypeInt, TypeReal, TypeDecimal, TypeString, @@ -333,7 +344,7 @@ func generateDotGo(fileName string, compares []CompareContext, types []TypeConte var ctx = make(map[string]interface{}) for _, compareCtx := range compares { - for _, typeCtx := range types { + for typesIndex, typeCtx := range types { ctx["compare"] = compareCtx ctx["type"] = typeCtx if compareCtx.CompareName == "NullEQ" { @@ -347,7 +358,13 @@ func generateDotGo(fileName string, compares []CompareContext, types []TypeConte if err != nil { return err } - + if typesIndex == 0 { + ctx["type"] = TypeInt + err := builtinCoalesceCompareVecTpl.Execute(w, ctx) + if err != nil { + return err + } + } } else { err := builtinCompareVecTpl.Execute(w, ctx) if err != nil { @@ -371,18 +388,7 @@ func generateTestDotGo(fileName string, compares []CompareContext, types []TypeC for _, compareCtx := range compares { if compareCtx.CompareName == "Coalesce" { - err := builtinCompareVecTestFuncHeader.Execute(w, CompareContext{CompareName: "Coalesce"}) - if err != nil { - return err - } - for _, typeCtx := range types { - err := builtinCoalesceCompareVecTestFunc.Execute(w, typeCtx) - if err != nil { - return err - } - } - w.WriteString(builtinCompareVecTestFuncTail) - continue + break } err := builtinCompareVecTestFuncHeader.Execute(w, compareCtx) if err != nil { @@ -396,6 +402,19 @@ func generateTestDotGo(fileName string, compares []CompareContext, types []TypeC } w.WriteString(builtinCompareVecTestFuncTail) } + err := builtinCompareVecTestFuncHeader.Execute(w, CompareContext{CompareName: "Coalesce"}) + if err != nil { + return err + } + types = append(types, TypeInt) + for _, typeCtx := range types { + err := builtinCoalesceCompareVecTestFunc.Execute(w, typeCtx) + if err != nil { + return err + } + } + w.WriteString(builtinCompareVecTestFuncTail) + w.WriteString(builtinCompareVecTestTail) data, err := format.Source(w.Bytes())