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

expression: refine built-in func truncate to support uint arg #8000

Merged
merged 9 commits into from
Oct 24, 2018
46 changes: 43 additions & 3 deletions expression/builtin_math.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ var (
_ builtinFunc = &builtinTruncateIntSig{}
_ builtinFunc = &builtinTruncateRealSig{}
_ builtinFunc = &builtinTruncateDecimalSig{}
_ builtinFunc = &builtinTruncateUnintSig{}
)

type absFunctionClass struct {
Expand Down Expand Up @@ -1737,7 +1738,11 @@ func (c *truncateFunctionClass) getFunction(ctx sessionctx.Context, args []Expre
var sig builtinFunc
switch argTp {
case types.ETInt:
sig = &builtinTruncateIntSig{bf}
if mysql.HasUnsignedFlag(args[0].GetType().Flag){
sig = &builtinTruncateUnintSig{bf}
} else {
sig = &builtinTruncateIntSig{bf}
}
case types.ETReal:
sig = &builtinTruncateRealSig{bf}
case types.ETDecimal:
Expand Down Expand Up @@ -1826,6 +1831,41 @@ func (b *builtinTruncateIntSig) evalInt(row chunk.Row) (int64, bool, error) {
return 0, isNull, errors.Trace(err)
}

floatX := float64(x)
return int64(types.Truncate(floatX, int(d))), false, nil
if d >= 0 {
return x, false, nil
} else {
shift := int64(math.Pow10(int(-d)))
return x / shift * shift, false, nil
}
}

func (b *builtinTruncateUnintSig) Clone() builtinFunc {
newSig := &builtinTruncateUnintSig{}
newSig.cloneFrom(&b.baseBuiltinFunc)
return newSig
}

type builtinTruncateUnintSig struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/Unint/Uint/

baseBuiltinFunc
}

// evalInt evals a TRUNCATE(X,D).
// See https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_truncate
func (b *builtinTruncateUnintSig) evalInt(row chunk.Row) (int64, bool, error) {
x, isNull, err := b.args[0].EvalInt(b.ctx, row)
if isNull || err != nil {
return 0, isNull, errors.Trace(err)
}
uintx := uint64(x)

d, isNull, err := b.args[1].EvalInt(b.ctx, row)
if isNull || err != nil {
return 0, isNull, errors.Trace(err)
}
if d >= 0 {
return x, false, nil
} else {
shift := uint64(math.Pow10(int(-d)))
return int64(uintx / shift * shift), false, nil
}
}
3 changes: 3 additions & 0 deletions expression/builtin_math_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,9 @@ func (s *testEvaluatorSuite) TestTruncate(c *C) {
{[]interface{}{newDec("23.298"), -100}, newDec("0")},
{[]interface{}{newDec("23.298"), 100}, newDec("23.298")},
{[]interface{}{nil, 2}, nil},
{[]interface{}{uint64(9223372036854775808), -10}, 9223372030000000000},
yu34po marked this conversation as resolved.
Show resolved Hide resolved
{[]interface{}{9223372036854775807, -7}, 9223372036850000000},
{[]interface{}{uint64(18446744073709551615), -10}, uint64(18446744070000000000)},
}

Dtbl := tblToDtbl(tbl)
Expand Down