matrixorigin / matrixorigin/matrixone
[Compatibility]: explicit_defaults_for_timestamp is accepted but ignored by TIMESTAMP DDL
- Dominant language
- Go
- Stars
- 1.9k
- Forks
- 311
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 768
Description
### Is there an existing issue for the same bug?
- [x] I have checked the existing issues, including open and closed issues.
### Branch Name
main
### Commit ID
fc621e3616d229c7a29d0c80e73ed8eb1997459c
### Other Environment Information
- MatrixOne: locally built from the commit above (`8.0.30-MatrixOne-v1.3.0`)
- MySQL baseline: 8.0.46
- Verification date: 2026-09-10
### Actual Behavior
MatrixOne exposes `explicit_defaults_for_timestamp` as a writable dynamic session/global variable, but setting it to `OFF` has no effect on TIMESTAMP column definition or write behavior.
With the setting `ON`, MatrixOne and MySQL both create an unconstrained `TIMESTAMP` column as nullable with a NULL default:
```sql
SET SESSION explicit_defaults_for_timestamp=ON;
CREATE TABLE t(id INT PRIMARY KEY, ts TIMESTAMP);
```
```text
ts TIMESTAMP NULL DEFAULT NULL
```
With the setting `OFF`, MySQL 8.0.46 applies its documented legacy implicit-first-TIMESTAMP behavior:
```text
ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
```
MatrixOne still creates:
```text
ts TIMESTAMP NULL DEFAULT NULL
```
The schema difference changes stored values:
- Omitting `ts` inserts the current timestamp in MySQL but NULL in MatrixOne.
- Explicitly inserting NULL into the implicit first TIMESTAMP stores the current timestamp in MySQL but NULL in MatrixOne.
- `TIMESTAMP NOT NULL` with no explicit default gains `DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP` under MySQL `OFF`, so an omitted value succeeds; MatrixOne keeps no default and rejects the same insert with `invalid default value for column 'ts'`.
- An explicitly nullable `TIMESTAMP NULL` remains nullable in both engines, which is the expected control.
`SELECT @@session.explicit_defaults_for_timestamp` correctly reports 0 after the MatrixOne assignment, so the variable is stored but ignored by DDL binding.
### Expected Behavior
When MatrixOne accepts `explicit_defaults_for_timestamp=OFF`, TIMESTAMP DDL and implicit write behavior should follow MySQL's corresponding compatibility rules. If the legacy mode is intentionally unsupported, the setting should not be exposed as a writable dynamic variable that silently has no effect.
### Steps to Reproduce
```sql
DROP DATABASE IF EXISTS explicit_timestamp_defaults;
CREATE DATABASE explicit_timestamp_defaults;
USE explicit_timestamp_defaults;
SET SESSION explicit_defaults_for_timestamp=OFF;
SELECT @@session.explicit_defaults_for_timestamp;
CREATE TABLE plain_t(
id INT PRIMARY KEY,
ts TIMESTAMP
);
SHOW CREATE TABLE plain_t;
INSERT INTO plain_t(id) VALUES(1);
INSERT INTO plain_t VALUES(2,NULL);
SELECT id,ts,ts IS NULL FROM plain_t ORDER BY id;
CREATE TABLE nullable_t(
id INT PRIMARY KEY,
ts TIMESTAMP NULL
);
SHOW CREATE TABLE nullable_t;
CREATE TABLE notnull_t(
id INT PRIMARY KEY,
ts TIMESTAMP NOT NULL
);
SHOW CREATE TABLE notnull_t;
INSERT INTO notnull_t(id) VALUES(1);
```
### Additional information
`pkg/frontend/variables.go` registers `explicit_defaults_for_timestamp` as a dynamic `ScopeBoth` Boolean with default 1. No production parser, binder, default-expression, or timestamp-column path reads the setting; the only other source occurrence is an error-message definition describing the MySQL option.
ON/OFF, unconstrained/explicit NULL/explicit NOT NULL column definitions, SHOW CREATE, omitted values, explicit NULL values, and post-create updates were reproduced three times on the same latest-main build and compared with MySQL 8.0.46. No existing issue for this variable was found.
Contributor guide
Assessment
This issue has not been assessed yet.