From 30ee5fd354591a56165abc76b14cc99a1959cf8f Mon Sep 17 00:00:00 2001 From: Ewan Chou Date: Fri, 11 Dec 2015 12:20:39 +0800 Subject: [PATCH] evaluator: funcCast set value directly without types.DataItem. Other expression check `expr.GetValue() == nil` returns false when we wrap nil in DataItem. --- optimizer/evaluator/evaluator.go | 8 +++--- optimizer/evaluator/evaluator_test.go | 36 +++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/optimizer/evaluator/evaluator.go b/optimizer/evaluator/evaluator.go index 9f2939d94c..78025e1736 100644 --- a/optimizer/evaluator/evaluator.go +++ b/optimizer/evaluator/evaluator.go @@ -627,20 +627,18 @@ func (e *Evaluator) funcConvert(f *ast.FuncConvertExpr) bool { func (e *Evaluator) funcCast(v *ast.FuncCastExpr) bool { value := v.Expr.GetValue() - d := &types.DataItem{Type: v.Tp} // Casting nil to any type returns null if value == nil { - d.Data = nil - v.SetValue(d) + v.SetValue(nil) return true } var err error - d.Data, err = types.Cast(value, v.Tp) + value, err = types.Cast(value, v.Tp) if err != nil { e.err = errors.Trace(err) return false } - v.SetValue(d.Data) + v.SetValue(value) return true } diff --git a/optimizer/evaluator/evaluator_test.go b/optimizer/evaluator/evaluator_test.go index 9d6db51a1f..d1613f373a 100644 --- a/optimizer/evaluator/evaluator_test.go +++ b/optimizer/evaluator/evaluator_test.go @@ -23,6 +23,7 @@ import ( "github.com/pingcap/tidb/mysql" "github.com/pingcap/tidb/parser" "github.com/pingcap/tidb/parser/opcode" + "github.com/pingcap/tidb/util/charset" "github.com/pingcap/tidb/util/mock" "github.com/pingcap/tidb/util/types" ) @@ -383,6 +384,41 @@ func (s *testEvaluatorSuite) TestConvert(c *C) { } } +func (s *testEvaluatorSuite) TestCast(c *C) { + f := types.NewFieldType(mysql.TypeLonglong) + + expr := &ast.FuncCastExpr{ + Expr: ast.NewValueExpr(1), + Tp: f, + } + ctx := mock.NewContext() + v, err := Eval(ctx, expr) + c.Assert(err, IsNil) + c.Assert(v, Equals, int64(1)) + + f.Flag |= mysql.UnsignedFlag + v, err = Eval(ctx, expr) + c.Assert(err, IsNil) + c.Assert(v, Equals, uint64(1)) + + f.Tp = mysql.TypeString + f.Charset = charset.CharsetBin + v, err = Eval(ctx, expr) + c.Assert(err, IsNil) + c.Assert(v, DeepEquals, []byte("1")) + + f.Tp = mysql.TypeString + f.Charset = "utf8" + v, err = Eval(ctx, expr) + c.Assert(err, IsNil) + c.Assert(v, DeepEquals, "1") + + expr.Expr = ast.NewValueExpr(nil) + v, err = Eval(ctx, expr) + c.Assert(err, IsNil) + c.Assert(v, IsNil) +} + func (s *testEvaluatorSuite) TestDateArith(c *C) { c.Skip("to be implement") ctx := mock.NewContext()