Fix SQLite compatibility for search-replace command#225
Fix SQLite compatibility for search-replace command#225dr5hn wants to merge 1 commit intowp-cli:mainfrom
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces SQLite support for the search-replace command by implementing database-specific logic for schema retrieval and string matching. Feedback suggests enabling case-sensitive LIKE for SQLite to ensure dry-run accuracy and refactoring the column metadata logic to reduce code duplication.
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Improves wp search-replace compatibility with SQLite (via the WordPress SQLite integration plugin) by replacing MySQL-specific SQL with SQLite-safe alternatives and enabling previously skipped SQLite scenarios.
Changes:
- Replace
SHOW CREATE TABLEwithsqlite_masterlookup when exporting on SQLite. - Avoid MySQL-only
REGEXP/LIKE BINARYusage by routing SQLite through PHP processing and introducing a DB-awarelike_operator(). - Update Behat feature coverage by removing
@skip-sqlitetags from regex scenarios.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/Search_Replace_Command.php | Adds SQLite-specific SQL branches (schema export, column introspection) and DB-aware LIKE operator handling. |
| features/search-replace.feature | Re-enables regex scenarios on SQLite by removing @skip-sqlite tags. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
|
Are these queries something the SQLite integration drop-in could handle for us? |
Codecov coverage noteThe 11 uncovered lines are all SQLite-specific code paths (gated behind These lines are tested by the 18 SQLite test matrix jobs (PHP 7.2–nightly, WP latest + trunk, Linux/macOS/Windows). The patch coverage gap is a known limitation of the coverage setup, not a testing gap. |
|
@swissspidy Good question, I think some of these could absolutely live in the drop-in, but not all of them cleanly.
Happy to open issues on WordPress/sqlite-database-integration for the ones that make sense there. This PR works as-is and can be slimmed down later as the drop-in picks those up. Would you rather wait for drop-in support, or land this and revisit? |
This comment was marked as resolved.
This comment was marked as resolved.
aadf8ba to
755407c
Compare
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 wp-cli#190
755407c to
df3309a
Compare
|
It would be great if you could open these as issues on that other repo 👍 |
Summary
Fixes #190
Addresses all MySQL-specific SQL queries that prevent
wp search-replacefrom working with the WordPress SQLite database integration plugin. This removes the 5@skip-sqlitetags from the test suite.Changes
DESCRIBE tablePRAGMA table_info(table)get_columns()REGEXP '^[aiO]:[1-9]'(serialized data detection)sql_handle_col()callerLIKE BINARY %s(case-sensitive match)LIKEvialike_operator()helpersql_handle_col(),php_handle_col(),log_sql_diff()SHOW CREATE TABLESELECT sql FROM sqlite_masterTechnical details
get_columns(): UsesPRAGMA table_info()on SQLite which returnsname,type,pkfields instead of MySQL'sField,Type,Keystructure.Serialized data detection: SQLite lacks native
REGEXPsupport. When SQLite is detected, the command skips theREGEXPcheck and always uses the PHP processing path (which usespreg_replace). This is slightly slower but produces identical results.like_operator()helper: ReturnsLIKE BINARYfor MySQL andLIKEfor SQLite. SQLite'sLIKEis case-insensitive for ASCII, which may match extra rows, but the PHP replacer handles case-sensitivity correctly so end results are identical.Export:
SHOW CREATE TABLEis replaced with a query tosqlite_masterwhich returns the CREATE TABLE statement in a singlesqlcolumn (index[0]) vs MySQL's two-column result (index[1]).Detection: Uses the existing
Utils\get_db_type()framework utility which checks for theSQLITE_DB_DROPIN_VERSIONconstant.Tests
Removed
@skip-sqlitetags from all 5 previously-skipped regex test scenarios:--regex-limit=1--regex-limit=2--regex-limitTest plan
vendor/bin/behat features/search-replace.featurewp search-replacewith--exportflag on SQLiteSubmitted during WCAsia 2026 Contributor Day — tracked in wp-cli/wp-cli#6295