Beispiel #1
0
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)
}
Beispiel #2
0
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)
	}
}
Beispiel #3
0
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())
}
Beispiel #4
0
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)
}
Beispiel #5
0
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))
}
Beispiel #6
0
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)
}
Beispiel #7
0
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)
}
Beispiel #8
0
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)
	}
}
Beispiel #9
0
// 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
}
Beispiel #10
0
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)
	}
}
Beispiel #11
0
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)
	}
}
Beispiel #12
0
// 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
}
Beispiel #13
0
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())
	}
}