fix: write child posts to their canonical hierarchical path - #405
Open
chubes4 wants to merge 1 commit into
Open
Conversation
The native runtime built its shared storage without a post resolver. Every other backend wires one. resolve_parent_dir() needs it to walk a post's ancestor chain, so without it the writer returns the post-type root immediately and a child lands flat while its row still records the parent. The canonical path then disagrees with the hierarchy the row declares, and a reader that derives the path from the parent chain cannot find the file. Resolve through WP_Markdown_Storage::read_post(), which reads the post out of the corpus. get_post() would work under WordPress and fatal anywhere else, and the runtime has no WordPress to depend on. A residual predicate is also matched in the executor after the provider read, but the provider projection was built only from the select list, the scalar and boolean predicates, and the subqueries. A provider that resolves a column lazily returns it empty when it is absent from the projection, so a body predicate matched against an empty string and selected nothing. Even LIKE '%' returned no rows. The regression writes a child under a parent, asserts the file lands in the parent directory, and asserts the child's body is searchable there. It fails on the prior resolver.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two independent defects in the native runtime, both of which make a post's body invisible to queries. Found while a wiki article written to
wordpress-com/infrastructure/landed flat at the wiki root and then matched no content search at all — not evenLIKE '%'.1. The native runtime has no post resolver
WP_Markdown_Native_Runtime_Factory::shared_storage()constructsWP_Markdown_Storageand never callsset_post_resolver(). Every other backend wires one —class-wp-markdown-db.php, the CLI, the primary storage runtime, the reconciliation adapter.resolve_parent_dir()needs that resolver to walk a post's ancestor chain:With no resolver it returns the post-type root on the first line, so a child post is written flat while its row still records
post_parent. The canonical path disagrees with the hierarchy the row declares, and a reader deriving the path from the parent chain cannot find the file.Resolved through
WP_Markdown_Storage::read_post(), which reads the post out of the corpus.get_post()would work under WordPress and fatal anywhere else — the smoke suite caught exactly that, since the runtime boots with no WordPress.2. Residual predicates are absent from the provider projection
$provider_projectionis assembled from the select list, scalar columns, scalar predicates, boolean predicates and subqueries — but not from$residual.The post provider deliberately defers body predicates to the executor:
ordered_projection()then hydratespost_contentonly when it appears in the projection. ForSELECT ID FROM wp_posts WHERE post_content LIKE '%x%'it does not, so the provider returns the lazily-resolved column empty and the executor matches the residual against''.Observed before the fix, on a row whose
post_contentis 5041 characters viaget_post():Tests
tests/smoke-native-markdown-post-write.phpgains a parent/child scenario: it asserts the child file lands in the parent directory and that the child's body is searchable at that path.Verified the test discriminates. With the resolver change reverted and the test kept:
With both fixes: 7/7 in that file.
The two fixes are independent — with the resolver reverted, the body assertion still passes because the projection fix hydrates content at whatever path the file occupies.
Suite baseline
6 smoke files fail identically on
mainand on this branch, so this introduces no new failures:smoke-native-create-index,smoke-native-indexed-varchar-scan,smoke-native-option-query,smoke-native-plugin-schema-query,smoke-native-query-parser,smoke-native-table-replace.Worth a separate issue: those files print
FAIL:while exiting0, sohomeboy.json'sphp "$test_file" || exit 1runner reports the suite green.Not addressed here
This prevents new mismatches. Posts already written flat with a parent recorded still need a data repair, and rewriting them in place does not reliably relocate the file — that wants
wp markdown-db reconcilerather than anwp_update_post()round trip.AI assistance: GPT-6 Astra via OpenCode, under Chris Huber direction, traced the flat write and the empty body match to these two causes, made both changes, and wrote the regression. Chris Huber remains responsible for review.