Small. Fast. Reliable.
Choose any three.

从SQLite 3.5.9迁移到3.6.0

SQLite版本3.6.0(2008-07-16)包含许多更改。与SQLite项目的习惯一样,大多数更改是完全向后兼容的。但是,版本3.6.0中的一些更改不兼容,可能需要修改应用程序代码和/或makefile。本文档简要介绍了SQLite 3.6.0中的更改,并特别注意了不兼容的更改。

关键点:

1.0不兼容的更改

首先讨论不兼容的更改,因为它们对于维护者和程序员而言最重要。

1.1不兼容更改概述

  1. sqlite3_vfs对象的更改

    1. 已修改xAccess方法的签名,以返回错误代码并将其输出存储到参数所指向的整数中,而不是直接返回输出。此更改使xAccess()方法可以报告失败。与此签名更改相关联,添加了新的扩展错误代码SQLITE_IOERR_ACCESS

    2. xGetTempname方法已从sqlite3_vfs中删除。取而代之的是,当filename参数为NULL时,增强了xOpen方法以打开其自己的发明的临时文件。

    3. sqlite3_vfs添加了xGetLastError()方法,用于将特定于文件系统的错误消息和错误代码返回给SQLite。

  2. sqlite3_io_methods 上xCheckReservedLock方法的签名已被修改,以便它返回错误代码并将其布尔结果存储到参数所指向的整数中。与此更改相关联,添加了新的扩展错误代码 SQLITE_IOERR_CHECKRESERVEDLOCK

  3. 当将SQLite移植到新的操作系统(与内核一起提供端口的Unix,Windows和OS / 2以外的其他操作系统)时,必须提供两个新函数sqlite3_os_init()sqlite3_os_end()作为其中的一部分。港口。

  4. IN和NOT IN运算符在其右手表达式中处理NULL值的方式已与SQL标准和其他SQL数据库引擎兼容。

  5. 在某些情况下,已经对SELECT语句的结果集的列名进行了调整,使其更像其他SQL数据库引擎一样工作。

  6. 更改编译时选项:

    1. 不再识别SQLITE_MUTEX_APPDEF编译时参数。作为替代,可以在运行时使用带有SQLITE_CONFIG_MUTEX 运算符和sqlite3_mutex_methods对象的sqlite3_config()创建替代的 互斥锁实现

    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引入了新的OS接口层,该提供了底层操作系统的抽象。这是一项重要的创新,已证明对移植和维护SQLite很有帮助。但是,开发人员在3.5.0版中引入的原始“虚拟文件系统”设计中发现了一些小缺陷,因此SQLite 3.6.0包含一些小的不兼容更改来解决这些缺陷。

重点: 版本3.6.0的SQLite操作系统接口中的不兼容更改仅影响使用虚拟文件系统接口或提供应用程序定义的互斥体实现 或使用其他晦涩的编译功能的罕见应用 程序-时间选项。SQLite 3.6.0版引入的更改将对绝大多数使用Unix,Windows和OS / 2内置接口并使用标准构建配置的SQLite应用程序产生零影响。

1.3 IN运算符处理NULL方式的更改

包括3.5.9在内的所有SQLite版本在IN和NOT IN运算符的右侧都有错误处理的NULL值。具体来说,SQLite以前忽略了IN和NOT IN右侧的NULL。

假设我们有一个表X1定义如下:

  创建表x1(x INTEGER);
  插入x1值(1);
  插入x1值(2);
  插入x1值(NULL);

给定上面X1的定义,以下表达式历来在SQLite中被评估为FALSE,尽管正确的答案实际上是NULL:

  3英寸(1,2,NULL)
  3英寸(SELECT * FROM x1)

类似地,以下表达式历来被评估为TRUE,而实际上NULL也是此处的正确答案:

  3 NOT IN(1,2,NULL)
  3 NOT IN(选择*来自x1)

根据SQL:1999标准,SQLite的历史行为是错误的,并且与MySQL和PostgreSQL的行为不一致。版本3.6.0更改了IN和NOT IN运算符的行为,以符合标准并提供与其他SQL数据库引擎相同的结果。

关键点:更改IN和NOT IN运算符处理NULL值的方式从技术上来说是一个错误修复,而不是设计更改。但是,维护人员应检查以确保应用程序在升级到3.6.0版之前不依赖较旧的错误行为。

1.4列命名规则的更改

联接子查询报告的列名已稍作修改,以便更像其他数据库引擎一样工作。考虑以下查询:

  创建表t1(a);
  创建表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”。

除非列包含AS子句,否则 SQLite从未对SELECT语句的结果集中的列名称作出任何保证。因此,从技术上来讲,对列名的更改不是兼容性。SQLite只是从一种未定义的行为变为另一种。但是,许多应用程序依赖于SQLite的未指定列命名行为,因此,在不兼容的更改子标题下讨论了此更改。

1.5编译时选项的更改

SQLite的编译时选项由C预处理器宏控制。SQLite版本3.6.0更改了其中一些宏的名称,以便所有特定于SQLite的C预处理器宏均以“ SQLITE_”前缀开头。这样做是为了减少与其他软件模块发生名称冲突的风险。

关键点: 更改编译时选项可能会影响执行定制SQLite构建的项目中的makefile。这些更改将对应用程序代码以及大多数使用标准默认SQLite构建的项目产生零影响。

2.0完全向后兼容的增强功能

除了上面列出的不兼容更改之外,SQLite 3.6.0版还添加了以下向后兼容的更改和增强功能:

  1. 新的sqlite3_config()接口允许应用程序在运行时自定义SQLite的行为。使用sqlite3_config()可能进行的自定义包括以下内容:

    1. 通过将SQLITE_CONFIG_MUTEX动词与sqlite3_mutex_methods对象一起使用,指定备用互斥量实现 。

    2. 使用带有sqlite3_mem_methods对象的SQLITE_CONFIG_MALLOC动词来指定替代的malloc实现 。

    3. 使用SQLITE_CONFIG_SINGLETHREADSQLITE_CONFIG_MULTITHREADSQLITE_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. 添加了page_count PRAGMA,用于返回页面中基础数据库文件的大小。

  9. 添加了新的R * Tree索引扩展