在 OceanBase MySQL 模式下,业务表中某个
DATETIME NOT NULL字段保存了零时间值
0000-00-00 00:00:00。执行
IS NULL条件查询时,发现该行会被查出来,表现上像是被当成了 NULL。
示例:
CREATE TABLE t1date( c1 INT, c2 DATETIME NOT NULL ); INSERT IGNORE INTO t1date VALUES (1, '0000-00-00 00:00:00'); INSERT IGNORE INTO t1date VALUES (2, '2025-11-01 12:20:00'); SELECT * FROM t1date WHERE c2 IS NULL;
查询结果:
1 0000-00-00 00:00:00
第 1 行会命中,第 2 行不会命中。
该行为主要出现在以下条件同时满足时:
✅租户为 MySQL 模式
✅列类型为 DATE / DATETIME
✅列属性为 NOT NULL
✅SQL 条件中使用了 WHERE col IS NULL
这不是存储层把 0000-00-00 00:00:00 真正存成了 NULL,而是 SQL 解析阶段做了兼容性改写。
在 OB 的 DML Resolver 中,对于 NOT NULL 的时间类型列,如果 SQL 中写的是:
col IS NULL会被改写为类似:
col IS NULL OR col = '0000-00-00 00:00:00'
因此,虽然字段值本身不是 NULL,但在 WHERE ... IS NULL 的过滤逻辑中,零时间会被一并匹配出来。
这个行为主要是 谓词过滤场景下的改写,不代表零时间在系统内部被当成真正的 NULL 值。
也就是说:
● 0000-00-00 00:00:00 仍然是一个特殊的零时间值
● 但在 WHERE c2 IS NULL 这类条件里,OB 为兼容性会把它纳入结果集
常见原因包括:
例如:
INSERT IGNORE INTO t1date VALUES (1, '0000-00-00 00:00:00');
该语句不会报错,而是插入零时间。
在 OceanBase MySQL 模式下,
DATETIME NOT NULL 字段上的
IS NULL谓词存在兼容性改写逻辑。
对于零时间值 0000-00-00 00:00:00,OB 会在条件过滤阶段将其视作 IS NULL 的匹配对象之一,因此出现 零时间被 IS NULL 查询命中的现象。属于 SQL 解析层的兼容行为,并非存储层将零时间物理转换为 NULL。
如果你在实际操作中遇到问题,可以在评论区留言交流。后续我们会持续分享更多运维干货,记得 关注不迷路 ,下次见~
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70047467/viewspace-3171836/ ,如需转载,请注明出处,否则将追究法律责任。