Skip to content

Commit

Permalink
*: parser support crc32 conv bit_xor (pingcap#2347)
Browse files Browse the repository at this point in the history
*: parser support crc32 conv bit_xor
  • Loading branch information
nolouch authored Dec 29, 2016
1 parent c00a1c3 commit c99cdaa
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 1 deletion.
2 changes: 2 additions & 0 deletions ast/functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ const (
Abs = "abs"
Ceil = "ceil"
Ceiling = "ceiling"
Conv = "conv"
CRC32 = "crc32"
Ln = "ln"
Log = "log"
Log2 = "log2"
Expand Down
2 changes: 2 additions & 0 deletions expression/builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ var Funcs = map[string]Func{
ast.Power: {builtinPow, 2, 2},
ast.Rand: {builtinRand, 0, 1},
ast.Round: {builtinRound, 1, 2},
ast.Conv: {builtinConv, 3, 3},
ast.CRC32: {builtinCRC32, 1, 1},

// time functions
ast.Curdate: {builtinCurrentDate, 0, 0},
Expand Down
21 changes: 21 additions & 0 deletions expression/builtin_math.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package expression

import (
"hash/crc32"
"math"
"math/rand"

Expand Down Expand Up @@ -185,3 +186,23 @@ func builtinRound(args []types.Datum, ctx context.Context) (d types.Datum, err e
d.SetFloat64(types.Round(x, dec))
return d, nil
}

// See http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_conv
func builtinConv(args []types.Datum, ctx context.Context) (d types.Datum, err error) {
//TODO implement
return d, errors.New("Function unimplement")
}

// See http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_crc32
func builtinCRC32(args []types.Datum, ctx context.Context) (d types.Datum, err error) {
if args[0].IsNull() {
return d, nil
}
x, err := args[0].ToString()
if err != nil {
return d, errors.Trace(err)
}
r := crc32.ChecksumIEEE([]byte(x))
d.SetUint64(uint64(r))
return d, nil
}
20 changes: 20 additions & 0 deletions expression/builtin_math_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,23 @@ func (s *testEvaluatorSuite) TestRound(c *C) {
c.Assert(v, testutil.DatumEquals, t["Ret"][0])
}
}

func (s *testEvaluatorSuite) TestCRC32(c *C) {
defer testleak.AfterTest(c)()
tbl := []struct {
Arg []interface{}
Ret uint64
}{
{[]interface{}{"mysql"}, 2501908538},
{[]interface{}{"MySQL"}, 3259397556},
{[]interface{}{"hello"}, 907060870},
}

Dtbl := tblToDtbl(tbl)

for _, t := range Dtbl {
v, err := builtinCRC32(t["Arg"], s.ctx)
c.Assert(err, IsNil)
c.Assert(v, testutil.DatumEquals, t["Ret"][0])
}
}
3 changes: 3 additions & 0 deletions parser/misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,9 @@ var tokenMap = map[string]int{
"CHAR_FUNC": charFunc,
"CHAR_LENGTH": charLength,
"CHARACTER_LENGTH": charLength,
"CONV": conv,
"BIT_XOR": bitXor,
"CRC32": crc32,
}

func isTokenIdentifier(s string, buf *bytes.Buffer) int {
Expand Down
22 changes: 22 additions & 0 deletions parser/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,9 @@ import (
charFunc "CHAR_FUNC"
charLength "CHAR_LENGTH"
characterLength "CHARACTER_LENGTH"
conv "CONV"
bitXor "BIT_XOR"
crc32 "CRC32"

/* the following tokens belong to UnReservedKeyword*/
action "ACTION"
Expand Down Expand Up @@ -3021,6 +3024,21 @@ FunctionCallNonKeyword:
Args: []ast.ExprNode{$3.(ast.ExprNode)},
}
}
| "CONV" '(' Expression ',' Expression ',' Expression ')'
{
$$ = &ast.FuncCallExpr{
FnName: model.NewCIStr($1),
Args: []ast.ExprNode{$3.(ast.ExprNode), $5.(ast.ExprNode), $7.(ast.ExprNode)},
}
}
| "CRC32" '(' Expression ')'
{
$$ = &ast.FuncCallExpr{
FnName: model.NewCIStr($1),
Args: []ast.ExprNode{$3.(ast.ExprNode)},
}
}


DateArithOpt:
"DATE_ADD"
Expand Down Expand Up @@ -3099,6 +3117,10 @@ FunctionCallAgg:
{
$$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$4.(ast.ExprNode)}, Distinct: $3.(bool)}
}
| "BIT_XOR" '(' DistinctOpt Expression ')'
{
$$ = &ast.AggregateFuncExpr{F: $1, Args: []ast.ExprNode{$4.(ast.ExprNode)}, Distinct: $3.(bool)}
}

FuncDatetimePrec:
{
Expand Down
2 changes: 2 additions & 0 deletions parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,8 @@ func (s *testParserSuite) TestBuiltin(c *C) {
{"SELECT LOG(2, 65536);", true},
{"SELECT LOG2(2);", true},
{"SELECT LOG10(10);", true},
{"SELECT CONV(10+'10'+'10'+X'0a',10,10);", true},
{"SELECT CRC32('MySQL');", true},

{"SELECT SUBSTR('Quadratically',5);", true},
{"SELECT SUBSTR('Quadratically',5, 3);", true},
Expand Down
2 changes: 1 addition & 1 deletion plan/typeinferer.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ func (v *typeInferrer) handleFuncCallExpr(x *ast.FuncCallExpr) {
"substring_index", "trim", "ltrim", "rtrim", "reverse", "hex", "unhex", "date_format", "rpad", "char_func":
tp = types.NewFieldType(mysql.TypeVarString)
chs = v.defaultCharset
case "strcmp", "isnull", "bit_length", "char_length", "character_length":
case "strcmp", "isnull", "bit_length", "char_length", "character_length", "crc32":
tp = types.NewFieldType(mysql.TypeLonglong)
case "connection_id":
tp = types.NewFieldType(mysql.TypeLonglong)
Expand Down
1 change: 1 addition & 0 deletions plan/typeinferer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ func (ts *testTypeInferrerSuite) TestInferType(c *C) {
{"char(66)", mysql.TypeVarString, charset.CharsetUTF8},
{"char_length('TiDB')", mysql.TypeLonglong, charset.CharsetBin},
{"character_length('TiDB')", mysql.TypeLonglong, charset.CharsetBin},
{"crc32('TiDB')", mysql.TypeLonglong, charset.CharsetBin},
}
for _, ca := range cases {
ctx := testKit.Se.(context.Context)
Expand Down

0 comments on commit c99cdaa

Please sign in to comment.