Small. Fast. Reliable.
Choose any three.

## SQLite Release 3.23.1 On 2018-04-10

Prior changes from version 3.23.0 (2018-04-02):

1. Add the sqlite3_serialize() and sqlite3_deserialize() interfaces when the SQLITE_ENABLE_DESERIALIZE compile-time option is used.
2. Recognize TRUE and FALSE as constants. (For compatibility, if there exist columns named "true" or "false", then the identifiers refer to the columns rather than Boolean constants.)
3. Support operators IS TRUE, IS FALSE, IS NOT TRUE, and IS NOT FALSE.
4. Added the SQLITE_DBSTATUS_CACHE_SPILL option to sqlite3_db_status() for reporting the number of cache spills that have occurred.
5. The "alternate-form-2" flag ("!") on the built-in printf implementation now causes string substitutions to measure the width and precision in characters instead of bytes.
6. If the xColumn method in a virtual table implementation returns an error message using sqlite3_result_error() then give that error message preference over internally-generated messages.
7. Added the -A command-line option to the CLI to make it easier to manage SQLite Archive files.
8. Add support for INSERT OR REPLACE, INSERT OR IGNORE, and UPDATE OR REPLACE in the Zipfile virtual table.
9. Enhance the sqlite3changeset_apply() interface so that it is hardened against attacks from deliberately corrupted changeset objects.
10. Added the sqlite3_normalize() extension function.
11. Query optimizer enhancements:
    1. Improve the omit-left-join optimization so that it works in cases where the right-hand table is UNIQUE but not necessarily NOT NULL.
    2. Improve the push-down optimization so that it works for many LEFT JOINs.
    3. Add the LEFT JOIN strength reduction optimization that converts a LEFT JOIN into an ordinary JOIN if there exist terms in the WHERE clause that would prevent the extra all-NULL row of the LEFT JOIN from appearing in the output set.
    4. Avoid unnecessary writes to the sqlite_sequence table when an AUTOINCREMENT table is updated with an rowid that is less than the maximum.
12. Bug fixes:
    1. Fix the parser to accept valid row value syntax. Ticket 7310e2fb3d046a5
    2. Fix the query planner so that it takes into account dependencies in the arguments to table-valued functions in subexpressions in the WHERE clause. Ticket 80177f0c226ff54
    3. Fix incorrect result with complex OR-connected WHERE and STAT4. Ticket ec32177c99ccac2
    4. Fix potential corruption in indexes on expressions due to automatic datatype conversions. Ticket 343634942dd54ab
    5. Assertion fault in FTS4. Ticket d6ec09eccf68cfc
    6. Incorrect result on the less-than operator in row values. Ticket f484b65f3d62305
    7. Always interpret non-zero floating-point values as TRUE, even if the integer part is zero. Ticket 36fae083b450e3a
    8. Fix an issue in the fsdir(PATH) table-valued function to the fileio.c extension, that caused a segfault if the fsdir() table was used as the inner table of a join. Problem reported on the mailing list and fixed by check-in 7ce4e71c1b7251be
    9. Issue an error rather instead of an assertion-fault or null-pointer dereference when the sqlite_master table is corrupted so that the sqlite_sequence table root page is really a btree-index page. Check-in 525deb7a67fbd647
    10. Fix the ANALYZE command so that it computes statistics on tables whose names begin with "sqlite". Check-in 0249d9aecf69948d
13. Additional fixes for issues detected by OSSFuzz:
    1. Fix a possible infinite loop on VACUUM for corrupt database files. Check-in 27754b74ddf64
    2. Disallow parameters in the WITH clause of triggers and views. Check-in b918d4b4e546d
    3. Fix a potential memory leak in row value processing. Check-in 2df6bbf1b8ca8
    4. Improve the performance of the replace() SQL function for cases where there are many substitutions on megabyte-sized strings, in an attempt to avoid OSSFuzz timeouts during testing. Check-in fab2c2b07b5d3
    5. Provide an appropriate error message when the sqlite_master table contains a CREATE TABLE AS statement. Formerly this caused either an assertion fault or null pointer dereference. Problem found by OSSFuzz on the GDAL project. Check-in d75e67654aa96
    6. Incorrect assert() statement removed. Check-in 823779d31eb09cda.
    7. Fix a problem with using the LIKE optimization on an INTEGER PRIMARY KEY. Check-in b850dd159918af56.

Changes in this specific patch release, version 3.23.1 (2018-04-10):

1. Fix two problems in the new LEFT JOIN strength reduction optimization. Tickets 1e39b966ae9ee739 and fac496b61722daf2.
2. Fix misbehavior of the FTS5 xBestIndex method. Ticket 2b8aed9f7c9e61e8.
3. Fix a harmless reference to an uninitialized virtual machine register. Ticket 093420fc0eb7cba7.
4. Fix the CLI so that it builds with -DSQLITE_UNTESTABLE
5. Fix the eval.c extension so that it works with PRAGMA empty_result_callbacks=ON.
6. Fix the generate_series virtual table so that it correctly returns no rows if any of its constraints are NULL.
7. Performance enhancements in the parser.

   Hashes:

8. SQLITE_SOURCE_ID: "2018-04-10 17:39:29 4bb2294022060e61de7da5c227a69ccd846ba330e31626ebcd59a94efd148b3b"
9. SHA3-256 for sqlite3.c: 65750d1e506f416a0b0b9dd22d171379679c733e3460549754dc68c92705b5dc

A complete list of SQLite releases in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.