Skip to content

Commit

Permalink
expression: fix convert number base for hybrid type (#21554)
Browse files Browse the repository at this point in the history
Signed-off-by: lzmhhh123 <lzmhhh123@gmail.com>
  • Loading branch information
lzmhhh123 authored Dec 9, 2020
1 parent b3f0f3c commit 6cd3c65
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 5 deletions.
34 changes: 30 additions & 4 deletions expression/builtin_math.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"sync"

"github.com/cznic/mathutil"
"github.com/pingcap/parser/ast"
"github.com/pingcap/parser/mysql"
"github.com/pingcap/tidb/sessionctx"
"github.com/pingcap/tidb/types"
Expand Down Expand Up @@ -1163,11 +1164,25 @@ func (b *builtinConvSig) Clone() builtinFunc {
// evalString evals CONV(N,from_base,to_base).
// See https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_conv.
func (b *builtinConvSig) evalString(row chunk.Row) (res string, isNull bool, err error) {
str, isNull, err := b.args[0].EvalString(b.ctx, row)
if isNull || err != nil {
return res, isNull, err
var str string
switch x := b.args[0].(type) {
case *Constant:
if x.Value.Kind() == types.KindBinaryLiteral {
str = x.Value.GetBinaryLiteral().ToBitLiteralString(true)
}
case *ScalarFunction:
if x.FuncName.L == ast.Cast {
arg0 := x.GetArgs()[0]
if arg0.GetType().Hybrid() || IsBinaryLiteral(arg0) {
str, isNull, err = arg0.EvalString(b.ctx, row)
if isNull || err != nil {
return str, isNull, err
}
d := types.NewStringDatum(str)
str = d.GetBinaryLiteral().ToBitLiteralString(true)
}
}
}

fromBase, isNull, err := b.args[1].EvalInt(b.ctx, row)
if isNull || err != nil {
return res, isNull, err
Expand All @@ -1177,6 +1192,17 @@ func (b *builtinConvSig) evalString(row chunk.Row) (res string, isNull bool, err
if isNull || err != nil {
return res, isNull, err
}
if len(str) == 0 {
str, isNull, err = b.args[0].EvalString(b.ctx, row)
if isNull || err != nil {
return res, isNull, err
}
} else {
str, isNull, err = b.conv(str[2:], 2, fromBase)
if err != nil {
return str, isNull, err
}
}
return b.conv(str, fromBase, toBase)
}
func (b *builtinConvSig) conv(str string, fromBase, toBase int64) (res string, isNull bool, err error) {
Expand Down
3 changes: 2 additions & 1 deletion expression/builtin_math_vec.go
Original file line number Diff line number Diff line change
Expand Up @@ -1070,7 +1070,8 @@ func (b *builtinSignSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) er
}

func (b *builtinConvSig) vectorized() bool {
return true
// TODO: change the vecEval match hybrid type fixing. Then open the vectorized evaluation.
return false
}

func (b *builtinConvSig) vecEvalString(input *chunk.Chunk, result *chunk.Column) error {
Expand Down
2 changes: 2 additions & 0 deletions expression/builtin_math_vec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@ import (
)

var vecBuiltinMathCases = map[string][]vecExprBenchCase{
/* TODO: Because of https://github.com/pingcap/tidb/issues/5817, we don't enable it now.
ast.Conv: {
{
retEvalType: types.ETString,
childrenTypes: []types.EvalType{types.ETString, types.ETInt, types.ETInt},
},
},
*/
ast.Sign: {
{retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETReal}},
},
Expand Down
36 changes: 36 additions & 0 deletions expression/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,42 @@ func (s *testIntegrationSuite2) TestMathBuiltin(c *C) {
result.Check(testkit.Rows("<nil>"))
result = tk.MustQuery("SELECT CONV('a', 37, 10);")
result.Check(testkit.Rows("<nil>"))
result = tk.MustQuery("SELECT CONV(0x0020, 2, 2);")
result.Check(testkit.Rows("100000"))
result = tk.MustQuery("SELECT CONV(0b10, 16, 2)")
result.Check(testkit.Rows("10"))
result = tk.MustQuery("SELECT CONV(0b10, 16, 8)")
result.Check(testkit.Rows("2"))
tk.MustExec("drop table if exists bit")
tk.MustExec("create table bit(b bit(10))")
tk.MustExec(`INSERT INTO bit (b) VALUES
(0b0000010101),
(0b0000010101),
(NULL),
(0b0000000001),
(0b0000000000),
(0b1111111111),
(0b1111111111),
(0b1111111111),
(0b0000000000),
(0b0000000000),
(0b0000000000),
(0b0000000000),
(0b0000100000);`)
tk.MustQuery("select conv(b, 2, 2) from `bit`").Check(testkit.Rows(
"10101",
"10101",
"<nil>",
"1",
"0",
"1111111111",
"1111111111",
"1111111111",
"0",
"0",
"0",
"0",
"100000"))

// for abs
result = tk.MustQuery("SELECT ABS(-1);")
Expand Down

0 comments on commit 6cd3c65

Please sign in to comment.