sqlite - SQLite - 浮动粒度打破了独特的约束?
问题描述
我在 Windows 上使用 SQLite 3.25.2,从官方页面https://sqlite.org/download.html下载了最新的预编译二进制文件
执行以下代码
DROP TABLE IF EXISTS TestReal;
CREATE TABLE TestReal(A REAL UNIQUE);
INSERT INTO TestReal values (9223372036854775807.0);
INSERT INTO TestReal values (9223372036854775807.0 - 1);
INSERT INTO TestReal values (9223372036854775807.0 - 2);
INSERT INTO TestReal values (9223372036854775807.0 - 3);
正如预期的那样失败,因为 9223372036854775807.0 是 2^63,这些数字超出了所有整数都可以精确表示为双精度数的范围。我是说
sqlite> select 9223372036854775807.0 = 9223372036854775807.0 - 1;
1
sqlite> select 9223372036854775807.0 = 9223372036854775807.0 - 512;
1
A 列是唯一的,因此打印“UNIQUE 约束失败:TestReal.A”消息非常有意义。但似乎有一个意想不到的解决方法
DROP TABLE IF EXISTS TestReal;
CREATE TABLE TestReal(A REAL UNIQUE);
INSERT INTO TestReal values (9223372036854775807);
INSERT INTO TestReal values (9223372036854775807 - 1);
INSERT INTO TestReal values (9223372036854775807 - 2);
INSERT INTO TestReal values (9223372036854775807 - 3);
运行没有任何问题。以下查询确认该表现在恰好插入了 4 个值,但只有一个不同的值,尽管具有唯一约束
sqlite> SELECT * FROM TestReal;
9.22337203685478e+18
9.22337203685478e+18
9.22337203685478e+18
9.22337203685478e+18
sqlite> SELECT DISTINCT(A) FROM TestReal;
9.22337203685478e+18
sqlite> .schema
CREATE TABLE TestReal(A REAL UNIQUE);
所以我的问题是:这是 SQLite 中的错误吗?还是我没有正确理解“独特”的实际含义?
解决方案
随着 SQLite 3.29.0 的发布,它解决了,这从来都不是预期的行为,而是一个错误。该错误仍然存在于 3.28.0 中,但不在 3.29.0 中,在最新版本中,我的两个代码片段都按预期失败。
这是包含修复的提交: https ://www.sqlite.org/src/info/9b0915272f4d4052
我通过在 3.28.0 源代码上手动应用此提交并替换MEM_IntReal
为(MEM_Int | MEM_Real)
.
在官方 SQLite 邮件列表中报告可能的错误后打开错误票证: https ://www.mail-archive.com/sqlite-users@mailinglists.sqlite.org/msg115214.html
我也报告了它,实际上早一点,但我的报告并没有引起太多关注: https ://www.mail-archive.com/sqlite-users@mailinglists.sqlite.org/msg112655.html
推荐阅读
- node.js - npm install serialport 需要VS吗?
- git - 从 Azure DevOps Pipeline 提交到 Git Repo 时文件夹重复
- java - Angular 和 ADFS
- jmeter-plugins - MAVEN JMETER:无法生成仪表板结果
- matlab - 如何访问包含结构的已加载文件中的特定行和列?
- uwp - Webview 控件的高度有限制吗?
- node.js - Express:cors 配置是否依赖于服务器 TTL?
- java - OAuth2 WebSecurityConfigurerAdapter 规则有什么意义,因为它没有优先于 ResourceServerConfigurerAdapter
- java - 使用 Drools 规则进行实体验证
- swift - TabBarController 与 ScrollView