Spec-Zone.ru › SQLite

Переход с SQLite 3.5.9 на 3.6.0

Версия SQLite 3.6.0 (2008-07-16) содержит множество изменений. Как обычно для проекта SQLite, большинство изменений полностью совместимы с предыдущими версиями. Однако некоторые изменения в версии 3.6.0 несовместимы и могут потребовать модификаций кода приложения и/или файлов make. Этот документ содержит краткое описание изменений в SQLite 3.6.0, с особым вниманием к несовместимым изменениям.

Ключевые моменты:
  • Формат файла базы данных не изменен.
  • Все несовместимости связаны с малоиспользуемыми интерфейсами и, следовательно, не должны оказывать никакого влияния на большинство приложений.

1.0 Несовместимые изменения

Несовместимые изменения рассматриваются первыми, поскольку они наиболее важны для разработчиков и программистов.

1.1 Обзор несовместимых изменений

  1. Изменения в объекте sqlite3_vfs

    1. Подпись метода xAccess была изменена для возвращения кода ошибки и для хранения его результата в целое число, указанное параметром, вместо непосредственного возвращения результата. Это изменение позволяет методу xAccess() сообщать о сбоях. В связи с этим изменением подписи добавлен новый расширенный код ошибки SQLITE_IOERR_ACCESS.

    2. Метод xGetTempname был удален из sqlite3_vfs. Вместо него метод xOpen расширен для открытия временного файла собственного изобретения, когда параметр filename имеет значение NULL.

    3. Добавлен метод xGetLastError() в sqlite3_vfs для возвращения специфичных для файловой системы сообщений об ошибках и кодов ошибок обратно в SQLite.

  2. Подпись метода xCheckReservedLock в sqlite3_io_methods была изменена, так что она возвращает код ошибки и сохраняет логическое значение результата в целое число, указанное параметром. В связи с этим изменением добавлен новый расширенный код ошибки SQLITE_IOERR_CHECKRESERVEDLOCK.

  3. При переносе SQLite на новые операционные системы (операционные системы, отличные от Unix, Windows и OS/2, для которых предоставляются порты вместе с ядром) необходимо предоставить две новые функции, sqlite3_os_init() и sqlite3_os_end(), в качестве части порта.

  4. Способ, которым операторы IN и NOT IN обрабатывают значения NULL в правых выражениях, приведён в соответствие со стандартом SQL и с поведением других СУБД.

  5. Имена столбцов для наборов результатов операторов SELECT в некоторых случаях были изменены, чтобы быть более похожими на поведение других СУБД.

  6. Изменения в параметрах компиляции:

    1. Параметр компиляции SQLITE_MUTEX_APPDEF больше не распознается. В качестве замены могут быть созданы альтернативные реализации мьютексов во время выполнения с использованием sqlite3_config() с оператором SQLITE_CONFIG_MUTEX и объектом sqlite3_mutex_methods.

    2. Параметры компиляции OS_UNIX, OS_WIN, OS_OS2, OS_OTHER и TEMP_STORE были переименованы для добавления префикса "SQLITE_" для предотвращения коллизий имён с приложением. Новые имена этих параметров соответственно: SQLITE_OS_UNIX, SQLITE_OS_WIN, SQLITE_OS_OS2, SQLITE_OS_OTHER и SQLITE_TEMP_STORE.

1.2 Изменения в слое VFS

SQLite версия 3.5.0 представила новый слой интерфейса ОС, который предоставил абстракцию базовой операционной системы. Это было важным нововведением и оказалось полезным при переносе и поддержании SQLite. Однако разработчики обнаружили некоторые незначительные недостатки в первоначальном дизайне «виртуальной файловой системы», представленном в версии 3.5.0, и поэтому SQLite 3.6.0 включает некоторые небольшие несовместимые изменения для решения этих недостатков.

Ключевой момент: Несовместимые изменения в интерфейсе операционной системы SQLite для версии 3.6.0 затрагивают только редкие приложения, которые используют интерфейс виртуальной файловой системы или предоставляют реализацию мьютекса, определённую приложением, или используют другие малоиспользуемые параметры компиляции. Внесённые изменения в SQLite версии 3.6.0 не повлияют на подавляющее большинство приложений SQLite, которые используют встроенные интерфейсы для Unix, Windows и OS/2 и стандартную конфигурацию сборки.

1.3 Изменения в обработке NULL значений оператором IN

Все версии SQLite до версии 3.5.9 включительно неправильно обрабатывали значения NULL в правой части операторов IN и NOT IN. В частности, SQLite ранее игнорировало значения NULL в правой части операторов IN и NOT IN.

Предположим, у нас есть таблица X1, определённая следующим образом:

  CREATE TABLE x1(x INTEGER);
  INSERT INTO x1 VALUES(1);
  INSERT INTO x1 VALUES(2);
  INSERT INTO x1 VALUES(NULL);

