Merge pull request #23 from pingcap/shenli/builtin-convert
Add convert type function
This commit is contained in:
@ -29,6 +29,8 @@ type FunctionCast struct {
|
||||
Expr expression.Expression
|
||||
// Tp is the conversion type.
|
||||
Tp *types.FieldType
|
||||
// Cast and Convert share this struct.
|
||||
IsConvert bool
|
||||
}
|
||||
|
||||
// Clone implements the Expression Clone interface.
|
||||
@ -38,8 +40,9 @@ func (f *FunctionCast) Clone() (expression.Expression, error) {
|
||||
return nil, err
|
||||
}
|
||||
nf := &FunctionCast{
|
||||
Expr: expr,
|
||||
Tp: f.Tp,
|
||||
Expr: expr,
|
||||
Tp: f.Tp,
|
||||
IsConvert: f.IsConvert,
|
||||
}
|
||||
return nf, nil
|
||||
}
|
||||
@ -61,6 +64,9 @@ func (f *FunctionCast) String() string {
|
||||
} else {
|
||||
tpStr = f.Tp.String()
|
||||
}
|
||||
if f.IsConvert {
|
||||
return fmt.Sprintf("CONVERT(%s, %s)", f.Expr.String(), tpStr)
|
||||
}
|
||||
return fmt.Sprintf("CAST(%s AS %s)", f.Expr.String(), tpStr)
|
||||
}
|
||||
|
||||
|
||||
@ -74,4 +74,16 @@ func (s *testCastSuite) TestCast(c *C) {
|
||||
|
||||
_, err = expr.Eval(nil, nil)
|
||||
c.Assert(err, NotNil)
|
||||
|
||||
// For String()
|
||||
f = types.NewFieldType(mysql.TypeLonglong)
|
||||
expr = &FunctionCast{
|
||||
Expr: Value{1},
|
||||
Tp: f,
|
||||
}
|
||||
str := expr.String()
|
||||
c.Assert(str, Equals, "CAST(1 AS SIGNED)")
|
||||
expr.IsConvert = true
|
||||
str = expr.String()
|
||||
c.Assert(str, Equals, "CONVERT(1, SIGNED)")
|
||||
}
|
||||
|
||||
@ -1808,6 +1808,15 @@ Function:
|
||||
Charset: $5.(string),
|
||||
}
|
||||
}
|
||||
| "CONVERT" '(' Expression ',' CastType ')'
|
||||
{
|
||||
// See: https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#function_convert
|
||||
$$ = &expressions.FunctionCast{
|
||||
Expr: $3.(expression.Expression),
|
||||
Tp: $5.(*types.FieldType),
|
||||
IsConvert: true,
|
||||
}
|
||||
}
|
||||
| "SUBSTRING" '(' Expression ',' Expression ')'
|
||||
{
|
||||
$$ = &expressions.FunctionSubstring{
|
||||
|
||||
@ -18,6 +18,8 @@ import (
|
||||
"testing"
|
||||
|
||||
. "github.com/pingcap/check"
|
||||
"github.com/pingcap/tidb/expression/expressions"
|
||||
"github.com/pingcap/tidb/stmt/stmts"
|
||||
)
|
||||
|
||||
func TestT(t *testing.T) {
|
||||
@ -257,6 +259,8 @@ func (s *testParserSuite) TestParser0(c *C) {
|
||||
{"SELECT SUBSTRING('Quadratically' FROM 5);", true},
|
||||
{"SELECT SUBSTRING('Quadratically' FROM 5 FOR 3);", true},
|
||||
|
||||
{"SELECT CONVERT('111', SIGNED);", true},
|
||||
|
||||
// For delete statement
|
||||
{"DELETE t1, t2 FROM t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.id=t2.id AND t2.id=t3.id;", true},
|
||||
{"DELETE FROM t1, t2 USING t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.id=t2.id AND t2.id=t3.id;", true},
|
||||
@ -284,8 +288,7 @@ func (s *testParserSuite) TestParser0(c *C) {
|
||||
src := "SELECT id+?, id+? from t;"
|
||||
l := NewLexer(src)
|
||||
l.SetPrepare()
|
||||
ok := yyParse(l) == 0
|
||||
c.Assert(ok, Equals, true)
|
||||
c.Assert(yyParse(l), Equals, 0)
|
||||
c.Assert(len(l.ParamList), Equals, 2)
|
||||
c.Assert(len(l.Stmts()), Equals, 1)
|
||||
|
||||
@ -293,7 +296,17 @@ func (s *testParserSuite) TestParser0(c *C) {
|
||||
src = "CREATE TABLE foo (a SMALLINT UNSIGNED, b INT UNSIGNED,); -- foo\nSelect --1 from foo;"
|
||||
l = NewLexer(src)
|
||||
l.SetPrepare()
|
||||
ok = yyParse(l) == 0
|
||||
c.Assert(ok, Equals, true)
|
||||
c.Assert(yyParse(l), Equals, 0)
|
||||
c.Assert(len(l.Stmts()), Equals, 2)
|
||||
|
||||
// Testcase for CONVERT(expr,type)
|
||||
src = "SELECT CONVERT('111', SIGNED);"
|
||||
l = NewLexer(src)
|
||||
c.Assert(yyParse(l), Equals, 0)
|
||||
st := l.Stmts()[0]
|
||||
ss, ok := st.(*stmts.SelectStmt)
|
||||
c.Assert(ok, IsTrue)
|
||||
cv, ok := ss.Fields[0].Expr.(*expressions.FunctionCast)
|
||||
c.Assert(ok, IsTrue)
|
||||
c.Assert(cv.IsConvert, IsTrue)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user