Skip to content

Commit

Permalink
Merge pull request #23 from pingcap/shenli/builtin-convert
Browse files Browse the repository at this point in the history
Add convert type function
  • Loading branch information
shenli committed Sep 7, 2015
2 parents d628bcb + 8663db2 commit a0ca718
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 6 deletions.
10 changes: 8 additions & 2 deletions expression/expressions/cast.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
}
Expand All @@ -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)
}

Expand Down
12 changes: 12 additions & 0 deletions expression/expressions/cast_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)")
}
9 changes: 9 additions & 0 deletions parser/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand Down
21 changes: 17 additions & 4 deletions parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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},
Expand Down Expand Up @@ -284,16 +288,25 @@ 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)

// Testcase for -- Comment and unary -- operator
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)
}

0 comments on commit a0ca718

Please sign in to comment.