matrixorigin / matrixorigin/matrixone

[Bug]: nonexistent DST local times are silently normalized to different instants

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

Description

## 现象

MatrixOne `main`(`ac660ae56ecd37bab3dd8c61193617a323377029`)将 DST 春季跳时区间内不存在的本地时间交给 Go `time.Date` 归一化,得到与 MySQL 不同的瞬时;写入 `TIMESTAMP` 时还会在严格模式下静默接受并改变输入值。

### `TIMESTAMP` 写入

```sql
SET time_zone = 'America/New_York';
SET sql_mode = 'STRICT_TRANS_TABLES';
CREATE TABLE t(id INT PRIMARY KEY, ts TIMESTAMP(6));
INSERT INTO t VALUES (1, '2024-03-10 02:30:00.123456');
SELECT CAST(ts AS CHAR), UNIX_TIMESTAMP(ts) FROM t;
```

- MatrixOne:写入成功且无 warning,读回 `2024-03-10 01:30:00.123456 / 1710052200.123456`。
- MySQL 8.0.46:错误 1292,拒绝不存在的本地时间。

在空 `sql_mode` 下,MatrixOne 仍无 warning 并读回 `01:30:00.123456`;MySQL 给出 warning 1299,并规范化到 DST 转换边界 `03:00:00.123456 / 1710054000.123456`。

### `CONVERT_TZ`

```sql
SELECT CONVERT_TZ('2024-03-10 02:30:00', 'America/New_York', 'UTC');
SELECT CONVERT_TZ('2024-03-31 02:30:00', 'Europe/Berlin', 'UTC');
SELECT CONVERT_TZ('2024-10-06 02:15:00', 'Australia/Lord_Howe', 'UTC');
```

```text
MatrixOne MySQL 8.0.46
America/New_York 2024-03-10 06:30:00 2024-03-10 07:00:00
Europe/Berlin 2024-03-31 01:30:00 2024-03-31 01:00:00
Australia/Lord_Howe 2024-10-05 15:45:00 2024-10-05 15:30:00
```

跳时前、跳时后和秋季重复小时的控制值在两端映射到相同瞬时,问题限定在春季不存在的本地时间区间。

## 期望

- 严格模式写入不存在的 `TIMESTAMP` 本地时间时应拒绝该值。
- 非严格模式应产生 warning,并使用与 MySQL 相同的 DST 转换边界。
- `CONVERT_TZ` 对 DST gap 中的本地时间应采用与 MySQL 一致的边界映射,不能因 Go 运行时的地区特定归一化规则得到另一个瞬时。

## 代码定位

`pkg/container/types/timestamp.go` 的 `ParseTimestamp` 调用 `Datetime.ToTimestamp(loc)`;`pkg/container/types/datetime.go` 的 `ToTimestamp` 经 `ConvertToGoTime` 直接调用 `time.Date(..., loc)`,没有检测构造后的年月日时分秒是否仍等于输入。`CONVERT_TZ` 也通过同一个 `ConvertToGoTime(fromLoc)` 路径处理源本地时间。因此 DST gap 被 Go 自动归一化且没有进入 SQL mode/warning 处理。

## 复现信息

- MatrixOne main:`ac660ae56ecd37bab3dd8c61193617a323377029`
- MySQL:8.0.46(已加载系统时区表)
- America/New_York、Europe/Berlin、Australia/Lord_Howe 三种 gap 及严格/非严格写入重复执行 3 次,结果一致

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.