Repository: pingcap/tidb
Pull request #61337: *: Fix insert dst transition timestamp
Author: login: mjonss
Labels: name: release-note
description: Denotes a PR that will be considered when it comes time to generate release notes.
name: size/XL
description: Denotes a PR that changes 500-999 lines, ignoring generated files.
name: approved
name: lgtm
name: needs-cherry-pick-release-8.5
description: Should cherry pick this PR to release-8.5 branch.
Created: 2025-05-27T00:48:45Z | Merged: 2025-05-29T03:35:01Z

<!--

Thank you for contributing to TiDB!

PR Title Format:
1. pkg [, pkg2, pkg3]: what's changed
2. *: what's changed

-->

### What problem does this PR solve?
<!--

Please create an issue first to describe the problem.

There MUST be one line starting with "Issue Number:  " and
linking the relevant issues via the "close" or "ref".

For more info, check https://pingcap.github.io/tidb-dev-guide/contribute-to-tidb/contribute-code.html#referring-to-an-issue.

-->

Issue Number: close #61334

Problem Summary:

### What changed and how does it work?

### Check List

Tests <!-- At least one of them must be included. -->

- [ ] Unit test
- [x] Integration test
- [ ] Manual test (add detailed scripts or steps below)
- [ ] No need to test
  > - [ ] I checked and no code files have been changed.
  > <!-- Or your custom  "No need to test" reasons -->

Side effects

- [ ] Performance regression: Consumes more CPU
- [ ] Performance regression: Consumes more Memory
- [ ] Breaking backward compatibility

Documentation

- [ ] Affects user behaviors
- [ ] Contains syntax changes
- [ ] Contains variable changes
- [ ] Contains experimental features
- [ ] Changes MySQL compatibility

### Release note

<!-- compatibility change, improvement, bugfix, and new feature need a release note -->

