Skip to content

Commit df3309a

Browse files
committed
Fix SQLite compatibility for search-replace command
Two targeted fixes for SQLite compatibility: 1. Skip views detection on SQLite — the drop-in does not support SHOW FULL TABLES, and WordPress on SQLite does not use views 2. Fall back to PHP processing on SQLite for serialized data detection — SQLite lacks native REGEXP support All other MySQL queries (DESCRIBE, SHOW CREATE TABLE, LIKE BINARY) are left unchanged as the SQLite integration drop-in translates them automatically. Remove @skip-sqlite from 4 of 5 regex test scenarios. One scenario (Logging with regex replace) remains skipped due to a pre-existing difference in regex backreference behavior on SQLite. Fixes #190
1 parent 20351f6 commit df3309a

File tree

2 files changed

+22
-13
lines changed

2 files changed

+22
-13
lines changed

features/search-replace.feature

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,6 @@ Feature: Do global search/replace
222222
"""
223223

224224
# See https://github.com/wp-cli/search-replace-command/issues/190
225-
@skip-sqlite
226225
Scenario: Regex search/replace
227226
Given a WP install
228227
When I run `wp search-replace '(Hello)\s(world)' '$2, $1' --regex`
@@ -962,6 +961,8 @@ Feature: Do global search/replace
962961
And STDERR should be empty
963962

964963
# See https://github.com/wp-cli/search-replace-command/issues/190
964+
# SQLite: regex backreference replacement produces different results due to
965+
# LIKE case-sensitivity differences. Requires further investigation.
965966
@skip-sqlite
966967
Scenario: Logging with regex replace
967968
Given a WP install
@@ -1326,7 +1327,6 @@ Feature: Do global search/replace
13261327
"""
13271328

13281329
# See https://github.com/wp-cli/search-replace-command/issues/190
1329-
@skip-sqlite
13301330
Scenario: Regex search/replace with `--regex-limit=1` option
13311331
Given a WP install
13321332
And I run `wp post create --post_content="I have a pen, I have an apple. Pen, pine-apple, apple-pen."`
@@ -1338,7 +1338,6 @@ Feature: Do global search/replace
13381338
"""
13391339

13401340
# See https://github.com/wp-cli/search-replace-command/issues/190
1341-
@skip-sqlite
13421341
Scenario: Regex search/replace with `--regex-limit=2` option
13431342
Given a WP install
13441343
And I run `wp post create --post_content="I have a pen, I have an apple. Pen, pine-apple, apple-pen."`
@@ -1350,7 +1349,6 @@ Feature: Do global search/replace
13501349
"""
13511350

13521351
# See https://github.com/wp-cli/search-replace-command/issues/190
1353-
@skip-sqlite
13541352
Scenario: Regex search/replace with incorrect or default `--regex-limit`
13551353
Given a WP install
13561354
When I try `wp search-replace '(Hello)\s(world)' '$2, $1' --regex --regex-limit=asdf`

src/Search_Replace_Command.php

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -480,10 +480,16 @@ public function __invoke( $args, $assoc_args ) {
480480
$tables = Utils\wp_get_table_names( $args, $assoc_args );
481481

482482
// Identify views so they can be skipped; views are dynamic and cannot be directly modified.
483-
$views_args = $assoc_args;
484-
$views_args['views-only'] = true;
485-
$views = Utils\wp_get_table_names( [], $views_args );
486-
$view_set = array_flip( array_intersect( $views, $tables ) );
483+
// The SQLite integration drop-in does not support SHOW FULL TABLES and WordPress
484+
// on SQLite does not use views, so skip the views query entirely.
485+
if ( 'sqlite' === Utils\get_db_type() ) {
486+
$view_set = array();
487+
} else {
488+
$views_args = $assoc_args;
489+
$views_args['views-only'] = true;
490+
$views = Utils\wp_get_table_names( [], $views_args );
491+
$view_set = array_flip( array_intersect( $views, $tables ) );
492+
}
487493

488494
foreach ( $tables as $table ) {
489495
foreach ( $this->skip_tables as $skip_table ) {
@@ -555,12 +561,17 @@ public function __invoke( $args, $assoc_args ) {
555561
$col_sql = self::esc_sql_ident( $col );
556562
$wpdb->last_error = '';
557563

558-
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- escaped through self::esc_sql_ident
559-
$serial_row = $wpdb->get_row( "SELECT * FROM $table_sql WHERE $col_sql REGEXP '^[aiO]:[1-9]' LIMIT 1" );
560-
561-
// When the regex triggers an error, we should fall back to PHP
562-
if ( false !== strpos( $wpdb->last_error, 'ERROR 1139' ) ) {
564+
if ( 'sqlite' === Utils\get_db_type() ) {
565+
// SQLite does not support REGEXP by default, fall back to PHP processing.
563566
$serial_row = true;
567+
} else {
568+
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- escaped through self::esc_sql_ident
569+
$serial_row = $wpdb->get_row( "SELECT * FROM $table_sql WHERE $col_sql REGEXP '^[aiO]:[1-9]' LIMIT 1" );
570+
571+
// When the regex triggers an error, we should fall back to PHP
572+
if ( false !== strpos( $wpdb->last_error, 'ERROR 1139' ) ) {
573+
$serial_row = true;
574+
}
564575
}
565576
}
566577

0 commit comments

Comments
 (0)