pingcap / pingcap/tidb

[expression] Vectorized FROM_DAYS can persist an out-of-range DATE that scalar evaluation rejects

Open
#70,116 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; default vectorized expression; default strict mode; MDL ON; one TiDB

**Steps**

Create a source with day numbers 3652424 and 3652425. Compare literal FROM_DAYS with column evaluation. Materialize both into nullable DATE tables, then insert FROM_DAYS(column) into a DATE PRIMARY KEY and compare with the literal insert. Verify the root Projection plan, year, null bit, statement terminal, rows, strict mode, MDL, and ADMIN CHECK.

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

Both scalar and vectorized paths return 9999-12-31 for 3652424 and NULL for 3652425. Nullable materialization stores NULL and a strict DATE primary-key insert rejects the overflow row.

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

Scalar evaluation returns NULL for 3652425. Vectorized column evaluation reports is-null false and year 10000. INSERT SELECT persists that value in a DATE PRIMARY KEY and returns success, while the literal path returns ERROR 1048 Column d cannot be null.

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

TiDB master 05b396fb66; default vectorized expression; default strict mode; MDL ON; one TiDB

Likely root cause and fix direction

**Likely root cause**

builtinFromDaysSig.evalTime calls TimeFromDays and rejects ret.Year greater than 9999. builtinFromDaysSig.vecEvalTime calls the same helper but stores the result directly. The missing caller-owned vector guard turns the scalar NULL terminal into an ordinary out-of-domain value before destination admission.

**Fix direction**

Apply the year-9999 check in vecEvalTime and SetNull for overflow rows. Add scalar/vector parity at 3652424 and 3652425 plus nullable and non-null INSERT SELECT conformance. Audit other scalar fixes for caller guards absent from vector twins.

Contributor guide

Open the contributing guide

Research direction

Start by locating builtinFromDaysSig.evalTime and vecEvalTime and inspect how both use TimeFromDays, comparing the scalar year check with vector result and null handling. Reproduce the 3652424 and 3652425 cases, then verify scalar/vector parity, nullable materialization, and strict nullable and non-null INSERT SELECT behavior, including rejection of the overflow row.

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
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.