Учитывая определение X1 выше, следующие выражения исторически оценивались как FALSE в SQLite, хотя правильный ответ — фактически NULL:

  3 IN (1,2,NULL)
  3 IN (SELECT * FROM x1)

Аналогично, следующие выражения исторически оценивались как TRUE, когда на самом деле правильным ответом является NULL:

  3 NOT IN (1,2,NULL)
  3 NOT IN (SELECT * FROM x1)

Историческое поведение SQLite некорректно согласно стандарту SQL:1999 и несовместимо с поведением MySQL и PostgreSQL. Версия 3.6.0 изменяет поведение операторов IN и NOT IN для соответствия стандарту и для получения тех же результатов, что и другие СУБД.

Ключевой момент: Изменение способа обработки значений NULL операторами IN и NOT IN технически является исправлением ошибки, а не изменением дизайна. Однако разработчики должны проверить, чтобы приложения не зависели от более старого, ошибочного поведения до обновления до версии 3.6.0.

1.4 Изменения в правилах именования столбцов

Имена столбцов, возвращаемых вложенными запросами JOIN, были немного изменены, чтобы быть более похожими на поведение других СУБД. Рассмотрим следующий запрос:

  CREATE TABLE t1(a);
  CREATE TABLE t2(x);
  SELECT * FROM (SELECT t1.a FROM t1 JOIN t2 ORDER BY t2.x LIMIT 1) ORDER BY 1;

В версии 3.5.9 указанный запрос возвращал бы один столбец под названием "t1.a". В версии 3.6.0 имя столбца просто "a".

SQLite никогда не давало гарантий относительно имён столбцов в наборе результатов оператора SELECT, если только столбец не содержал фразы AS. Поэтому это изменение имени столбца технически не является несовместимостью. SQLite просто переходит от одного неопределённого поведения к другому. Тем не менее, многие приложения зависят от неопределённого поведения SQLite в отношении именования столбцов, и поэтому это изменение обсуждается в подзаголовке несовместимых изменений.

1.5 Изменения в параметрах компиляции

Параметры компиляции SQLite управляются макросами препроцессора C. Версия SQLite 3.6.0 изменяет имена некоторых из этих макросов, чтобы все макросы препроцессора C, специфичные для SQLite, начинались с префикса "SQLITE_". Это делается для уменьшения риска конфликтов имён с другими модулями программного обеспечения.

Ключевой момент: Изменения в параметрах компиляции могут повлиять на файлы make в проектах, которые выполняют пользовательскую сборку SQLite. Эти изменения должны не оказывать никакого влияния на код приложения, и для большинства проектов, которые используют стандартную, по умолчанию сборку SQLite.

2.0 Полностью обратные совместимые улучшения

В дополнение к несовместимым изменениям, перечисленным выше, SQLite версии 3.6.0 добавляет следующие обратные совместимые изменения и улучшения:

  1. Новый интерфейс sqlite3_config() позволяет приложению настраивать поведение SQLite во время выполнения. Настройки, возможные с помощью sqlite3_config(), включают:

    1. Укажите альтернативную реализацию мьютекса с помощью глагола SQLITE_CONFIG_MUTEX с объектом sqlite3_mutex_methods.

    2. Укажите альтернативную реализацию malloc с помощью глагола SQLITE_CONFIG_MALLOC с объектом sqlite3_mem_methods.

    3. Частично или полностью отключить использование мьютексов с помощью SQLITE_CONFIG_SINGLETHREAD, SQLITE_CONFIG_MULTITHREAD и SQLITE_CONFIG_SERIALIZED.

  2. Новый флаг SQLITE_OPEN_NOMUTEX доступен для интерфейса sqlite3_open_v2().

  3. Новый интерфейс sqlite3_status() позволяет приложению запросить состояние производительности SQLite во время выполнения.

  4. Интерфейсы sqlite3_memory_used() и sqlite3_memory_highwater() устарели. Эквивалентная функциональность теперь доступна через sqlite3_status().

  5. Интерфейс sqlite3_initialize() может быть вызван для явной инициализации подсистемы SQLite. Интерфейс sqlite3_initialize() вызывается автоматически при вызове определённых интерфейсов, поэтому использование sqlite3_initialize() не обязательно, но рекомендуется.

  6. Интерфейс sqlite3_shutdown() заставляет SQLite освободить все системные ресурсы (выделения памяти, мьютексы, открытые дескрипторы файлов), которые могли быть выделены с помощью sqlite3_initialize().

  7. Интерфейс sqlite3_next_stmt() позволяет приложению обнаружить все подготовленные операторы, связанные с соединением с базой данных.

  8. Добавлен PRAGMA page_count для возврата размера файла базы данных в страницах.

  9. Добавлен новый расширение индекса R*Tree.

Эта страница была изменена в последний раз 2022-01-08 05:02:57 UTC

SQLite is in the Public Domain.
https://sqlite.org/35to36.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API