func compareForTest(a, b interface{}) (int, error) { sc := new(variable.StatementContext) sc.IgnoreTruncate = true aDatum := NewDatum(a) bDatum := NewDatum(b) return aDatum.CompareDatum(sc, bDatum) }
func (s *testCompareSuite) TestCompareDatum(c *C) { defer testleak.AfterTest(c)() cmpTbl := []struct { lhs Datum rhs Datum ret int // 0, 1, -1 }{ {MaxValueDatum(), NewDatum("00:00:00"), 1}, {MinNotNullDatum(), NewDatum("00:00:00"), -1}, {Datum{}, NewDatum("00:00:00"), -1}, {Datum{}, Datum{}, 0}, {MinNotNullDatum(), MinNotNullDatum(), 0}, {MaxValueDatum(), MaxValueDatum(), 0}, {Datum{}, MinNotNullDatum(), -1}, {MinNotNullDatum(), MaxValueDatum(), -1}, } sc := new(variable.StatementContext) sc.IgnoreTruncate = true for i, t := range cmpTbl { comment := Commentf("%d %v %v", i, t.lhs, t.rhs) ret, err := t.lhs.CompareDatum(sc, t.rhs) c.Assert(err, IsNil) c.Assert(ret, Equals, t.ret, comment) ret, err = t.rhs.CompareDatum(sc, t.lhs) c.Assert(err, IsNil) c.Assert(ret, Equals, -t.ret, comment) } }
func (ts *testTypeConvertSuite) TestToFloat32(c *C) { ft := NewFieldType(mysql.TypeFloat) var datum = NewFloat64Datum(281.37) sc := new(variable.StatementContext) sc.IgnoreTruncate = true converted, err := datum.ConvertTo(sc, ft) c.Assert(err, IsNil) c.Assert(converted.Kind(), Equals, KindFloat32) c.Assert(converted.GetFloat32(), Equals, float32(281.37)) datum.SetString("281.37") converted, err = datum.ConvertTo(sc, ft) c.Assert(err, IsNil) c.Assert(converted.Kind(), Equals, KindFloat32) c.Assert(converted.GetFloat32(), Equals, float32(281.37)) ft = NewFieldType(mysql.TypeDouble) datum = NewFloat32Datum(281.37) converted, err = datum.ConvertTo(sc, ft) c.Assert(err, IsNil) c.Assert(converted.Kind(), Equals, KindFloat64) // Convert to float32 and convert back to float64, we will get a different value. c.Assert(converted.GetFloat64(), Not(Equals), 281.37) c.Assert(converted.GetFloat64(), Equals, datum.GetFloat64()) }
func (ts *testDatumSuite) TestToBool(c *C) { testDatumToBool(c, int(0), 0) testDatumToBool(c, int64(0), 0) testDatumToBool(c, uint64(0), 0) testDatumToBool(c, float32(0.1), 0) testDatumToBool(c, float64(0.1), 0) testDatumToBool(c, "", 0) testDatumToBool(c, "0.1", 0) testDatumToBool(c, []byte{}, 0) testDatumToBool(c, []byte("0.1"), 0) testDatumToBool(c, Hex{Value: 0}, 0) testDatumToBool(c, Bit{Value: 0, Width: 8}, 0) testDatumToBool(c, Enum{Name: "a", Value: 1}, 1) testDatumToBool(c, Set{Name: "a", Value: 1}, 1) t, err := ParseTime("2011-11-10 11:11:11.999999", mysql.TypeTimestamp, 6) c.Assert(err, IsNil) testDatumToBool(c, t, 1) td, err := ParseDuration("11:11:11.999999", 6) c.Assert(err, IsNil) testDatumToBool(c, td, 1) ft := NewFieldType(mysql.TypeNewDecimal) ft.Decimal = 5 v, err := Convert(0.1415926, ft) c.Assert(err, IsNil) testDatumToBool(c, v, 0) d := NewDatum(&invalidMockType{}) sc := new(variable.StatementContext) sc.IgnoreTruncate = true _, err = d.ToBool(sc) c.Assert(err, NotNil) }
func testEqualDatums(c *C, a []interface{}, b []interface{}, same bool) { sc := new(variable.StatementContext) sc.IgnoreTruncate = true res, err := EqualDatums(sc, MakeDatums(a), MakeDatums(b)) c.Assert(err, IsNil) c.Assert(res, Equals, same, Commentf("a: %v, b: %v", a, b)) }
func testDatumToInt64(c *C, val interface{}, expect int64) { d := NewDatum(val) sc := new(variable.StatementContext) sc.IgnoreTruncate = true b, err := d.ToInt64(sc) c.Assert(err, IsNil) c.Assert(b, Equals, expect) }
func testDatumToBool(c *C, in interface{}, res int) { datum := NewDatum(in) res64 := int64(res) sc := new(variable.StatementContext) sc.IgnoreTruncate = true b, err := datum.ToBool(sc) c.Assert(err, IsNil) c.Assert(b, Equals, res64) }
func testStrToFloat(c *C, str string, expect float64, truncateAsErr bool, expectErr error) { sc := new(variable.StatementContext) sc.IgnoreTruncate = !truncateAsErr val, err := StrToFloat(sc, str) if expectErr != nil { c.Assert(terror.ErrorEqual(err, expectErr), IsTrue) } else { c.Assert(err, IsNil) c.Assert(val, Equals, expect) } }
// Before every execution, we must clear statement context. func resetStmtCtx(ctx context.Context, s ast.StmtNode) { sessVars := ctx.GetSessionVars() sc := new(variable.StatementContext) switch s.(type) { case *ast.UpdateStmt, *ast.InsertStmt, *ast.DeleteStmt: sc.IgnoreTruncate = false sc.TruncateAsWarning = !sessVars.StrictSQLMode if _, ok := s.(*ast.UpdateStmt); ok { sc.InUpdateStmt = true } default: sc.IgnoreTruncate = true if show, ok := s.(*ast.ShowStmt); ok { if show.Tp == ast.ShowWarnings { sc.SetWarnings(sessVars.StmtCtx.GetWarnings()) } } } sessVars.StmtCtx = sc }
func accept(c *C, tp byte, value interface{}, unsigned bool, expected string) { ft := NewFieldType(tp) if unsigned { ft.Flag |= mysql.UnsignedFlag } d := NewDatum(value) sc := new(variable.StatementContext) sc.IgnoreTruncate = true casted, err := d.ConvertTo(sc, ft) c.Assert(err, IsNil, Commentf("%v", ft)) if casted.IsNull() { c.Assert(expected, Equals, "<nil>") } else { str, err := casted.ToString() c.Assert(err, IsNil) c.Assert(str, Equals, expected) } }
func (ts *testDatumSuite) TestCoerceDatum(c *C) { testCases := []struct { a Datum b Datum kind byte }{ {NewIntDatum(1), NewIntDatum(1), KindInt64}, {NewUintDatum(1), NewDecimalDatum(NewDecFromInt(1)), KindMysqlDecimal}, {NewFloat64Datum(1), NewDecimalDatum(NewDecFromInt(1)), KindFloat64}, {NewFloat64Datum(1), NewFloat64Datum(1), KindFloat64}, } sc := new(variable.StatementContext) sc.IgnoreTruncate = true for _, ca := range testCases { x, y, err := CoerceDatum(sc, ca.a, ca.b) c.Check(err, IsNil) c.Check(x.Kind(), Equals, y.Kind()) c.Check(x.Kind(), Equals, ca.kind) } }
// FlagsToStatementContext creates a StatementContext from a `tipb.SelectRequest.Flags`. func FlagsToStatementContext(flags uint64) *variable.StatementContext { sc := new(variable.StatementContext) sc.IgnoreTruncate = (flags & FlagIgnoreTruncate) > 0 sc.TruncateAsWarning = (flags & FlagTruncateAsWarning) > 0 return sc }
func (ts *testDatumSuite) TestBitOps(c *C) { testCases := []struct { a Datum b Datum bitop string // bitwise operator result Datum }{ // And {NewIntDatum(341), NewIntDatum(170), "And", NewIntDatum(0)}, {NewIntDatum(341), NewUintDatum(170), "And", NewUintDatum(0)}, {NewUintDatum(341), NewUintDatum(170), "And", NewUintDatum(0)}, {NewIntDatum(-1), NewFloat64Datum(-2.5), "And", NewUintDatum(18446744073709551613)}, {NewFloat64Datum(-1.4), NewFloat64Datum(-2.4), "And", NewUintDatum(18446744073709551614)}, {NewFloat64Datum(-1.5), NewFloat64Datum(-2.5), "And", NewUintDatum(18446744073709551612)}, // Or {NewIntDatum(341), NewIntDatum(170), "Or", NewIntDatum(511)}, {NewIntDatum(341), NewUintDatum(170), "Or", NewUintDatum(511)}, {NewUintDatum(341), NewUintDatum(170), "Or", NewUintDatum(511)}, {NewIntDatum(-1), NewFloat64Datum(-2.5), "Or", NewUintDatum(18446744073709551615)}, {NewFloat64Datum(-1.4), NewFloat64Datum(-2.4), "Or", NewUintDatum(18446744073709551615)}, {NewFloat64Datum(-1.5), NewFloat64Datum(-2.5), "Or", NewUintDatum(18446744073709551615)}, // Xor {NewIntDatum(341), NewIntDatum(170), "Xor", NewUintDatum(511)}, {NewIntDatum(341), NewUintDatum(170), "Xor", NewUintDatum(511)}, {NewUintDatum(341), NewUintDatum(170), "Xor", NewUintDatum(511)}, {NewIntDatum(-1), NewFloat64Datum(-2.5), "Xor", NewUintDatum(2)}, {NewFloat64Datum(-1.4), NewFloat64Datum(-2.4), "Xor", NewUintDatum(1)}, {NewFloat64Datum(-1.5), NewFloat64Datum(-2.5), "Xor", NewUintDatum(3)}, // Not {NewIntDatum(-1), Datum{}, "Not", NewUintDatum(0)}, {NewIntDatum(1), Datum{}, "Not", NewUintDatum(18446744073709551614)}, {NewFloat64Datum(-0.5), Datum{}, "Not", NewUintDatum(0)}, {NewFloat64Datum(-0.4), Datum{}, "Not", NewUintDatum(18446744073709551615)}, {NewUintDatum(18446744073709551615), Datum{}, "Not", NewUintDatum(0)}, // LeftShift {NewIntDatum(-1), NewIntDatum(1), "LeftShift", NewUintDatum(18446744073709551614)}, {NewIntDatum(-1), NewIntDatum(-1), "LeftShift", NewUintDatum(0)}, {NewIntDatum(1), NewIntDatum(10), "LeftShift", NewUintDatum(1024)}, {NewFloat64Datum(-1.4), NewFloat64Datum(2.4), "LeftShift", NewUintDatum(18446744073709551612)}, {NewFloat64Datum(-1.4), NewFloat64Datum(2.5), "LeftShift", NewUintDatum(18446744073709551608)}, // RightShift {NewUintDatum(18446744073709551614), NewIntDatum(1), "RightShift", NewUintDatum(9223372036854775807)}, {NewIntDatum(-1), NewIntDatum(-1), "RightShift", NewUintDatum(0)}, {NewIntDatum(1024), NewIntDatum(10), "RightShift", NewUintDatum(1)}, {NewFloat64Datum(1024), NewFloat64Datum(10.4), "RightShift", NewUintDatum(1)}, {NewFloat64Datum(1024), NewFloat64Datum(10.5), "RightShift", NewUintDatum(0)}, } for _, ca := range testCases { var ( result Datum err error ) sc := new(variable.StatementContext) sc.IgnoreTruncate = true switch ca.bitop { case "And": result, err = ComputeBitAnd(sc, ca.a, ca.b) case "Or": result, err = ComputeBitOr(sc, ca.a, ca.b) case "Not": result, err = ComputeBitNeg(sc, ca.a) case "Xor": result, err = ComputeBitXor(sc, ca.a, ca.b) case "LeftShift": result, err = ComputeLeftShift(sc, ca.a, ca.b) case "RightShift": result, err = ComputeRightShift(sc, ca.a, ca.b) } c.Check(err, Equals, nil) c.Assert(result.GetUint64(), Equals, ca.result.GetUint64()) } }