func (v *typeInferrer) binaryOperation(x *ast.BinaryOperationExpr) { switch x.Op { case opcode.AndAnd, opcode.OrOr, opcode.LogicXor: x.Type = types.NewFieldType(mysql.TypeLonglong) case opcode.LT, opcode.LE, opcode.GE, opcode.GT, opcode.EQ, opcode.NE, opcode.NullEQ: x.Type = types.NewFieldType(mysql.TypeLonglong) case opcode.RightShift, opcode.LeftShift, opcode.And, opcode.Or, opcode.Xor: x.Type = types.NewFieldType(mysql.TypeLonglong) x.Type.Flag |= mysql.UnsignedFlag case opcode.IntDiv: x.Type = types.NewFieldType(mysql.TypeLonglong) case opcode.Plus, opcode.Minus, opcode.Mul, opcode.Mod: if x.L.GetType() != nil && x.R.GetType() != nil { xTp := mergeArithType(x.L.GetType().Tp, x.R.GetType().Tp) x.Type = types.NewFieldType(xTp) leftUnsigned := x.L.GetType().Flag & mysql.UnsignedFlag rightUnsigned := x.R.GetType().Flag & mysql.UnsignedFlag // If both operands are unsigned, result is unsigned. x.Type.Flag |= (leftUnsigned & rightUnsigned) } case opcode.Div: if x.L.GetType() != nil && x.R.GetType() != nil { xTp := mergeArithType(x.L.GetType().Tp, x.R.GetType().Tp) if xTp == mysql.TypeLonglong { xTp = mysql.TypeDecimal } x.Type = types.NewFieldType(xTp) } } x.Type.Charset = charset.CharsetBin x.Type.Collate = charset.CollationBin }