Opened 4 months ago
Last modified 3 weeks ago
#64250 reviewing enhancement
Refactor redirect_guess_404_permalink to use WP_Query instead of raw SQL
| Reported by: |
|
Owned by: |
|
|---|---|---|---|
| Milestone: | 7.1 | Priority: | normal |
| Severity: | normal | Version: | 2.3 |
| Component: | Permalinks | Keywords: | has-patch has-unit-tests needs-dev-note changes-requested |
| Focuses: | performance | Cc: |
Description
The current implementation of the redirect_guess_404_permalink() function uses a direct SQL query to retrieve post IDs when attempting to guess the correct URL for a 404 request based on query variables. While this approach works, it bypasses WordPress’s built-in query abstraction layer and associated benefits.
This change proposes replacing the raw SQL with a WP_Query implementation. Doing so will improve maintainability, consistency, and performance through native WordPress features such as:
- Query caching – Utilises WordPress’s object caching layer, reducing redundant database queries.
- Filtering and extensibility – Enables the use of hooks and filters that developers may rely on to modify query behaviour.
- Security and readability – Removes the need for manual SQL sanitisation and improves code clarity.
- Future compatibility – Ensures the function remains aligned with core WordPress query handling and schema changes.
The refactor should maintain the same functional behaviour — guessing the most appropriate redirect target for a 404 request — while ensuring no regression in performance or accuracy.
Change History (24)
This ticket was mentioned in PR #10531 on WordPress/wordpress-develop by @altf4falt.
4 months ago
#1
- Keywords has-patch added
#2
@
4 months ago
I've refactored the function to use WP Query instead of direct SQL queries.
PR Link: https://github.com/WordPress/wordpress-develop/pull/10531
@altf4falt commented on PR #10531:
4 months ago
#3
@westonruter I've resolved the comments. Seeking clarification on one comment and requesting for a re-review
#4
@
4 months ago
- Keywords good-first-bug removed
- Milestone changed from Future Release to 7.0
- Owner set to spacedmonkey
- Status changed from new to reviewing
This ticket was mentioned in PR #10590 on WordPress/wordpress-develop by @spacedmonkey.
3 months ago
#5
Trac ticket:
@spacedmonkey commented on PR #10531:
3 months ago
#6
@westonruter @anandrajaram21 I have put together a little PR to use WP_Query without a filter. https://github.com/WordPress/wordpress-develop/pull/10590/commits/4c87073adeed8643d01d8a5934d7c8c5c00cf889. Completely untested, but this is how I think this should work.
@westonruter commented on PR #10531:
3 months ago
#7
@spacedmonkey Clever. So you're leveraging the search capabilities of WP_Query to implement fuzzy redirect guessing, specifically via restricting the search_columns to just include the post_name.
Full diff from base: https://github.com/WordPress/wordpress-develop/compare/33c8d7efa3d96ddd9a87168dfe15e771fb81d29c...4c87073adeed8643d01d8a5934d7c8c5c00cf889
@westonruter commented on PR #10531:
3 months ago
#8
In looking at https://github.com/WordPress/wordpress-develop/pull/10590 which has the aforementioned commit, unit tests are failing.
@altf4falt commented on PR #10531:
3 months ago
#9
@spacedmonkey This approach makes sense. I'll try this out, however as @westonruter mentioned, the tests do not pass, so I'll try making the tests pass while keeping the core idea in mind. Thanks for the input!
@spacedmonkey commented on PR #10531:
3 months ago
#10
@anandrajaram21 Here is the full changeset Full diff from base:
https://github.com/WordPress/wordpress-develop/compare/33c8d7efa3d96ddd9a87168dfe15e771fb81d29c...ff81f8864ce2277b9c2c3596315af4e55942960b
I had to make some more tweaks to WP_Query, but it seems to be working. It needs unit tests and testing.
@altf4falt commented on PR #10531:
2 months ago
#11
@westonruter @spacedmonkey I've made the required changes as suggested, and also tweaked the test cases to make sure they pass. Do let me know if I can go ahead and write unit tests for the modified WP_Query, or if there are any other changes to be made before I do so
This ticket was mentioned in Slack in #core-performance by westonruter. View the logs.
8 weeks ago
@mukesh27 commented on PR #10531:
5 weeks ago
#14
@westonruter or @spacedmonkey Could either of you commit this PR so we can get proper testing during the betas/RCs? Since it touches WP_Query, it would be good to get it committed as soon as possible to allow broader testing and reduce any potential risk.
@westonruter commented on PR #10531:
5 weeks ago
#15
Yes, @spacedmonkey is going to commit.
#16
@
5 weeks ago
- Keywords changes-requested added
@westonruter @spacedmonkey Sorry, I haven't had much opportunity to review the proposed PR before now.
While I agree the query in redirect_guess_404_permalink() ought to be cached, I'm not sure that adding a dedicated feature to WP_Query is an appropriate approach.
If WordPress is to allow developers to specify the search position, then that's the parameter that should be introduced, it search_pos => start,end,none or whatever.
We'll also need to make sure it is/isn't available to be set on the front end, as appropriate, and include the variable in WP accordingly. With tests for that too.
As an initial step to include performance of this query it could be stored as a salted cache in the post-queries group.
It would also be good to consider the performance impact of caching the current code vs using a WP_Query instance. WP_Query is a lot while the current code is very little.
#17
@
4 weeks ago
Thanks for your feedback @peterwilsoncc
I did consider just adding caching here. This issue was found because I am working on a site that has around 2.4 million posts and 1+ million attachments. The like search here, simply falls over. So it is best for a query of that size to be punted off to a search provider like elastic search. There are already a number of drop-in solution for adding ES or other scalable search solution / database to WP_Query. So WP_Query feels like a good fit here.
I like the idea of adding search_pos and having these options.
- anywhere so %s%
- start %s
- end %s.
None does not make sense here, we already have exact parameter, that feel like that.
Some ideas for naming
'search_match_type' => 'prefix' | 'suffix' | 'contains'
'search_like' => 'left' | 'right' | 'both'
'search_position' => 'start' | 'end' | 'anywhere'
We could add it to WP, not sure in the value of that, but I am not against it.
This ticket was mentioned in Slack in #core-performance by westonruter. View the logs.
4 weeks ago
#19
@
4 weeks ago
@spacedmonkey You're right, none isn't a good word but I figured you'd get the idea. Of the three options you present, I like the third best with the first as a very close second.
My preference remains for the generic rather than the current code's version as it would be a little frustrating to end up with exact, starts_with and ends_with.
Re: ES drop-ins, I think a little outreach would need to be made to ensure that changes work as expected. As the addition of the slug to the searchable fields and the position (whether the changes I've proposed or those in the existing PR) would either bypass the s trigger for elastic search or trigger the wrong result set.
#20
@
4 weeks ago
- Milestone changed from 7.0 to 7.1
Removing commit as it looks like there is still work to do on this proposal.
Moving to 7.1 as 7.0 beta 1 is tomorrow, but feel free to move it back to the milestone if the patch is ready to ship in the next few hours :)
This ticket was mentioned in PR #10975 on WordPress/wordpress-develop by jonnynews.
4 weeks ago
#22
Trac ticket: https://core.trac.wordpress.org/ticket/64250
## Use of AI Tools
The redirect_guess_404_permalink() function in src/wp-includes/canonical.php has been refactored to replace direct SQL queries with WordPress's native WP_Query abstraction layer.
Trac ticket: https://core.trac.wordpress.org/ticket/64250