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? |
|
Hello! 👋 Thanks for opening this pull request! Please check out our contributing guidelines. We appreciate you taking the initiative to contribute to this project. Contributing isn't limited to just code. We encourage you to contribute in the way that best fits your abilities, by writing tutorials, giving a demo at your local meetup, helping other users with their support questions, or revising our documentation. Here are some useful Composer commands to get you started:
To run a single Behat test, you can use the following command: # Run all tests in a single file
composer behat features/some-feature.feature
# Run only a specific scenario (where 123 is the line number of the "Scenario:" title)
composer behat features/some-feature.feature:123You can find a list of all available Behat steps in our handbook. |
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
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