matrixorigin / matrixorigin/matrixone

[Compatibility]: VARCHAR-to-TIME conversion ignores non-strict warning semantics

Open
#28,497 0 comments 0 reactions 1 assignee Claimed by @jiangxinmeng1 View on GitHub
area/compatibility kind/bug needs-triage
Dominant language
Go
Stars
1.9k
Forks
311
Avg merge
1d 3h
Merged PRs (30d)
768

Description

## Problem

With `sql_mode=''`, MatrixOne treats malformed or trailing-content `VARCHAR` to `TIME` conversions as statement errors. MySQL 8.3 applies its non-strict conversion semantics instead: it keeps a valid time prefix when present, returns `NULL`/zero-time where appropriate, and emits a warning.

This is a shared conversion-path difference rather than a `TIME_TO_SEC`-specific problem. It affects direct casts, functions that implicitly request a time value, table scans, prepared statements, assignments, and CTAS.

Tested on MatrixOne `main` commit `f0c31cd4b830be32442cf329e0a3fb08aa9c16c3` and MySQL 8.3.0. Each MatrixOne reproduction was repeated three times.

## Minimal reproduction

```sql
SET SESSION sql_mode='';

SELECT CAST('01:02:03.456789tail' AS TIME(6));
SELECT CAST('tail' AS TIME(6));
SELECT TIME_TO_SEC('01:02:03tail');
```

MatrixOne returns error 20301 (`invalid time value ...`) for all three statements.

MySQL returns:

```text
01:02:03.456789 -- warning 1292
NULL -- warning 1292
3723 -- warning 1292
```

## Row and persistence scenarios

```sql
CREATE TABLE src(id INT, s VARCHAR(64));
INSERT INTO src VALUES
(1, '01:02:03.456789'),
(2, '01:02:03.456789tail'),
(3, 'tail'),
(4, ''),
(5, NULL);

SELECT id, CAST(s AS TIME(6)) FROM src ORDER BY id;
CREATE TABLE copied AS
SELECT id, CAST(s AS TIME(6)) AS t FROM src;

CREATE TABLE assigned(id INT, t TIME(6));
INSERT INTO assigned VALUES (1, '01:02:03.456789tail');
INSERT INTO assigned VALUES (2, 'tail');
```

MatrixOne aborts the mixed-row SELECT and CTAS on the first trailing value. The two non-strict INSERT statements also return error 20301 and persist no rows.

MySQL completes the SELECT/CTAS with the valid prefix preserved and malformed values converted to `NULL`, emitting warnings. Its assignment path stores `01:02:03.456789` for the trailing input and `00:00:00.000000` for the invalid input, with warning 1265.

The same difference is present when the input is supplied through a prepared-statement parameter.

## Controls

- Valid `TIME(6)` strings preserve microseconds in both systems.
- `NULL` remains `NULL` in both systems.
- Filtering the table to the valid row allows MatrixOne to complete the cast correctly.
- MatrixOne remains healthy after each error.

## Code analysis

`pkg/sql/plan/function/func_cast.go`, `strToTime`, calls `types.ParseTime`. When parsing fails, only assignment-mode compact-time and out-of-range cases enter a MySQL-compatible fallback. Other malformed/trailing strings return the parse error directly; expression casts have no non-strict warning/nullification path.

The conversion layer therefore does not implement the session's non-strict semantics consistently across expression and assignment modes.

## Expected behavior

When strict SQL mode is disabled, string-to-`TIME` conversion should use consistent non-strict coercion semantics across direct casts, implicit function conversion, prepared statements, INSERT, and CTAS, with warnings rather than aborting the statement. Strict mode can continue to reject invalid assignment values where required.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.