pingcap / pingcap/tidb

[expression] Vectorized CONVERT_TZ can silently overwrite rows from incomplete dates under default strict mode

Open
#70,123 1 comment 0 reactions 0 assignees View on GitHub
affects-7.5 affects-8.1 affects-8.5 component/expression found-by-ai 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; TiKV 730be34f; default vector ON; global strict mode; MDL ON; one TiDB/PD/TiKV; no injection

**Steps**

Create a DATE source under permissive sql_mode with 2024-00-15, 2024-01-00, and 2024-01-15. Seed scalar and vector destination copies with valid timestamps and payloads. Restore the global default strict sql_mode. Run identical REPLACE INTO dst SELECT id,CONVERT_TZ(d,+00:00,+08:00),new with tidb_enable_vectorized_expression OFF and ON in separate sessions. Compare terminals and full destination rows.

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

Scalar and vectorized evaluation preserve the same invalid-time warning policy. Under default strict DML both statements return 1292 and preserve every seeded destination preimage.

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

Scalar execution returns 1292 on 2024-00-15 and preserves all three rows. Default vectorized execution returns success; rows 1 and 2 become NULL/new and row 3 becomes 2024-01-15 08:00:00/new. Two existing valid timestamp and payload preimages are silently lost.

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

TiDB master 05b396fb66; TiKV 730be34f; default vector ON; global strict mode; MDL ON; one TiDB/PD/TiKV; no injection

Likely root cause and fix direction

**Likely root cause**

builtinConvertTzSig.evalTime rejects Time.InvalidZero through handleInvalidTimeError. builtinConvertTzSig.vecEvalTime directly calls convertTz, which returns NULL for the same incomplete values without appending the warning. The missing warning crosses the default strict-DML boundary and changes statement abort into commit.

**Fix direction**

Copy the scalar InvalidZero plus handleInvalidTimeError branch into vecEvalTime before convertTz. Add scalar/vector parity for value, NULL, warnings, and strict INSERT/REPLACE terminals over incomplete month/day values.

Contributor guide

Open the contributing guide

Research direction

Start by comparing builtinConvertTzSig.evalTime with builtinConvertTzSig.vecEvalTime and reproduce the scalar/vectorized CONVERT_TZ cases described in the issue under strict DML. Verify that incomplete month/day values produce matching values, NULL results, warnings, and INSERT/REPLACE outcomes; done means vectorized execution preserves the same destination rows and error behavior as scalar execution.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, mysql
Domain
database
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.