pingcap / pingcap/tidb

TiDB changes TIME values when a UNION prefix crosses a CTE or derived-table boundary

Open
#70,634 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
TiDB returns different values for relationally equivalent `UNION ALL` queries
when the first two branches are represented by a CTE or derived table. A
`TIME` value is converted to `DATETIME` and receives the current date at the
materialization boundary.

### 1. Minimal reproduce step (Required)

Run the flat form:

```sql
SELECT TIME('03:04:05') AS v
UNION ALL
SELECT CAST('2024-01-01' AS DATETIME)
UNION ALL
SELECT 1;
```

Observed result on TiDB:

```text
03:04:05
2024-01-01 00:00:00
1
```

Now materialize the first two branches:

```sql
WITH cut AS (
SELECT TIME('03:04:05') AS v
UNION ALL
SELECT CAST('2024-01-01' AS DATETIME)
)
SELECT v FROM cut
UNION ALL
SELECT 1;
```

The first row becomes (the date is the server's current date):

```text
2026-08-24 03:04:05
```

The equivalent derived-table form has the same result:

```sql
SELECT v
FROM (
SELECT TIME('03:04:05') AS v
UNION ALL
SELECT CAST('2024-01-01' AS DATETIME)
) AS cut
UNION ALL
SELECT 1;
```

The final protocol metadata is `MYSQL_TYPE_VAR_STRING` in both forms; the
value itself changes, so this is not merely a metadata display difference.

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

Both query forms should return the same three values. A relational boundary
must not inject the current date into a `TIME` value.

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

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

```text
DBMS: 8.0.11-TiDB-v8.5.7
Endpoint: 127.0.0.1:4000
Test date: 2026-08-24
TiDB version (SELECT tidb_version()):
Release Version: v8.5.7
Edition: Community
Git Commit Hash: 202b7f47286a1109b5c957401d34c9358d130ae0
Git Branch: HEAD
UTC Build Time: 2026-07-15 02:06:00
GoVersion: go1.25.10
Race Enabled: false
Check Table Before Drop: false
Store: unistore
```

Contributor guide

Open the contributing guide

Research direction

Start by running the flat, CTE, and derived-table SQL queries in the report and compare their TIME results and protocol metadata. Trace the UNION ALL type handling across the CTE or derived-table materialization boundary, then add a regression test showing that all equivalent forms preserve the TIME value without injecting the current date.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, sql
Domain
databases
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.