Skip to content

Commit

Permalink
expression: base #3868 pr, and rewrite builtin function unary minus t…
Browse files Browse the repository at this point in the history
…o handle overflow gracely
  • Loading branch information
winkyao committed Jul 25, 2017
1 parent 869e1f6 commit b305a4f
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 31 deletions.
1 change: 1 addition & 0 deletions executor/aggregate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ func (s *testSuite) TestAggPrune(c *C) {
testleak.AfterTest(c)()
}()
tk := testkit.NewTestKit(c, s.store)

tk.MustExec("use test")
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(id int primary key, b varchar(50), c int)")
Expand Down
1 change: 1 addition & 0 deletions executor/prepared.go
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ func ResetStmtCtx(ctx context.Context, s ast.StmtNode) {
sc.TruncateAsWarning = !sessVars.StrictSQLMode
case *ast.SelectStmt:
sc.InSelectStmt = true
sc.IgnoreTruncate = true
default:
sc.IgnoreTruncate = true
if show, ok := s.(*ast.ShowStmt); ok {
Expand Down
20 changes: 15 additions & 5 deletions expression/builtin_op_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,29 @@ func (s *testEvaluatorSuite) TestUnary(c *C) {
}{
{uint64(9223372036854775809), "-9223372036854775809", true, false},
{uint64(9223372036854775810), "-9223372036854775810", true, false},
{uint64(9223372036854775808), -9223372036854775808, false, false},
{uint64(9223372036854775808), int64(-9223372036854775808), false, false},
{int64(math.MinInt64), "9223372036854775808", true, false}, // --9223372036854775808
}
sc := s.ctx.GetSessionVars().StmtCtx
origin := sc.InSelectStmt
sc.InSelectStmt = true
defer func() {
sc.InSelectStmt = origin
}()

for _, t := range cases {
f, err := newFunctionForTest(s.ctx, ast.UnaryMinus, primitiveValsToConstants([]interface{}{t.args})...)
c.Assert(err, IsNil)
d, err := f.Eval(nil)

if !t.overflow {
c.Assert(d.GetValue(), Equals, t.expected)
if t.getErr == false {
c.Assert(err, IsNil)
if !t.overflow {
c.Assert(d.GetValue(), Equals, t.expected)
} else {
c.Assert(d.GetMysqlDecimal().String(), Equals, t.expected)
}
} else {
c.Assert(d.GetMysqlDecimal().String(), Equals, t.expected)
c.Assert(err, NotNil)
}
}
}
Expand Down
26 changes: 0 additions & 26 deletions expression/scalar_function.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/sessionctx/variable"
"github.com/pingcap/tidb/terror"
"github.com/pingcap/tidb/util/codec"
"github.com/pingcap/tidb/util/types"
)
Expand Down Expand Up @@ -161,21 +160,6 @@ func (sf *ScalarFunction) Decorrelate(schema *Schema) Expression {
return sf
}

func (sf *ScalarFunction) convertArgsToDecimal(sc *variable.StatementContext) error {
ft := types.NewFieldType(mysql.TypeNewDecimal)
for _, arg := range sf.GetArgs() {
if constArg, ok := arg.(*Constant); ok {
val, err := constArg.Value.ConvertTo(sc, ft)
if err != nil {
return errors.Trace(err)
}
constArg.Value = val
}
}

return nil
}

// Eval implements Expression interface.
func (sf *ScalarFunction) Eval(row []types.Datum) (d types.Datum, err error) {
sc := sf.GetCtx().GetSessionVars().StmtCtx
Expand Down Expand Up @@ -213,16 +197,6 @@ func (sf *ScalarFunction) Eval(row []types.Datum) (d types.Datum, err error) {
}
}

if err != nil && terror.ErrorEqual(err, types.ErrOverflow) &&
sf.FuncName.L == ast.UnaryMinus && sc.InSelectStmt {
// TODO: fix #3762, overflow convert it to decimal
err = sf.convertArgsToDecimal(sc)
if err != nil {
return d, errors.Trace(err)
}
res, isNull, err = sf.EvalDecimal(row, sc)
}

if isNull || err != nil {
d.SetValue(nil)
return d, errors.Trace(err)
Expand Down

0 comments on commit b305a4f

Please sign in to comment.