SQLite - зернистость поплавка, нарушающая уникальные противопоказания? - PullRequest
0 голосов
/ 31 октября 2018

Я использую SQLite 3.25.2 для Windows, скачал последние скомпилированные двоичные файлы с официальной страницы 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

И столбец А уникален, поэтому имеет смысл напечатать сообщение «УНИКАЛЬНОЕ ограничение не выполнено: 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? Или я не правильно понимаю, что на самом деле означает «уникальный»?

1 Ответ

0 голосов
/ 15 июля 2019

С выпуском 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...