pingcap / pingcap/tidb

[expression] TiDB can drop a DATE/DATETIME-distinct predicate and silently delete protected rows

Open
#70,130 0 comments 0 reactions 0 assignees View on GitHub
component/expression found-by-ai may-affects-7.5 may-affects-8.1 may-affects-8.5 severity/critical type/bug
Dominant language
Go
Stars
40.5k
Forks
6.2k
PR merge metrics
PR metrics pending

Description

## Bug Report

### 1. Minimal reproduce step (Required)

**Environment**

TiDB master 05b396fb66; default strict mode; MDL ON; one TiDB/PD/real TiKV; no injection

**Steps**

Create a DATETIME(6) table containing midnight, noon, and next-day witnesses. Compare DATE-then-DATETIME predicates, the reverse order, and a DATE_ADD(..., INTERVAL 0 SECOND) structural control. Record each individual predicate set, EXPLAIN, affected rows, warnings, surviving primary keys, and ADMIN CHECK TABLE. The exact SQL is in scaffolds/top-level/ai_native_cast_target_type_hash_wrong_delete_repro.sql.

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

Both predicates must survive. Only the midnight row satisfies the complete conjunction; the noon and next-day rows must remain regardless of predicate order.

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

Exact current master retained only CAST AS DATE in the first plan. DELETE succeeded with no warnings, affected the midnight and noon rows, and left only the next-day row. Reverse order and the structural control affected only the midnight row and preserved noon. ADMIN CHECK stayed green.

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

TiDB master 05b396fb66; default strict mode; MDL ON; one TiDB/PD/real TiKV; no injection

Likely root cause and fix direction

**Likely root cause**

ReHashCode encodes CAST identity as function name, argument hashes, and RetType.EvalType only. DATE and DATETIME both map to ETDatetime, even though one discards the time-of-day and the other preserves it. RemoveDupExprs treats the colliding full equality hashes as semantic identity and removes the later condition.

**Fix direction**

Include the complete equality-relevant CAST target FieldType in both normal and canonical expression keys, and keep HashCode, CanonicalHashCode, Equal, and Equals contracts aligned. At minimum, concrete type, precision, scale, charset, collation, flags, and enum/set elements require an explicit audit.

Contributor guide

Open the contributing guide

Research direction

Run scaffolds/top-level/ai_native_cast_target_type_hash_wrong_delete_repro.sql and compare the predicate plans, affected rows, warnings, and surviving keys. Then trace ReHashCode and RemoveDupExprs, including HashCode, CanonicalHashCode, Equal, and Equals, to understand the expression identity used for duplicate removal. Done means both predicates remain distinct and the repro preserves the noon and next-day rows.

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
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.