evaluator: funcCast set value directly without types.DataItem.

Other expression check `expr.GetValue() == nil` returns false when we wrap nil in DataItem.
This commit is contained in:
Ewan Chou
2015-12-11 12:20:39 +08:00
parent d6256a4730
commit 30ee5fd354
2 changed files with 39 additions and 5 deletions

View File

@ -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
}

View File

@ -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()