继续分分析PR。
Pass go vet #16
这个修复了没有指定结构体中变量名的一些测试数据。
mysqldef: fix issue #19 #20
修复了issues#19中提到的make test错误。
原因就是Marshal()中没有使用本地时区导致的。
然后对Timestamp的测试案例修改了两个边界值。
Allow uses to shutdown the pprof #17
谢大对pprof增加了debug开关。
tidb: Add some comments #24
增加了pprof的注释。
mysqldef: save FSP and fix zone offset for codec #29
这个PR对mysqldef.Time的Marshal和UnmarshalInLocation的二进制编码解码增加了FSP信息,然后修复了时区偏移问题,并增加了测试数据。
Add convert type function #23
添加了一个mysql的函数 CONVERT(expr,type),
mysql文档说明了:Discussion of CONVERT(expr, type) syntax here also applies to CAST(expr AS type), which is equivalent。这个函数的具体实现和 CAST(expr AS type)等价(这个CAST已经实现过了),这里加了一个标志来区别是否为Convert,主要用在String()方法。然后对parser.y添加了这个语法。
Pass go tool vet –shadow #31
优化修改了一些变量的重复使用和格式。
Godeps: Update version of boltdb #30
更新boltdb 的版本。
Pass gofmt #32
格式化代码。
cleanup compare #35
把之前零散的不同类型之间的比较统一整合在了util/types/compare.go,并且以前用panic抛出的异常改为返回error。
tidb: update gitignore #38
修改了gitignore。
Update godep packages. #34
更新/改了依赖包。
expressions: operator supports []byte type #39
首先跟着代码跑会发现,select 1 + cast(“123” as binary);这样的语句还不支持,那么原因在这里:
// Operator: DIV / - % MOD + *
// See https://dev.mysql.com/doc/refman/5.7/en/arithmetic-functions.html#operator_divide
func (o *BinaryOperation) evalArithmeticOp(ctx context.Context, args map[interface{}]interface{}) (interface{}, error) {
	a, b, err := o.get2(ctx, args)
	if err != nil {
		return nil, err
	}
	if a == nil || b == nil {
		// TODO: for <=>, if a and b are both nil, return true
		return nil, nil
	}
	if a, b, err = o.coerceArithmetic2(a, b); err != nil {
		return nil, o.traceErr(err)
	}
	// TODO: support logic division DIV
	switch o.Op {
	case opcode.Plus:
		return o.evalPlus(a, b)
	case opcode.Minus:
		return o.evalMinus(a, b)
	case opcode.Mul:
		return o.evalMul(a, b)
	case opcode.Div:
		return o.evalDiv(a, b)
	case opcode.Mod:
		return o.evalMod(a, b)
	case opcode.IntDiv:
		return o.evalIntDiv(a, b)
	default:
		return nil, o.errorf("invalid op %v in arithmetic operation", o.Op)
	}
}
在a, b, err := o.get2(ctx, args)得到表达式左右两边的值一个是int64一个是[]byte,这个没问题,然后这个o.coerceArithmetic2(a, b)的作用是把需要做算术运算的两边转换成尽量统一的类型,比如一个int64一个float64,则会把两边都转换成float64,然后在coerceArithmetic2()先调用了:
func (o *BinaryOperation) coerceArithmetic(a interface{}) (interface{}, error) {
	switch x := a.(type) {
	case string:
		// MySQL will convert string to float for arithmetic operation
		f, err := types.StrToFloat(x)
		if err != nil {
			return nil, err
		}
		return f, err
	case mysql.Time:
		// TODO: if time has no precision, return int64
		return x.ToNumber(), nil
	case mysql.Duration:
		// TODO: if duration has no precision, return int64
		return x.ToNumber(), nil
	default:
		return x, nil
	}
}
而这里还没定义[]byte的转换,所以这里直接返回的还是[]byte类型,而后面没有定义[]byte类型的加法等:
func (o *BinaryOperation) evalPlus(a interface{}, b interface{}) (interface{}, error) {
	// TODO: check overflow
	switch x := a.(type) {
	case int64:
		switch y := b.(type) {
		case int64:
			return x + y, nil
		case uint64:
			// For MySQL, if any is unsigned, return unsigned
			// TODO: check overflow
			return uint64(x) + y, nil
		}
	case uint64:
		switch y := b.(type) {
		case int64:
			// For MySQL, if any is unsigned, return unsigned
			// TODO: check overflow
			return x + uint64(y), nil
		case uint64:
			return x + y, nil
		}
	case float64:
		switch y := b.(type) {
		case float64:
			return x + y, nil
		}
	case mysql.Decimal:
		switch y := b.(type) {
		case mysql.Decimal:
			return x.Add(y), nil
		}
	}
	return types.InvOp2(a, b, opcode.Plus)
}
所以只需要这样改coerceArithmetic就解决了。
而这次PR还改了unary.go。这个是为了解决类似:
select + cast("123" as binary);
的,只要跟着跑一下,同理的。
mysqldef: remove fsp codec, set out manually. #40
移除了PR#29中在编码解码中增加的offset,在测试数据改成手动设置offset。