Skip to content

Commit

Permalink
expression,table: fix insert partitioned table bug when the time zone…
Browse files Browse the repository at this point in the history
… change (#14370) (#14476)
  • Loading branch information
tiancaiamao authored and bb7133 committed Jan 16, 2020
1 parent 91f8a2a commit 0d84245
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 3 deletions.
4 changes: 4 additions & 0 deletions expression/builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,10 @@ type builtinFunc interface {
Clone() builtinFunc
}

type builtinFuncNew interface {
evalIntWithCtx(ctx sessionctx.Context, row chunk.Row) (val int64, isNull bool, err error)
}

// baseFunctionClass will be contained in every struct that implement functionClass interface.
type baseFunctionClass struct {
funcName string
Expand Down
4 changes: 4 additions & 0 deletions expression/builtin_compare.go
Original file line number Diff line number Diff line change
Expand Up @@ -1455,6 +1455,10 @@ func (b *builtinLTIntSig) Clone() builtinFunc {
return newSig
}

func (b *builtinLTIntSig) evalIntWithCtx(ctx sessionctx.Context, row chunk.Row) (val int64, isNull bool, err error) {
return resOfLT(CompareInt(ctx, b.args[0], b.args[1], row, row))
}

func (b *builtinLTIntSig) evalInt(row chunk.Row) (val int64, isNull bool, err error) {
return resOfLT(CompareInt(b.ctx, b.args[0], b.args[1], row, row))
}
Expand Down
15 changes: 12 additions & 3 deletions expression/builtin_time.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ var (
_ functionClass = &subDateFunctionClass{}
)

var (
_ builtinFuncNew = &builtinUnixTimestampIntSig{}
)

var (
_ builtinFunc = &builtinDateSig{}
_ builtinFunc = &builtinDateLiteralSig{}
Expand Down Expand Up @@ -4315,15 +4319,20 @@ func (b *builtinUnixTimestampIntSig) Clone() builtinFunc {
// evalInt evals a UNIX_TIMESTAMP(time).
// See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_unix-timestamp
func (b *builtinUnixTimestampIntSig) evalInt(row chunk.Row) (int64, bool, error) {
val, isNull, err := b.args[0].EvalTime(b.ctx, row)
return b.evalIntWithCtx(b.ctx, row)
}

func (b *builtinUnixTimestampIntSig) evalIntWithCtx(ctx sessionctx.Context, row chunk.Row) (int64, bool, error) {
val, isNull, err := b.args[0].EvalTime(ctx, row)
if err != nil && terror.ErrorEqual(types.ErrInvalidTimeFormat.GenWithStackByArgs(val), err) {
// Return 0 for invalid date time.
return 0, false, nil
}
if isNull {
return 0, true, nil
}
t, err := val.Time.GoTime(getTimeZone(b.ctx))

tz := ctx.GetSessionVars().Location()
t, err := val.Time.GoTime(tz)
if err != nil {
return 0, false, nil
}
Expand Down
3 changes: 3 additions & 0 deletions expression/scalar_function.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,9 @@ func (sf *ScalarFunction) Eval(row chunk.Row) (d types.Datum, err error) {

// EvalInt implements Expression interface.
func (sf *ScalarFunction) EvalInt(ctx sessionctx.Context, row chunk.Row) (int64, bool, error) {
if f, ok := sf.Function.(builtinFuncNew); ok {
return f.evalIntWithCtx(ctx, row)
}
return sf.Function.evalInt(row)
}

Expand Down
57 changes: 57 additions & 0 deletions table/tables/partition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -308,3 +308,60 @@ func (ts *testSuite) TestLocateRangePartitionErr(c *C) {
_, err := tk.Exec("INSERT INTO t_month_data_monitor VALUES (4, '2019-04-04')")
c.Assert(table.ErrNoPartitionForGivenValue.Equal(err), IsTrue)
}

func (ts *testSuite) TestTimeZoneChange(c *C) {
tk := testkit.NewTestKitWithInit(c, ts.store)
tk.MustExec("use test")
createTable := `CREATE TABLE timezone_test (
id int(11) NOT NULL,
creation_dt timestamp DEFAULT CURRENT_TIMESTAMP ) PARTITION BY RANGE ( unix_timestamp(creation_dt) )
( PARTITION p5 VALUES LESS THAN ( UNIX_TIMESTAMP('2020-01-03 15:10:00') ),
PARTITION p6 VALUES LESS THAN ( UNIX_TIMESTAMP('2020-01-03 15:15:00') ),
PARTITION p7 VALUES LESS THAN ( UNIX_TIMESTAMP('2020-01-03 15:20:00') ),
PARTITION p8 VALUES LESS THAN ( UNIX_TIMESTAMP('2020-01-03 15:25:00') ),
PARTITION p9 VALUES LESS THAN (MAXVALUE) )`
tk.MustExec("SET @@time_zone = 'Asia/Shanghai'")
tk.MustExec(createTable)
tk.MustQuery("SHOW CREATE TABLE timezone_test").Check(testkit.Rows("timezone_test CREATE TABLE `timezone_test` (\n" +
" `id` int(11) NOT NULL,\n" +
" `creation_dt` timestamp DEFAULT CURRENT_TIMESTAMP\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
"PARTITION BY RANGE ( unix_timestamp(`creation_dt`) ) (\n" +
" PARTITION p5 VALUES LESS THAN (1578035400),\n" +
" PARTITION p6 VALUES LESS THAN (1578035700),\n" +
" PARTITION p7 VALUES LESS THAN (1578036000),\n" +
" PARTITION p8 VALUES LESS THAN (1578036300),\n" +
" PARTITION p9 VALUES LESS THAN (MAXVALUE)\n)"))
tk.MustExec("DROP TABLE timezone_test")

// Note that the result of "show create table" varies with time_zone.
tk.MustExec("SET @@time_zone = 'UTC'")
tk.MustExec(createTable)
tk.MustQuery("SHOW CREATE TABLE timezone_test").Check(testkit.Rows("timezone_test CREATE TABLE `timezone_test` (\n" +
" `id` int(11) NOT NULL,\n" +
" `creation_dt` timestamp DEFAULT CURRENT_TIMESTAMP\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
"PARTITION BY RANGE ( unix_timestamp(`creation_dt`) ) (\n" +
" PARTITION p5 VALUES LESS THAN (1578064200),\n" +
" PARTITION p6 VALUES LESS THAN (1578064500),\n" +
" PARTITION p7 VALUES LESS THAN (1578064800),\n" +
" PARTITION p8 VALUES LESS THAN (1578065100),\n" +
" PARTITION p9 VALUES LESS THAN (MAXVALUE)\n)"))

// Change time zone and insert data, check the data locates in the correct partition.
tk.MustExec("SET @@time_zone = 'Asia/Shanghai'")
tk.MustExec("INSERT INTO timezone_test VALUES (1,'2020-01-03 15:16:59')")
tk.MustQuery("SELECT * FROM timezone_test PARTITION (p5)").Check(testkit.Rows("1 2020-01-03 15:16:59"))
tk.MustQuery("SELECT * FROM timezone_test PARTITION (p6)").Check(testkit.Rows())
tk.MustQuery("SELECT * FROM timezone_test PARTITION (p7)").Check(testkit.Rows())
tk.MustQuery("SELECT * FROM timezone_test PARTITION (p8)").Check(testkit.Rows())
tk.MustQuery("SELECT * FROM timezone_test PARTITION (p9)").Check(testkit.Rows())

tk.MustExec("SET @@time_zone = 'UTC'")
tk.MustExec("INSERT INTO timezone_test VALUES (1,'2020-01-03 15:16:59')")
tk.MustQuery("SELECT * FROM timezone_test PARTITION (p5)").Check(testkit.Rows("1 2020-01-03 07:16:59"))
tk.MustQuery("SELECT * FROM timezone_test PARTITION (p6)").Check(testkit.Rows())
tk.MustQuery("SELECT * FROM timezone_test PARTITION (p7)").Check(testkit.Rows("1 2020-01-03 15:16:59"))
tk.MustQuery("SELECT * FROM timezone_test PARTITION (p8)").Check(testkit.Rows())
tk.MustQuery("SELECT * FROM timezone_test PARTITION (p9)").Check(testkit.Rows())
}

0 comments on commit 0d84245

Please sign in to comment.