Пример #1
0
// See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_curdate
func builtinCurrentDate(args []types.Datum, _ context.Context) (d types.Datum, err error) {
	year, month, day := time.Now().Date()
	t := types.Time{
		Time: types.FromDate(year, int(month), day, 0, 0, 0, 0),
		Type: mysql.TypeDate, Fsp: 0}
	d.SetMysqlTime(t)
	return d, nil
}
Пример #2
0
func (s *testEvaluatorSuite) TestBinopNumeric(c *C) {
	defer testleak.AfterTest(c)()
	tbl := []struct {
		lhs interface{}
		op  opcode.Op
		rhs interface{}
		ret interface{}
	}{
		// plus
		{1, opcode.Plus, 1, 2},
		{1, opcode.Plus, uint64(1), 2},
		{1, opcode.Plus, "1", 2},
		{1, opcode.Plus, types.NewDecFromInt(1), 2},
		{uint64(1), opcode.Plus, 1, 2},
		{uint64(1), opcode.Plus, uint64(1), 2},
		{uint64(1), opcode.Plus, -1, 0},
		{1, opcode.Plus, []byte("1"), 2},
		{1, opcode.Plus, types.Hex{Value: 1}, 2},
		{1, opcode.Plus, types.Bit{Value: 1, Width: 1}, 2},
		{1, opcode.Plus, types.Enum{Name: "a", Value: 1}, 2},
		{1, opcode.Plus, types.Set{Name: "a", Value: 1}, 2},

		// minus
		{1, opcode.Minus, 1, 0},
		{1, opcode.Minus, uint64(1), 0},
		{1, opcode.Minus, float64(1), 0},
		{1, opcode.Minus, types.NewDecFromInt(1), 0},
		{uint64(1), opcode.Minus, 1, 0},
		{uint64(1), opcode.Minus, uint64(1), 0},
		{types.NewDecFromInt(1), opcode.Minus, 1, 0},
		{"1", opcode.Minus, []byte("1"), 0},

		// mul
		{1, opcode.Mul, 1, 1},
		{1, opcode.Mul, uint64(1), 1},
		{1, opcode.Mul, float64(1), 1},
		{1, opcode.Mul, types.NewDecFromInt(1), 1},
		{uint64(1), opcode.Mul, 1, 1},
		{uint64(1), opcode.Mul, uint64(1), 1},
		{types.Time{Time: types.FromDate(0, 0, 0, 0, 0, 0, 0)}, opcode.Mul, 0, 0},
		{types.ZeroDuration, opcode.Mul, 0, 0},
		{types.Time{Time: types.FromGoTime(time.Now()), Fsp: 0, Type: mysql.TypeDatetime}, opcode.Mul, 0, 0},
		{types.Time{Time: types.FromGoTime(time.Now()), Fsp: 6, Type: mysql.TypeDatetime}, opcode.Mul, 0, 0},
		{types.Duration{Duration: 100000000, Fsp: 6}, opcode.Mul, 0, 0},

		// div
		{1, opcode.Div, float64(1), 1},
		{1, opcode.Div, float64(0), nil},
		{1, opcode.Div, 2, 0.5},
		{1, opcode.Div, 0, nil},

		// int div
		{1, opcode.IntDiv, 2, 0},
		{1, opcode.IntDiv, uint64(2), 0},
		{1, opcode.IntDiv, 0, nil},
		{1, opcode.IntDiv, uint64(0), nil},
		{uint64(1), opcode.IntDiv, 2, 0},
		{uint64(1), opcode.IntDiv, uint64(2), 0},
		{uint64(1), opcode.IntDiv, 0, nil},
		{uint64(1), opcode.IntDiv, uint64(0), nil},
		{1.0, opcode.IntDiv, 2.0, 0},
		{1.0, opcode.IntDiv, 0, nil},

		// mod
		{10, opcode.Mod, 2, 0},
		{10, opcode.Mod, uint64(2), 0},
		{10, opcode.Mod, 0, nil},
		{10, opcode.Mod, uint64(0), nil},
		{-10, opcode.Mod, uint64(2), 0},
		{uint64(10), opcode.Mod, 2, 0},
		{uint64(10), opcode.Mod, uint64(2), 0},
		{uint64(10), opcode.Mod, 0, nil},
		{uint64(10), opcode.Mod, uint64(0), nil},
		{uint64(10), opcode.Mod, -2, 0},
		{float64(10), opcode.Mod, 2, 0},
		{float64(10), opcode.Mod, 0, nil},
		{types.NewDecFromInt(10), opcode.Mod, 2, 0},
		{types.NewDecFromInt(10), opcode.Mod, 0, nil},
	}

	for _, t := range tbl {
		expr := &ast.BinaryOperationExpr{Op: t.op, L: ast.NewValueExpr(t.lhs), R: ast.NewValueExpr(t.rhs)}
		v, err := Eval(s.ctx, expr)
		c.Assert(err, IsNil)
		switch v.Kind() {
		case types.KindNull:
			c.Assert(t.ret, IsNil)
		default:
			// we use float64 as the result type check for all.
			sc := s.ctx.GetSessionVars().StmtCtx
			f, err := v.ToFloat64(sc)
			c.Assert(err, IsNil)
			d := types.NewDatum(t.ret)
			r, err := d.ToFloat64(sc)
			c.Assert(err, IsNil)
			c.Assert(r, Equals, f)
		}
	}
}