Skip to content

Commit ea10464

Browse files
authored
Introduce an unsafe flag for using the new driver with SQLite < 3.37.0 (#256)
WIP open for feedback and the flag name for discussion. I came to the conclusion that a special flag with the word `UNSAFE` might be the best solution here. By default, the new driver would still throw the following error: > The SQLite version 3.27.2 is not supported. Minimum required version is 3.37.0. But with the new flag, it could enable accessing a database created with 3.37.0 on older SQLite versions. **An important consideration or TODO:** In this form, it would serve a basic use case, which is opening an existing database on an older SQLite for previews, including writing data to the database. However, any new `CREATE TABLE` statement would fail because of the use of the `STRICT` keyword (`General error: 1 near "STRICT": syntax error`). We could address that by omitting that keyword in this mode, but maybe let's first determine whether there are use cases for it. Resolves #252.
1 parent 488b8db commit ea10464

File tree

1 file changed

+42
-7
lines changed

1 file changed

+42
-7
lines changed

wp-includes/sqlite-ast/class-wp-sqlite-driver.php

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -483,13 +483,48 @@ public function __construct( WP_SQLite_Connection $connection, string $database
483483
// Check the SQLite version.
484484
$sqlite_version = $this->get_sqlite_version();
485485
if ( version_compare( $sqlite_version, self::MINIMUM_SQLITE_VERSION, '<' ) ) {
486-
throw $this->new_driver_exception(
487-
sprintf(
488-
'The SQLite version %s is not supported. Minimum required version is %s.',
489-
$sqlite_version,
490-
self::MINIMUM_SQLITE_VERSION
491-
)
492-
);
486+
if ( defined( 'WP_SQLITE_UNSAFE_ENABLE_UNSUPPORTED_VERSIONS' ) && WP_SQLITE_UNSAFE_ENABLE_UNSUPPORTED_VERSIONS ) {
487+
// When "WP_SQLITE_UNSAFE_ENABLE_UNSUPPORTED_VERSIONS" is enabled,
488+
// allow using legacy SQLite versions, but not older than 3.27.0.
489+
if ( version_compare( $sqlite_version, '3.27.0', '<' ) ) {
490+
throw $this->new_driver_exception(
491+
sprintf(
492+
'The SQLite version %s is not supported. Minimum required version is %s.'
493+
. ' With "WP_SQLITE_UNSAFE_ENABLE_UNSUPPORTED_VERSIONS" enabled, you must use 3.27.0 or newer.',
494+
$sqlite_version,
495+
self::MINIMUM_SQLITE_VERSION
496+
)
497+
);
498+
}
499+
500+
/*
501+
* SQLite versions prior to 3.37.0 do not support STRICT tables.
502+
*
503+
* However, a database created with SQLite >= 3.37.0 can be used
504+
* with SQLite versions < 3.37.0 when "PRAGMA writable_schema" is
505+
* set to "ON", which also enables error-tolerant schema parsing.
506+
*
507+
* This is an unsafe opt-in feature for special back compatibility
508+
* use cases, as it can corrupt the database by allowing incorrect
509+
* types into STRICT tables. Additionally, depending on the legacy
510+
* SQLite version used, there is no guarantee that all features of
511+
* the SQLite driver will work as expected. Use this with caution.
512+
*
513+
* See: https://www.sqlite.org/stricttables.html#accessing_strict_tables_in_earlier_versions_of_sqlite
514+
*
515+
* TODO: Remove this flag when we drop support for PHP 8.0.
516+
* From PHP 8.1, SQLite 3.46.1 is used by default.
517+
*/
518+
$this->execute_sqlite_query( 'PRAGMA writable_schema=ON' );
519+
} else {
520+
throw $this->new_driver_exception(
521+
sprintf(
522+
'The SQLite version %s is not supported. Minimum required version is %s.',
523+
$sqlite_version,
524+
self::MINIMUM_SQLITE_VERSION
525+
)
526+
);
527+
}
493528
}
494529

495530
// Load SQLite version to a property used by WordPress health info.

0 commit comments

Comments
 (0)