matrixorigin / matrixorigin/matrixone

[Compatibility]: ALLOW_INVALID_DATES is accepted but DATE and DATETIME remain strictly validated

Open
#28,602 1 comment 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

## Environment

- MatrixOne: `main` at `fc621e3616d229c7a29d0c80e73ed8eb1997459c`
- MySQL reference: 8.0.46
- Session time zone: `+00:00`

## Problem

MatrixOne accepts `ALLOW_INVALID_DATES` in `sql_mode`, but still rejects calendar-invalid `DATE` and `DATETIME` values such as `2024-02-30`. The mode does not change direct writes, updates, prepared parameters, or column defaults.

MySQL documents that [`ALLOW_INVALID_DATES`](https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html#sqlmode_allow_invalid_dates) permits month values 1-12 and day values 1-31 without checking the day against the actual number of days in the month. It applies to `DATE` and `DATETIME`, not `TIMESTAMP`.

## Minimal reproduction

```sql
SET SESSION sql_mode = 'STRICT_TRANS_TABLES,ALLOW_INVALID_DATES';

CREATE TABLE t(
id INT PRIMARY KEY,
d DATE,
dt DATETIME(6)
);

INSERT INTO t VALUES(
1,
'2024-02-30',
'2024-02-30 12:34:56.123456'
);

SELECT id, CAST(d AS CHAR), CAST(dt AS CHAR) FROM t;
```

MatrixOne returns:

```text
ERROR 20203: invalid argument parsedate, bad value 2024-02-30
```

MySQL 8.0.46 stores and returns:

```text
1 | 2024-02-30 | 2024-02-30 12:34:56.123456
```

Without `ALLOW_INVALID_DATES`, both systems reject the same row.

## Covered boundaries and paths

The behavior was checked with `2024-02-30`, non-leap `2023-02-29`, and `2024-04-31`.

- Direct `INSERT`, `UPDATE`, and SQL `PREPARE ... EXECUTE ... USING` parameters are accepted by MySQL under the mode and rejected by MatrixOne.
- MySQL accepts `DATE DEFAULT '2024-02-30'` and `DATETIME DEFAULT '2024-02-30 12:34:56'` under the mode; MatrixOne rejects the table definition.
- MySQL can subsequently evaluate `YEAR`, `MONTH`, `DAY`, `DAYOFMONTH`, `LAST_DAY`, `DATE_ADD`, and `DATEDIFF` over the stored value. MatrixOne has no equivalent stored-value path because every entry point rejects it.
- `2024-13-01` and `2024-01-32` are rejected by both systems even with the mode, confirming that the expected range is not arbitrary invalid input.
- A row containing an invalid `TIMESTAMP` is rejected by both systems, confirming MySQL's documented exclusion of `TIMESTAMP` from this mode.

## Code analysis

`pkg/frontend/variables.go` lists `ALLOW_INVALID_DATES` as a valid `sql_mode` token, but there are no consumers of this token outside that registration. `types.ParseDate` and `types.ParseDatetime` always validate the calendar date and do not receive session SQL mode information. DML binding, prepared execution, and default-value validation therefore cannot select the relaxed rule.

The behavior above was reproduced three times with fresh databases and connections. Each relaxed-mode case has a strict-mode control, and the out-of-range month/day plus `TIMESTAMP` controls prevent widening the expected behavior beyond MySQL's documented scope.

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.