pingcap / pingcap/tidb

Wrong result comparing a TIME column with a DATETIME column after SET TIMESTAMP

Open
#70,810 2 comments 0 reactions 0 assignees View on GitHub
contribution may-affects-25.10 may-affects-26.3 may-affects-7.5 may-affects-8.1 may-affects-8.5 severity/critical sig/execution type/bug
Dominant language
Go
Stars
40.5k
Forks
6.2k
PR merge metrics
PR metrics pending

Description

## Bug Report

Please answer these questions before submitting your issue. Thanks!

### 1. Minimal reproduce step (Required)

A cast that depends on the session statement timestamp is pushed down to TiKV, but the timestamp is not pushed down along with it.

```sql
mysql> set time_zone = '+00:00';
Query OK, 0 rows affected (0.000 sec)
mysql> set timestamp = 69006; -- 1970-01-01 19:10:06 UTC
Query OK, 0 rows affected (0.001 sec)

mysql> create table t(t time,dt datetime);
Query OK, 0 rows affected (0.033 sec)
mysql> insert into t values ('19:10:06', '1970-01-01 19:10:06');
Query OK, 1 row affected (0.005 sec)

mysql> select cast(t as datetime) from t;
+---------------------+
| cast(t as datetime) |
+---------------------+
| 1970-01-01 19:10:06 |
+---------------------+
1 row in set (0.001 sec)
```

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

`select count(*) from t where t = dt;` should return `1`.

```sql
mysql> select count(*) from t where t = dt;
+----------+
| count(*) |
+----------+
| 1 |
+----------+
1 row in set (0.006 sec)
```

On the TiDB side, `CAST(t AS DATETIME)` uses the session statement timestamp as the date part, producing `1970-01-01 19:10:06`, which equals `dt`.

```sql
mysql> select t,dt,t = dt from t;
+----------+---------------------+--------+
| t | dt | t = dt |
+----------+---------------------+--------+
| 19:10:06 | 1970-01-01 19:10:06 | 1 |
+----------+---------------------+--------+
1 row in set (0.002 sec)
```

### 3. What did you see instead (Required)

```sql
mysql> select count(*) from t where t = dt;
+----------+
| count(*) |
+----------+
| 0 |
+----------+
1 row in set (0.006 sec)
```

But it returns `0`.

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

```
Release Version: v9.0.0-beta.2.pre-2156-ga80e3356c4
Edition: Community
Git Commit Hash: a80e3356c4befd6c4f316586b0f8e1bd5d24eb1f
Git Branch: master
UTC Build Time: 2026-08-31 05:56:58
GoVersion: go1.25.12
Race Enabled: false
Check Table Before Drop: false
Store: tikv
Kernel Type: Classic
```

---

Suggested fix directions:

- Do not push down `CastDurationAsTime` (and other casts that depend on the statement timestamp) when the session `timestamp` variable has been explicitly modified.
- Or propagate the session statement timestamp to TiKV (e.g. add it to the `DAGRequest`) so TiKV uses the same `now` as TiDB.

Contributor guide

Open the contributing guide

Research direction

Start by tracing CastDurationAsTime and the CAST(t AS DATETIME) comparison through TiDB's pushdown path, then inspect how the DAGRequest reaches TiKV. Reproduce the case with SET TIMESTAMP and the supplied SQL statements. Done means the comparison returns 1 when the session timestamp is explicitly modified, without inconsistent TiDB and TiKV results.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, sql
Domain
databases, distributed-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.