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:
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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()
|
||||
|
||||
Reference in New Issue
Block a user