Please refer to [Release Notes Language Style Guide](https://pingcap.github.io/tidb-dev-guide/contribute-to-tidb/release-notes-style-guide.html) to write a quality release note.

```release-note
Fixed an issue when inserting timestamps that would fall into the Daylight Saving Times transition, moving the clock forward, would result in zero date, 0000-00-00.
```


Linked issue #61334: INSERT with timestamp in DST non-existent range results in '0000-00-00' instead as adjusted to next valid time, as in MySQL
## Bug Report

Please answer these questions before submitting your issue. Thanks!

During Daylight Saving Time, DST, the time '2025-03-30 02:00:00'~'2025-03-30 02:59:00' does not exist. When I insert such a invalid data into TiDB , the result is '0000-00-00' and different compared with MySQL 8.0.39, which adjusts it to the next valid time.

### 1. Minimal reproduce step (Required)

```
SET time_zone = 'Europe/Stockholm';
set sql_mode='';
CREATE TABLE `t1` (
   id int,
  `created` timestamp NULL DEFAULT NULL
);
insert into t1 values(1,'2025-03-30 01:59:00');
insert into t1 values(2,'2025-03-30 02:00:00');
insert into t1 values(3,'2025-03-30 02:59:00');
insert into t1 values(4,'2025-03-30 03:00:00');
select * from t1;
```



### 2. What did you expect to see? (Required)

```
mysql> select * from t1;
+------+---------------------+
| id   | created             |
+------+---------------------+
|    1 | 2025-03-30 01:59:00 |
|    2 | 2025-03-30 03:00:00 |
|    3 | 2025-03-30 03:00:00 |
|    4 | 2025-03-30 03:00:00 |
+------+---------------------+
4 rows in set (0.01 sec)
```

### 3. What did you see instead (Required)
```
mysql> select * from t1;
+------+---------------------+
| id   | created             |
+------+---------------------+
|    1 | 2025-03-30 01:59:00 |
|    2 | 0000-00-00 00:00:00 |
|    3 | 0000-00-00 00:00:00 |
|    4 | 2025-03-30 03:00:00 |
+------+---------------------+
4 rows in set (0.01 sec)
```

### 4. What is your TiDB version? (Required)

v8.5.1

Diff:
diff --git a/errors.toml b/errors.toml
index ed58a83f08c39..34c5e84f5b105 100644
--- a/errors.toml
+++ b/errors.toml
@@ -1996,6 +1996,11 @@ error = '''
 Delete can not find column %s for table %s
 '''
 
+["executor:8179"]
+error = '''
+Timestamp is not valid, since it is in Daylight Saving Time transition '%s' for time zone '%s'
+'''
+
 ["executor:8212"]
 error = '''
 Failed to split region ranges: %s
diff --git a/pkg/errno/errcode.go b/pkg/errno/errcode.go
index 2622729a3faf6..dfb99bbde15e5 100644
--- a/pkg/errno/errcode.go
+++ b/pkg/errno/errcode.go
@@ -1087,6 +1087,7 @@ const (
 	ErrMemoryExceedForInstance             = 8176
 	ErrDeleteNotFoundColumn                = 8177
 	ErrKeyTooLarge                         = 8178
+	ErrTimeStampInDSTTransition            = 8179
 
 	// Error codes used by TiDB ddl package
 	ErrUnsupportedDDLOperation            = 8200
diff --git a/pkg/errno/errname.go b/pkg/errno/errname.go
index 6caa979a29e0d..12eb517e0061f 100644
--- a/pkg/errno/errname.go
+++ b/pkg/errno/errname.go
@@ -1185,4 +1185,5 @@ var MySQLErrName = map[uint16]*mysql.ErrMessage{
 	ErrGlobalIndexNotExplicitlySet: mysql.Message("Global Index is needed for index '%-.192s', since the unique index is not including all partitioning columns, and GLOBAL is not given as IndexOption", nil),
 
 	ErrWarnGlobalIndexNeedManuallyAnalyze: mysql.Message("Auto analyze is not effective for index '%-.192s', need analyze manually", nil),
+	ErrTimeStampInDSTTransition:           mysql.Message("Timestamp is not valid, since it is in Daylight Saving Time transition '%s' for time zone '%s'", nil),
 }
diff --git a/pkg/executor/insert_common.go b/pkg/executor/insert_common.go
index 9593943959e64..28ad92c7b744a 100644
--- a/pkg/executor/insert_common.go
+++ b/pkg/executor/insert_common.go
@@ -322,6 +322,16 @@ func (e *InsertValues) handleErr(col *table.Column, val *types.Datum, rowIdx int
 	} else {
 		err = completeInsertErr(c, val, rowIdx, err)
 	}
+	if col != nil && col.GetType() == mysql.TypeTimestamp &&
+		types.ErrTimestampInDSTTransition.Equal(err) {
+		newErr := exeerrors.ErrTruncateWrongInsertValue.FastGenByArgs(types.TypeStr(col.GetType()), val.GetString(), col.Name.O, rowIdx+1)
+		if e.Ctx().GetSessionVars().SQLMode.HasStrictMode() {
+			return newErr
+		}
+		// timestamp already adjusted to end of DST transition, convert error to warning
+		e.Ctx().GetSessionVars().StmtCtx.AppendWarning(newErr)
+		return nil
+	}
 
 	// TODO: should not filter all types of errors here.
 	if err != nil {
diff --git a/pkg/types/errors.go b/pkg/types/errors.go
index 2302932994f1f..3dee9c0da5a3b 100644
--- a/pkg/types/errors.go
+++ b/pkg/types/errors.go
@@ -98,4 +98,7 @@ var (
 	ErrJSONBadOneOrAllArg = dbterror.ClassTypes.NewStd(mysql.ErrJSONBadOneOrAllArg)
 	// ErrJSONVacuousPath is returned for path expressions that are not allowed in that context.
 	ErrJSONVacuousPath = dbterror.ClassTypes.NewStd(mysql.ErrJSONVacuousPath)
+	// ErrTimestampInDSTTransition is returned if the converted timestamp is in the Daylight Saving Time
+	// transition when time leaps forward (normally skips one hour).
+	ErrTimestampInDSTTransition = dbterror.ClassExecutor.NewStd(mysql.ErrTimeStampInDSTTransition)
 )
diff --git a/pkg/types/time.go b/pkg/types/time.go
index 99ebccebfd3a4..81e9451f1728d 100644
--- a/pkg/types/time.go
+++ b/pkg/types/time.go
@@ -2007,6 +2007,17 @@ func parseTime(ctx Context, str string, tp byte, fsp int, isFloat bool) (Time, e
 
 	t.SetType(tp)
 	if err = t.Check(ctx); err != nil {
+		minTS, maxTS := MinTimestamp, MaxTimestamp
+		minErr := minTS.ConvertTimeZone(gotime.UTC, ctx.Location())
+		maxErr := maxTS.ConvertTimeZone(gotime.UTC, ctx.Location())
+		if minErr == nil && maxErr == nil && tp == mysql.TypeTimestamp && !t.IsZero() &&
+			t.Compare(minTS) > 0 && t.Compare(maxTS) < 0 {
+			// Handle the case when the timestamp given is in the DST transition
+			if tAdjusted, err2 := t.AdjustedGoTime(ctx.Location()); err2 == nil {
+				t.SetCoreTime(FromGoTime(tAdjusted))
+				return t, errors.Trace(ErrTimestampInDSTTransition.GenWithStackByArgs(str, ctx.Location().String()))
+			}
+		}
 		return NewTime(ZeroCoreTime, tp, DefaultFsp), errors.Trace(err)
 	}
 	return t, nil
diff --git a/tests/integrationtest/r/executor/insert.result b/tests/integrationtest/r/executor/insert.result
index 217ac06bcacb4..5723a9f293361 100644
--- a/tests/integrationtest/r/executor/insert.result
+++ b/tests/integrationtest/r/executor/insert.result
@@ -2222,3 +2222,205 @@ INSERT IGNORE INTO t1 VALUES (127);
 show warnings;
 Level	Code	Message
 Warning	1062	Duplicate entry '\x00\x00\x7F' for key 't1.id'
+SET @old_time_zone = @@time_zone;
+SET @@time_zone = 'Europe/Amsterdam';
+SET @old_sql_mode = @@sql_mode;
+DROP TABLE IF EXISTS t;
+CREATE TABLE t (id int primary key, ts timestamp, mode varchar(255));
+SET SQL_MODE = '';
+INSERT INTO t VALUES (1, '0000-00-00 00:00:00', '');
+INSERT INTO t VALUES (2, '2025-00-30 00:00:00', '');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-00-30 00:00:00' for column 'ts' at row 1
+INSERT INTO t VALUES (3, '2025-02-30 00:00:00', '');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-02-30 00:00:00' for column 'ts' at row 1
+INSERT INTO t VALUES (4, '2025-03-30 01:59:59', '');
+INSERT INTO t VALUES (5, '2025-03-30 02:00:00', '');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-03-30 02:00:00' for column 'ts' at row 1
+INSERT INTO t VALUES (6, '2025-03-30 02:30:00', '');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-03-30 02:30:00' for column 'ts' at row 1
+INSERT INTO t VALUES (7, '2025-03-30 03:00:00', '');
+SET SQL_MODE = 'ALLOW_INVALID_DATES';
+INSERT INTO t VALUES (8, '0000-00-00 00:00:00', 'ALLOW_INVALID_DATES');
+INSERT INTO t VALUES (9, '2025-00-30 00:00:00', 'ALLOW_INVALID_DATES');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-00-30 00:00:00' for column 'ts' at row 1
+INSERT INTO t VALUES (10, '2025-02-30 00:00:00', 'ALLOW_INVALID_DATES');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-02-30 00:00:00' for column 'ts' at row 1
+INSERT INTO t VALUES (11, '2025-03-30 01:59:59', 'ALLOW_INVALID_DATES');
+INSERT INTO t VALUES (12, '2025-03-30 02:00:00', 'ALLOW_INVALID_DATES');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-03-30 02:00:00' for column 'ts' at row 1
+INSERT INTO t VALUES (13, '2025-03-30 02:30:00', 'ALLOW_INVALID_DATES');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-03-30 02:30:00' for column 'ts' at row 1
+INSERT INTO t VALUES (14, '2025-03-30 03:00:00', 'ALLOW_INVALID_DATES');
+SET SQL_MODE = 'NO_ZERO_IN_DATE';
+INSERT INTO t VALUES (15, '0000-00-00 00:00:00', 'NO_ZERO_IN_DATE');
+INSERT INTO t VALUES (16, '2025-00-30 00:00:00', 'NO_ZERO_IN_DATE');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-00-30 00:00:00' for column 'ts' at row 1
+INSERT INTO t VALUES (17, '2025-02-30 00:00:00', 'NO_ZERO_IN_DATE');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-02-30 00:00:00' for column 'ts' at row 1
+INSERT INTO t VALUES (18, '2025-03-30 01:59:59', 'NO_ZERO_IN_DATE');
+INSERT INTO t VALUES (19, '2025-03-30 02:00:00', 'NO_ZERO_IN_DATE');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-03-30 02:00:00' for column 'ts' at row 1
+INSERT INTO t VALUES (20, '2025-03-30 02:30:00', 'NO_ZERO_IN_DATE');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-03-30 02:30:00' for column 'ts' at row 1
+INSERT INTO t VALUES (21, '2025-03-30 03:00:00', 'NO_ZERO_IN_DATE');
+SET SQL_MODE = 'NO_ZERO_IN_DATE,ALLOW_INVALID_DATES';
+INSERT INTO t VALUES (22, '0000-00-00 00:00:00', 'NO_ZERO_IN_DATE,ALLOW_INVALID_DATES');
+INSERT INTO t VALUES (23, '2025-00-30 00:00:00', 'NO_ZERO_IN_DATE,ALLOW_INVALID_DATES');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-00-30 00:00:00' for column 'ts' at row 1
+INSERT INTO t VALUES (24, '2025-02-30 00:00:00', 'NO_ZERO_IN_DATE,ALLOW_INVALID_DATES');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-02-30 00:00:00' for column 'ts' at row 1
+INSERT INTO t VALUES (25, '2025-03-30 01:59:59', 'NO_ZERO_IN_DATE,ALLOW_INVALID_DATES');
+INSERT INTO t VALUES (26, '2025-03-30 02:00:00', 'NO_ZERO_IN_DATE,ALLOW_INVALID_DATES');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-03-30 02:00:00' for column 'ts' at row 1
+INSERT INTO t VALUES (27, '2025-03-30 02:30:00', 'NO_ZERO_IN_DATE,ALLOW_INVALID_DATES');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-03-30 02:30:00' for column 'ts' at row 1
+INSERT INTO t VALUES (28, '2025-03-30 03:00:00', 'NO_ZERO_IN_DATE,ALLOW_INVALID_DATES');
+SET SQL_MODE = 'NO_ZERO_DATE';
+INSERT INTO t VALUES (29, '0000-00-00 00:00:00', 'NO_ZERO_DATE');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '0000-00-00 00:00:00' for column 'ts' at row 1
+INSERT INTO t VALUES (30, '2025-00-30 00:00:00', 'NO_ZERO_DATE');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-00-30 00:00:00' for column 'ts' at row 1
+INSERT INTO t VALUES (31, '2025-02-30 00:00:00', 'NO_ZERO_DATE');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-02-30 00:00:00' for column 'ts' at row 1
+INSERT INTO t VALUES (32, '2025-03-30 01:59:59', 'NO_ZERO_DATE');
+INSERT INTO t VALUES (33, '2025-03-30 02:00:00', 'NO_ZERO_DATE');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-03-30 02:00:00' for column 'ts' at row 1
+INSERT INTO t VALUES (34, '2025-03-30 02:30:00', 'NO_ZERO_DATE');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-03-30 02:30:00' for column 'ts' at row 1
+INSERT INTO t VALUES (35, '2025-03-30 03:00:00', 'NO_ZERO_DATE');
+SET SQL_MODE = 'NO_ZERO_DATE,ALLOW_INVALID_DATES';
+INSERT INTO t VALUES (36, '0000-00-00 00:00:00', 'NO_ZERO_DATE,ALLOW_INVALID_DATES');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '0000-00-00 00:00:00' for column 'ts' at row 1
+INSERT INTO t VALUES (37, '2025-00-30 00:00:00', 'NO_ZERO_DATE,ALLOW_INVALID_DATES');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-00-30 00:00:00' for column 'ts' at row 1
+INSERT INTO t VALUES (38, '2025-02-30 00:00:00', 'NO_ZERO_DATE,ALLOW_INVALID_DATES');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-02-30 00:00:00' for column 'ts' at row 1
+INSERT INTO t VALUES (39, '2025-03-30 01:59:59', 'NO_ZERO_DATE,ALLOW_INVALID_DATES');
+INSERT INTO t VALUES (40, '2025-03-30 02:00:00', 'NO_ZERO_DATE,ALLOW_INVALID_DATES');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-03-30 02:00:00' for column 'ts' at row 1
+INSERT INTO t VALUES (41, '2025-03-30 02:30:00', 'NO_ZERO_DATE,ALLOW_INVALID_DATES');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-03-30 02:30:00' for column 'ts' at row 1
+INSERT INTO t VALUES (42, '2025-03-30 03:00:00', 'NO_ZERO_DATE,ALLOW_INVALID_DATES');
+SET SQL_MODE = 'NO_ZERO_DATE,NO_ZERO_IN_DATE';
+INSERT INTO t VALUES (43, '0000-00-00 00:00:00', 'NO_ZERO_DATE,NO_ZERO_IN_DATE');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '0000-00-00 00:00:00' for column 'ts' at row 1
+INSERT INTO t VALUES (44, '2025-00-30 00:00:00', 'NO_ZERO_DATE,NO_ZERO_IN_DATE');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-00-30 00:00:00' for column 'ts' at row 1
+INSERT INTO t VALUES (45, '2025-02-30 00:00:00', 'NO_ZERO_DATE,NO_ZERO_IN_DATE');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-02-30 00:00:00' for column 'ts' at row 1
+INSERT INTO t VALUES (46, '2025-03-30 01:59:59', 'NO_ZERO_DATE,NO_ZERO_IN_DATE');
+INSERT INTO t VALUES (47, '2025-03-30 02:00:00', 'NO_ZERO_DATE,NO_ZERO_IN_DATE');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-03-30 02:00:00' for column 'ts' at row 1
+INSERT INTO t VALUES (48, '2025-03-30 02:30:00', 'NO_ZERO_DATE,NO_ZERO_IN_DATE');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-03-30 02:30:00' for column 'ts' at row 1
+INSERT INTO t VALUES (49, '2025-03-30 03:00:00', 'NO_ZERO_DATE,NO_ZERO_IN_DATE');
+SET SQL_MODE = 'NO_ZERO_DATE,NO_ZERO_IN_DATE,ALLOW_INVALID_DATES';
+INSERT INTO t VALUES (50, '0000-00-00 00:00:00', 'NO_ZERO_DATE,NO_ZERO_IN_DATE,ALLOW_INVALID_DATES');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '0000-00-00 00:00:00' for column 'ts' at row 1
+INSERT INTO t VALUES (51, '2025-00-30 00:00:00', 'NO_ZERO_DATE,NO_ZERO_IN_DATE,ALLOW_INVALID_DATES');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-00-30 00:00:00' for column 'ts' at row 1
+INSERT INTO t VALUES (52, '2025-02-30 00:00:00', 'NO_ZERO_DATE,NO_ZERO_IN_DATE,ALLOW_INVALID_DATES');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-02-30 00:00:00' for column 'ts' at row 1
+INSERT INTO t VALUES (53, '2025-03-30 01:59:59', 'NO_ZERO_DATE,NO_ZERO_IN_DATE,ALLOW_INVALID_DATES');
+INSERT INTO t VALUES (54, '2025-03-30 02:00:00', 'NO_ZERO_DATE,NO_ZERO_IN_DATE,ALLOW_INVALID_DATES');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-03-30 02:00:00' for column 'ts' at row 1
+INSERT INTO t VALUES (55, '2025-03-30 02:30:00', 'NO_ZERO_DATE,NO_ZERO_IN_DATE,ALLOW_INVALID_DATES');
+Level	Code	Message
+Warning	1292	Incorrect timestamp value: '2025-03-30 02:30:00' for column 'ts' at row 1
+INSERT INTO t VALUES (56, '2025-03-30 03:00:00', 'NO_ZERO_DATE,NO_ZERO_IN_DATE,ALLOW_INVALID_DATES');
+SELECT * FROM t ORDER BY id;
+id	ts	mode
+1	0000-00-00 00:00:00	
+2	0000-00-00 00:00:00	
+3	0000-00-00 00:00:00	
+4	2025-03-30 01:59:59	
+5	2025-03-30 03:00:00	
+6	2025-03-30 03:00:00	
+7	2025-03-30 03:00:00	
+8	0000-00-00 00:00:00	ALLOW_INVALID_DATES
+9	0000-00-00 00:00:00	ALLOW_INVALID_DATES
+10	0000-00-00 00:00:00	ALLOW_INVALID_DATES
+11	2025-03-30 01:59:59	ALLOW_INVALID_DATES
+12	2025-03-30 03:00:00	ALLOW_INVALID_DATES
+13	2025-03-30 03:00:00	ALLOW_INVALID_DATES
+14	2025-03-30 03:00:00	ALLOW_INVALID_DATES
+15	0000-00-00 00:00:00	NO_ZERO_IN_DATE
+16	0000-00-00 00:00:00	NO_ZERO_IN_DATE
+17	0000-00-00 00:00:00	NO_ZERO_IN_DATE
+18	2025-03-30 01:59:59	NO_ZERO_IN_DATE
+19	2025-03-30 03:00:00	NO_ZERO_IN_DATE
+20	2025-03-30 03:00:00	NO_ZERO_IN_DATE
+21	2025-03-30 03:00:00	NO_ZERO_IN_DATE
+22	0000-00-00 00:00:00	NO_ZERO_IN_DATE,ALLOW_INVALID_DATES
+23	0000-00-00 00:00:00	NO_ZERO_IN_DATE,ALLOW_INVALID_DATES
+24	0000-00-00 00:00:00	NO_ZERO_IN_DATE,ALLOW_INVALID_DATES
+25	2025-03-30 01:59:59	NO_ZERO_IN_DATE,ALLOW_INVALID_DATES
+26	2025-03-30 03:00:00	NO_ZERO_IN_DATE,ALLOW_INVALID_DATES
+27	2025-03-30 03:00:00	NO_ZERO_IN_DATE,ALLOW_INVALID_DATES
+28	2025-03-30 03:00:00	NO_ZERO_IN_DATE,ALLOW_INVALID_DATES
+29	0000-00-00 00:00:00	NO_ZERO_DATE
+30	0000-00-00 00:00:00	NO_ZERO_DATE
+31	0000-00-00 00:00:00	NO_ZERO_DATE
+32	2025-03-30 01:59:59	NO_ZERO_DATE
+33	2025-03-30 03:00:00	NO_ZERO_DATE
+34	2025-03-30 03:00:00	NO_ZERO_DATE
+35	2025-03-30 03:00:00	NO_ZERO_DATE
+36	0000-00-00 00:00:00	NO_ZERO_DATE,ALLOW_INVALID_DATES
+37	0000-00-00 00:00:00	NO_ZERO_DATE,ALLOW_INVALID_DATES
+38	0000-00-00 00:00:00	NO_ZERO_DATE,ALLOW_INVALID_DATES
+39	2025-03-30 01:59:59	NO_ZERO_DATE,ALLOW_INVALID_DATES
+40	2025-03-30 03:00:00	NO_ZERO_DATE,ALLOW_INVALID_DATES
+41	2025-03-30 03:00:00	NO_ZERO_DATE,ALLOW_INVALID_DATES
+42	2025-03-30 03:00:00	NO_ZERO_DATE,ALLOW_INVALID_DATES
+43	0000-00-00 00:00:00	NO_ZERO_DATE,NO_ZERO_IN_DATE
+44	0000-00-00 00:00:00	NO_ZERO_DATE,NO_ZERO_IN_DATE
+45	0000-00-00 00:00:00	NO_ZERO_DATE,NO_ZERO_IN_DATE
+46	2025-03-30 01:59:59	NO_ZERO_DATE,NO_ZERO_IN_DATE
+47	2025-03-30 03:00:00	NO_ZERO_DATE,NO_ZERO_IN_DATE
+48	2025-03-30 03:00:00	NO_ZERO_DATE,NO_ZERO_IN_DATE
+49	2025-03-30 03:00:00	NO_ZERO_DATE,NO_ZERO_IN_DATE
+50	0000-00-00 00:00:00	NO_ZERO_DATE,NO_ZERO_IN_DATE,ALLOW_INVALID_DATES
+51	0000-00-00 00:00:00	NO_ZERO_DATE,NO_ZERO_IN_DATE,ALLOW_INVALID_DATES
+52	0000-00-00 00:00:00	NO_ZERO_DATE,NO_ZERO_IN_DATE,ALLOW_INVALID_DATES
+53	2025-03-30 01:59:59	NO_ZERO_DATE,NO_ZERO_IN_DATE,ALLOW_INVALID_DATES
+54	2025-03-30 03:00:00	NO_ZERO_DATE,NO_ZERO_IN_DATE,ALLOW_INVALID_DATES
+55	2025-03-30 03:00:00	NO_ZERO_DATE,NO_ZERO_IN_DATE,ALLOW_INVALID_DATES
+56	2025-03-30 03:00:00	NO_ZERO_DATE,NO_ZERO_IN_DATE,ALLOW_INVALID_DATES
+DROP TABLE t;
+SET @@time_zone = @old_time_zone;
+SET @@sql_mode = @old_sql_mode;
diff --git a/tests/integrationtest/t/executor/insert.test b/tests/integrationtest/t/executor/insert.test
index 0126e6e60745e..09a58994510da 100644
--- a/tests/integrationtest/t/executor/insert.test
+++ b/tests/integrationtest/t/executor/insert.test
@@ -1678,3 +1678,90 @@ INSERT IGNORE INTO t1 VALUES (127);
 INSERT IGNORE INTO t1 VALUES (127);
 show warnings;
 
+# Testing Timestamp and invalid dates and DST transitions
+--enable_warnings
+SET @old_time_zone = @@time_zone;
+SET @@time_zone = 'Europe/Amsterdam';
+SET @old_sql_mode = @@sql_mode;
+DROP TABLE IF EXISTS t;
+CREATE TABLE t (id int primary key, ts timestamp, mode varchar(255));
+SET SQL_MODE = '';
+# TODO: These report wrong warning:
+# Warning | 1292 | Incorrect timestamp value: '0000-00-00 00:00:00' for column 'ts' at row 1
+# instead of:
+# mysql> Warning | 1264 | Out of range value for column 'ts' at row 1
+INSERT INTO t VALUES (1, '0000-00-00 00:00:00', '');
+# TODO: These report wrong errors:
+# Warning | 1292 | Incorrect timestamp value: '2025-00-30 00:00:00' for column 'ts' at row 1
+# instead of:
+# mysql> Warning | 1264 | Out of range value for column 'ts' at row 1
+INSERT INTO t VALUES (2, '2025-00-30 00:00:00', '');
+# TODO: These report wrong errors:
+# Warning | 1292 | Incorrect timestamp value: '2025-02-30 00:00:00' for column 'ts' at row 1
+# instead of:
+# mysql> Warning | 1264 | Out of range value for column 'ts' at row 1
+INSERT INTO t VALUES (3, '2025-02-30 00:00:00', '');
+INSERT INTO t VALUES (4, '2025-03-30 01:59:59', '');
+INSERT INTO t VALUES (5, '2025-03-30 02:00:00', '');
+INSERT INTO t VALUES (6, '2025-03-30 02:30:00', '');
+INSERT INTO t VALUES (7, '2025-03-30 03:00:00', '');
+SET SQL_MODE = 'ALLOW_INVALID_DATES';
+INSERT INTO t VALUES (8, '0000-00-00 00:00:00', 'ALLOW_INVALID_DATES');
+INSERT INTO t VALUES (9, '2025-00-30 00:00:00', 'ALLOW_INVALID_DATES');
+INSERT INTO t VALUES (10, '2025-02-30 00:00:00', 'ALLOW_INVALID_DATES');
+INSERT INTO t VALUES (11, '2025-03-30 01:59:59', 'ALLOW_INVALID_DATES');
+INSERT INTO t VALUES (12, '2025-03-30 02:00:00', 'ALLOW_INVALID_DATES');
+INSERT INTO t VALUES (13, '2025-03-30 02:30:00', 'ALLOW_INVALID_DATES');
+INSERT INTO t VALUES (14, '2025-03-30 03:00:00', 'ALLOW_INVALID_DATES');
+SET SQL_MODE = 'NO_ZERO_IN_DATE';
+INSERT INTO t VALUES (15, '0000-00-00 00:00:00', 'NO_ZERO_IN_DATE');
+INSERT INTO t VALUES (16, '2025-00-30 00:00:00', 'NO_ZERO_IN_DATE');
+INSERT INTO t VALUES (17, '2025-02-30 00:00:00', 'NO_ZERO_IN_DATE');
+INSERT INTO t VALUES (18, '2025-03-30 01:59:59', 'NO_ZERO_IN_DATE');
+INSERT INTO t VALUES (19, '2025-03-30 02:00:00', 'NO_ZERO_IN_DATE');
+INSERT INTO t VALUES (20, '2025-03-30 02:30:00', 'NO_ZERO_IN_DATE');
+INSERT INTO t VALUES (21, '2025-03-30 03:00:00', 'NO_ZERO_IN_DATE');
+SET SQL_MODE = 'NO_ZERO_IN_DATE,ALLOW_INVALID_DATES';
+INSERT INTO t VALUES (22, '0000-00-00 00:00:00', 'NO_ZERO_IN_DATE,ALLOW_INVALID_DATES');
+INSERT INTO t VALUES (23, '2025-00-30 00:00:00', 'NO_ZERO_IN_DATE,ALLOW_INVALID_DATES');
+INSERT INTO t VALUES (24, '2025-02-30 00:00:00', 'NO_ZERO_IN_DATE,ALLOW_INVALID_DATES');
+INSERT INTO t VALUES (25, '2025-03-30 01:59:59', 'NO_ZERO_IN_DATE,ALLOW_INVALID_DATES');
+INSERT INTO t VALUES (26, '2025-03-30 02:00:00', 'NO_ZERO_IN_DATE,ALLOW_INVALID_DATES');
+INSERT INTO t VALUES (27, '2025-03-30 02:30:00', 'NO_ZERO_IN_DATE,ALLOW_INVALID_DATES');
+INSERT INTO t VALUES (28, '2025-03-30 03:00:00', 'NO_ZERO_IN_DATE,ALLOW_INVALID_DATES');
+SET SQL_MODE = 'NO_ZERO_DATE';
+INSERT INTO t VALUES (29, '0000-00-00 00:00:00', 'NO_ZERO_DATE');
+INSERT INTO t VALUES (30, '2025-00-30 00:00:00', 'NO_ZERO_DATE');
+INSERT INTO t VALUES (31, '2025-02-30 00:00:00', 'NO_ZERO_DATE');
+INSERT INTO t VALUES (32, '2025-03-30 01:59:59', 'NO_ZERO_DATE');
+INSERT INTO t VALUES (33, '2025-03-30 02:00:00', 'NO_ZERO_DATE');
+INSERT INTO t VALUES (34, '2025-03-30 02:30:00', 'NO_ZERO_DATE');
+INSERT INTO t VALUES (35, '2025-03-30 03:00:00', 'NO_ZERO_DATE');
+SET SQL_MODE = 'NO_ZERO_DATE,ALLOW_INVALID_DATES';
+INSERT INTO t VALUES (36, '0000-00-00 00:00:00', 'NO_ZERO_DATE,ALLOW_INVALID_DATES');
+INSERT INTO t VALUES (37, '2025-00-30 00:00:00', 'NO_ZERO_DATE,ALLOW_INVALID_DATES');
+INSERT INTO t VALUES (38, '2025-02-30 00:00:00', 'NO_ZERO_DATE,ALLOW_INVALID_DATES');
+INSERT INTO t VALUES (39, '2025-03-30 01:59:59', 'NO_ZERO_DATE,ALLOW_INVALID_DATES');
+INSERT INTO t VALUES (40, '2025-03-30 02:00:00', 'NO_ZERO_DATE,ALLOW_INVALID_DATES');
+INSERT INTO t VALUES (41, '2025-03-30 02:30:00', 'NO_ZERO_DATE,ALLOW_INVALID_DATES');
+INSERT INTO t VALUES (42, '2025-03-30 03:00:00', 'NO_ZERO_DATE,ALLOW_INVALID_DATES');
+SET SQL_MODE = 'NO_ZERO_DATE,NO_ZERO_IN_DATE';
+INSERT INTO t VALUES (43, '0000-00-00 00:00:00', 'NO_ZERO_DATE,NO_ZERO_IN_DATE');
+INSERT INTO t VALUES (44, '2025-00-30 00:00:00', 'NO_ZERO_DATE,NO_ZERO_IN_DATE');
+INSERT INTO t VALUES (45, '2025-02-30 00:00:00', 'NO_ZERO_DATE,NO_ZERO_IN_DATE');
+INSERT INTO t VALUES (46, '2025-03-30 01:59:59', 'NO_ZERO_DATE,NO_ZERO_IN_DATE');
+INSERT INTO t VALUES (47, '2025-03-30 02:00:00', 'NO_ZERO_DATE,NO_ZERO_IN_DATE');
+INSERT INTO t VALUES (48, '2025-03-30 02:30:00', 'NO_ZERO_DATE,NO_ZERO_IN_DATE');
+INSERT INTO t VALUES (49, '2025-03-30 03:00:00', 'NO_ZERO_DATE,NO_ZERO_IN_DATE');
+SET SQL_MODE = 'NO_ZERO_DATE,NO_ZERO_IN_DATE,ALLOW_INVALID_DATES';
+INSERT INTO t VALUES (50, '0000-00-00 00:00:00', 'NO_ZERO_DATE,NO_ZERO_IN_DATE,ALLOW_INVALID_DATES');
+INSERT INTO t VALUES (51, '2025-00-30 00:00:00', 'NO_ZERO_DATE,NO_ZERO_IN_DATE,ALLOW_INVALID_DATES');
+INSERT INTO t VALUES (52, '2025-02-30 00:00:00', 'NO_ZERO_DATE,NO_ZERO_IN_DATE,ALLOW_INVALID_DATES');
+INSERT INTO t VALUES (53, '2025-03-30 01:59:59', 'NO_ZERO_DATE,NO_ZERO_IN_DATE,ALLOW_INVALID_DATES');
+INSERT INTO t VALUES (54, '2025-03-30 02:00:00', 'NO_ZERO_DATE,NO_ZERO_IN_DATE,ALLOW_INVALID_DATES');
+INSERT INTO t VALUES (55, '2025-03-30 02:30:00', 'NO_ZERO_DATE,NO_ZERO_IN_DATE,ALLOW_INVALID_DATES');
+INSERT INTO t VALUES (56, '2025-03-30 03:00:00', 'NO_ZERO_DATE,NO_ZERO_IN_DATE,ALLOW_INVALID_DATES');
+SELECT * FROM t ORDER BY id;
+DROP TABLE t;
+SET @@time_zone = @old_time_zone;
+SET @@sql_mode = @old_sql_mode;
diff --git a/tests/integrationtest/t/expression/time.test b/tests/integrationtest/t/expression/time.test
index e7c96f3a8ff30..b7f4e7ca602d5 100644
--- a/tests/integrationtest/t/expression/time.test
+++ b/tests/integrationtest/t/expression/time.test
@@ -98,6 +98,7 @@ insert t values (20010101100000.123456, 20110707101112.123456);
 select * from t;
 
 # TestDateAddForNonExistingTimestamp
+-- enable_warnings
 set time_zone = 'CET';
 drop table if exists t;
 create table t(ts timestamp);
@@ -110,6 +111,7 @@ set time_zone = 'Europe/Amsterdam';
 insert into t values('2022-03-27 02:30:00');
 select date_add(ts, interval 1 hour) from t order by ts;
 set time_zone = default;
+-- disable_warnings
 
 # TestTimestampAddWithFractionalSecond
 drop table if exists t;


Reviews:
user: login: copilot-pull-request-reviewer[bot]
body: ## Pull Request Overview

Fix handling of timestamps that fall into the Daylight Saving Time (DST) forward transition by adjusting them instead of producing a zero date, and convert the resulting error into a warning on non-strict inserts.

- Add DST transition detection and adjustment in `parseTime` for `TIMESTAMP` values.
- Introduce a new error type `ErrTimestampInDSTTransition` and hook it into insertion error handling to downgrade to a warning in non-strict mode.
- Cover the new behavior with extensive integration tests against various SQL modes and DST boundaries.

### Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.

<details>
<summary>Show a summary per file</summary>

| File                                    | Description                                                     |
|-----------------------------------------|-----------------------------------------------------------------|
| pkg/types/time.go                       | Detect and adjust timestamps in DST forward transitions.        |
| pkg/types/errors.go                     | Define new `ErrTimestampInDSTTransition` error.                 |
| pkg/executor/insert_common.go           | Handle the new DST error in inserts, convert to warning.        |
| pkg/errno/errcode.go                    | Assign error code for DST transition error.                     |
| pkg/errno/errname.go                    | Register error message for DST transition error.                |
| tests/integrationtest/t/executor/insert.test   | Add integration tests for DST transition cases across modes.    |
| tests/integrationtest/r/executor/insert.result | Update expected results for DST-related warnings and adjustments. |
| tests/integrationtest/t/expression/time.test    | Enable warnings for expression-based DST tests.                 |
</details>



<details>
<summary>Comments suppressed due to low confidence (3)</summary>

**pkg/errno/errcode.go:1090**
* The constant name uses 'TimeStamp' (capital 'S') but the error variable is named ErrTimestampInDSTTransition (lowercase 's'). Rename for consistency.
```
ErrTimeStampInDSTTransition            = 8179
```
**pkg/errno/errname.go:1188**
* Error name mapping uses 'ErrTimeStampInDSTTransition' but the exported error variable is 'ErrTimestampInDSTTransition'. Align the key with the variable name.
```
ErrTimeStampInDSTTransition:           mysql.Message("Timestamp is not valid, since it is in Daylight Saving Time transition '%s' for time zone '%s'", nil),
```
**pkg/types/time.go:2013**
* The new DST adjustment logic in `parseTime` should have dedicated unit tests (e.g., in `time_test.go`) to validate both the adjustment path and the error return.
```
if minErr == nil && maxErr == nil && tp == mysql.TypeTimestamp && !t.IsZero() &&
```
</details>


state: COMMENTED
author_association: NONE
submitted_at: 2025-05-28T07:59:58Z
user: login: Defined2014
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-28T09:45:47Z
user: login: Defined2014
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-28T09:48:19Z
user: login: mjonss
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-28T23:18:34Z
user: login: mjonss
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-28T23:18:59Z
user: login: Defined2014
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-29T02:08:42Z
user: login: YangKeao
body: LGTM
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-29T03:26:47Z

Review comments:
diff_hunk: @@ -98,6 +98,7 @@ insert t values (20010101100000.123456, 20110707101112.123456);
 select * from t;
 
 # TestDateAddForNonExistingTimestamp
+-- enable_warnings
path: tests/integrationtest/t/expression/time.test
user: login: Defined2014
body: Need to call `--disable_warnings` to avoid affecting other test cases.
created_at: 2025-05-28T09:45:47Z
author_association: CONTRIBUTOR
diff_hunk: @@ -322,6 +322,15 @@ func (e *InsertValues) handleErr(col *table.Column, val *types.Datum, rowIdx int
 	} else {
 		err = completeInsertErr(c, val, rowIdx, err)
 	}
+	if col != nil && col.GetType() == mysql.TypeTimestamp &&
+		types.ErrTimestampInDSTTransition.Equal(err) {
+		if e.Ctx().GetSessionVars().SQLMode.HasStrictMode() {
+			return exeerrors.ErrTruncateWrongInsertValue.FastGenByArgs(types.TypeStr(col.GetType()), val.GetString(), col.Name.O, rowIdx+1)
path: pkg/executor/insert_common.go
user: login: Defined2014
body: Maybe we could use a temp variable to store `exeerrors.ErrTruncateWrongInsertValue.FastGenByArgs(types.TypeStr(col.GetType()), val.GetString(), col.Name.O, rowIdx+1)` which could reused.
created_at: 2025-05-28T09:48:19Z
author_association: CONTRIBUTOR
diff_hunk: @@ -98,6 +98,7 @@ insert t values (20010101100000.123456, 20110707101112.123456);
 select * from t;
 
 # TestDateAddForNonExistingTimestamp
+-- enable_warnings
path: tests/integrationtest/t/expression/time.test
user: login: mjonss
body: Thanks for the suggestion, done!
created_at: 2025-05-28T23:18:34Z
author_association: CONTRIBUTOR
diff_hunk: @@ -322,6 +322,15 @@ func (e *InsertValues) handleErr(col *table.Column, val *types.Datum, rowIdx int
 	} else {
 		err = completeInsertErr(c, val, rowIdx, err)
 	}
+	if col != nil && col.GetType() == mysql.TypeTimestamp &&
+		types.ErrTimestampInDSTTransition.Equal(err) {
+		if e.Ctx().GetSessionVars().SQLMode.HasStrictMode() {
+			return exeerrors.ErrTruncateWrongInsertValue.FastGenByArgs(types.TypeStr(col.GetType()), val.GetString(), col.Name.O, rowIdx+1)
path: pkg/executor/insert_common.go
user: login: mjonss
body: Thanks for the suggestion, done!
created_at: 2025-05-28T23:18:59Z
author_association: CONTRIBUTOR

PR comments:
user: login: tiprow[bot]
created_at: 2025-05-27T00:49:03Z
body: Hi @mjonss. Thanks for your PR.

PRs from untrusted users cannot be marked as trusted with `/ok-to-test` in this repo meaning untrusted PR authors can never trigger tests themselves. Collaborators can still trigger tests on the PR using `/test all`.

I understand the commands that are listed [here](https://go.k8s.io/bot-commands?repo=pingcap%2Ftidb).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes-sigs/prow](https://github.com/kubernetes-sigs/prow/issues/new?title=Prow%20issue:) repository.
</details>

author_association: NONE
user: login: codecov[bot]
created_at: 2025-05-28T00:34:46Z
body: ## [Codecov](https://app.codecov.io/gh/pingcap/tidb/pull/61337?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pingcap) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 73.6128%. Comparing base [(`eeccd2e`)](https://app.codecov.io/gh/pingcap/tidb/commit/eeccd2e94c23df353ba70919691d65d38ad31805?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pingcap) to head [(`ca4db35`)](https://app.codecov.io/gh/pingcap/tidb/commit/ca4db35e3e6ce9b84f0e99a7fd3f5237ed31b520?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pingcap).
> Report is 1 commits behind head on master.

<details><summary>Additional details and impacted files</summary>


```diff
@@               Coverage Diff                @@
##             master     #61337        +/-   ##
================================================
+ Coverage   73.1763%   73.6128%   +0.4364%     
================================================
  Files          1726       1726                
  Lines        479335     479369        +34     
================================================
+ Hits         350760     352877      +2117     
+ Misses       107098     105002      -2096     
- Partials      21477      21490        +13     
```

| [Flag](https://app.codecov.io/gh/pingcap/tidb/pull/61337/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pingcap) | Coverage Δ | |
|---|---|---|
| [integration](https://app.codecov.io/gh/pingcap/tidb/pull/61337/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pingcap) | `42.4846% <100.0000%> (?)` | |
| [unit](https://app.codecov.io/gh/pingcap/tidb/pull/61337/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pingcap) | `72.4630% <88.8888%> (+0.0323%)` | :arrow_up: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pingcap#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Components](https://app.codecov.io/gh/pingcap/tidb/pull/61337/components?src=pr&el=components&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pingcap) | Coverage Δ | |
|---|---|---|
| [dumpling](https://app.codecov.io/gh/pingcap/tidb/pull/61337/components?src=pr&el=component&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pingcap) | `52.7804% <ø> (ø)` | |
| [parser](https://app.codecov.io/gh/pingcap/tidb/pull/61337/components?src=pr&el=component&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pingcap) | `∅ <ø> (∅)` | |
| [br](https://app.codecov.io/gh/pingcap/tidb/pull/61337/components?src=pr&el=component&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pingcap) | `47.6113% <ø> (+0.0241%)` | :arrow_up: |

</details>
<details><summary> :rocket: New features to boost your workflow: </summary>

- :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
- :package: [JS Bundle Analysis](https://docs.codecov.com/docs/javascript-bundle-analysis): Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
</details>
author_association: NONE
user: login: mjonss
created_at: 2025-05-28T00:41:18Z
body: /retest
author_association: CONTRIBUTOR
user: login: tiprow[bot]
created_at: 2025-05-28T00:41:39Z
body: @mjonss: Cannot trigger testing until a trusted user reviews the PR and leaves an `/ok-to-test` message.

<details>

In response to [this](https://github.com/pingcap/tidb/pull/61337#issuecomment-2914529021):

>/retest


Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes-sigs/prow](https://github.com/kubernetes-sigs/prow/issues/new?title=Prow%20issue:) repository.
</details>
author_association: NONE
user: login: ti-chi-bot[bot]
created_at: 2025-05-29T03:26:56Z
body: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/pingcap/tidb/pull/61337#pullrequestreview-2876846409" title="Approved">Defined2014</a>*, *<a href="https://github.com/pingcap/tidb/pull/61337#pullrequestreview-2876932819" title="Approved">YangKeao</a>*

The full list of commands accepted by this bot can be found [here](https://prow.tidb.net/command-help?repo=pingcap%2Ftidb).

The pull request process is described [here](https://book.prow.tidb.net/#/workflows/pr)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/pingcap/tidb/blob/master/OWNERS)~~ [Defined2014,YangKeao]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
author_association: NONE
user: login: ti-chi-bot[bot]
created_at: 2025-05-29T03:27:01Z
body: [LGTM Timeline notifier]
---
Timeline:

- `2025-05-29 02:08:53.400478043 +0000 UTC m=+71154.462495648`: :ballot_box_with_check: agreed by [Defined2014](https://github.com/Defined2014).
- `2025-05-29 03:27:00.42665779 +0000 UTC m=+75841.488675410`: :ballot_box_with_check: agreed by [YangKeao](https://github.com/YangKeao).
author_association: NONE
user: login: ti-chi-bot
created_at: 2025-07-08T12:58:22Z
body: In response to a cherrypick label: new pull request created to branch `release-8.5`: #62302.
But this PR has conflicts, please resolve them!
author_association: MEMBER