MCP top queries and procedures over long windows: no dropped filters, null for what the rollup lacks, per-server coverage - #4715
Merged
Conversation
…ters, null for missing columns, in-statement text, per-server coverage, edge disclosure
A stitched UNION ALL cannot give an ordered first row, so ORDER BY bucket LIMIT 1 over it sorted every row the server has. The probe is now least() of two ordered first-row probes, one per relation, split at the same floor the stitch uses; a single relation keeps the one-probe form.
…uide marker, and the raw empty page keeps the shared sentence (#4711)
…coverage probe split
… served-span attribution, probe observed
…es over the served span
erikdarlingdata
marked this pull request as ready for review
September 29, 2026 13:44
This was referenced Sep 29, 2026
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.
Fixes #4711.
What changed
parallel_only,min_dopandgroup_by=host_objectused to be dropped on the hourly rollup whilefilter_appliedclaimed them. The reader now forces raw when any is set, sofilter_applied, thegroup_byecho andprecision_noteare true.precision_notesays the read stayed on raw; the raw floor probe reportswindow_truncated/effective_start. The empty min_dop status carrieseffective_start,effective_hours_backandwindow_truncated; when raw no longer holds the whole window it says which part it read, and otherwise it keeps the sentence Lite shares word for word.tier_used=hourly, plan hash, plan handle, DOP, reads/writes/physical reads/rows/spills,avg_reads,is_parallel,distinct_textsand min/max cpu/elapsed are JSON null (procedures:object_type, handles, I/O totals and all four extremes). The rollup's min/max are per-collection sums, so none are selected.sql_handleis now returned (exact, it is a rollup group column).precision_notesays so, and so does each tool's guide (get_tool_guide); the served tools/list heads are unchanged. No new payload keys.LEFT JOIN LATERALoverv_query_statsreplaces one query per row; the read over-fetches by 5 and drops WAITFOR shells as raw does. A miss gives a nullquery_textand atext_note.window_truncated,effective_startandtruncation_noteon hourly now come from it. When the window crosses the stitch floor F (RollupCoverage.StitchFloor, the same F the stitched relation splits at), the probe isleast()of two ordered first-row probes: the legacy view below F, and the successor from F (HourlyFirstBucketSql). That is exact, because the legacy half only holds rows below F. With nothing to split, it probes the single spliced relation (HourlyFirstBucketSingleRelationSql, which throws if the splice is ever a UNION). A first row can't be taken cheaply from a stitchedUNION ALLsubquery, because the planner sorts every row of the server in the window to return one.precision_noteby the newHourlyWindowEdges.Note: the start (no bucket before the first served one), and the end, against the rollup's materialization ceiling (see below).Exactness fixes, second pass
window_truncatedandeffective_startstill describe the start edge.parallel_only,min_dopandgroup_byforce the raw tier. With an agedas_ofraw holds nothing there. The tool now returns statusempty("raw query_stats holds nothing in this window; the hourly rollup, which does, cannot apply parallel_only/min_dop/group_by=host_object"), withwindow_truncated = trueandeffective_start = null, instead of "the window's answer".text_notethat also says it "may be a WAITFOR shell, which raw query_stats filters out".sql_handleon the hourly tier.precision_notestates that the handle is the rollup'sMAX(sql_handle), which can name a handle seen only on a zero-interval collection that raw excludes. Totals are unaffected.cpu_attributionon the hourly tier. The share divides by the span the rollup served (first bucket to min(ceiling, end of the as_of hour), on hour edges), and the existing note states that span. Raw reads keep the requested window.Exactness fixes, third pass
AND f.bucket < $N, where$Nis the relation's materialization ceiling bound as a naive-UTC timestamp parameter (a placeholder swapped for the clause, or for nothing when the ceiling is unknown). A bucket materialized after the cached coverage snapshot is neither read nor counted, so "nothing after it was read" is true by construction. The split probe keeps its two orderedLIMIT 1s insideleast().cpu_attributionare read over the span the hourly rollup served (first bucket to the ceiling), on both tools, so the measured denominator and the ranked numerator cover the same span.Cost
The probe is one extra indexed query per hourly-tier call, uncached. Measured read-only on a large production monitoring store, with 43 servers and 1-day rollup chunks, most of them compressed:
UNION ALLand took 146 ms on the busiest server, sorting about 207 K rows. That's why the probe splits at F.Tests
TopQueriesHourlyRoutingLiveTests): forced-raw with floor disclosure and empty status; hourly nulls plussql_handleplus null text andtext_note; young server reportswindow_truncated. Procedures live test asserts the nulls. New source pins inTopQueriesHourlyRoutingTests, newHourlyWindowEdgesTests.TopQueriesHourlyRoutingLiveTests4/4,TopProceduresHourlyRoutingLiveTests2/2,TopQueriesHourlyRoutingTests4/4,HourlyWindowEdgesTests4/4,McpPayloadContractCensusTests68/68,McpPageContractTests43/43,DocCommentHygieneTests77/77,StorageCommandTimeoutTests,StartupCommandTimeoutTests,McpReadCommandTimeoutTests,CommentFilterAdoptionTests,RepoFileAdoptionTests,StitchedRelationSqlTestsall green. Darling.Tests builds 0 errors, no CA/CS/IDE warnings.McpPayloadContractCensusTests.WindowFloorBlocks4 -> 5.HourlyRouted_StitchedWindow_CoverageProbeSplitsAtTheFloor: a window crossing F reports the legacy half's first bucket, and a successor-only server reports the successor's first bucket. On the rig, 5/5 in its class.least(, exactly two ordered probes, noUNIONin either constant, and the probe method callsStitchFloor. On the previous tip they're a compile RED (HourlyFirstBucketSingleRelationSqldoesn't exist there), and the old single stitched constant has noleast(.if (false && tier == Hourly && ...)) makes the forced-raw fact fail:Expected: "raw" Actual: "hourly". Restored; green.HourlyWindowEdgesTestsis a compile RED on dev (type absent); the other pins assert shapes dev lacks. The forced-raw fact's RED is the mutation above.HourlyRouted_StitchedWindow_CoverageProbeSplitsAtTheFloorfail (expected the legacy half's 01:00 first bucket, got the successor's 10:00); restored, the classes pass 5/5 and 2/2.fmtInt/fmtNum/fmtMs, which return "—" for null; no JS change.Exactness fixes, second pass: tests
RED = the pre-change head (
e43d9b27c) with the new test files copied in. GREEN = this branch.HourlyRouted_EndBeyondTheMaterializationCeiling_SaysNothingAfterItWasRead(live)Assert.Containssub-string not found (old note says "included whole")ForcedRaw_OverAWindowRawNoLongerHolds_SaysNothingWasRead(live, aged as_of)Assert.Containssub-string not found (old text: "the window's answer")HourlyRouted_MissingColumnsAreNull_AndSqlHandleIsCarried(live, WAITFOR text_note)Assert.Containssub-string not foundHourlyWindowEdgesTestsstart wordingAssert.Containssub-string not found (old sentence says "the partial hour")HourlyWindowEdgesTestsceiling, combined-edge andServedSpancasesNotetakes 3 arguments,ServedSpandoes not existHourlyRouted_StitchedWindow_CoverageProbeSplitsAtTheFloor(live, legacy-only server D)< $4bound, see the mutation rowHourlyAttributionSpanTests(3 unit facts)Assert.Equalvalues differ: start, and the 0.75 share)< $4mutation: removingf.bucket < $4 ANDfrom the legacy half ofHourlyFirstBucketSqlmakes the stitched fact FAIL on server D: expectedeffective_start13:00, actual 11:00 (the legacy-only bucket wins). Restored: pass.HourlyAttributionSpanto return the requested window for hourly reads failsHourly_LateFirstBucketAndLowCeiling_UsesTheServedSpanandHourly_ShareDividesByTheServedSpan_NotTheRequestedWindow. Restored: 3 of 3 pass.*Census*|*Ratchet*|*Inventory*|*Adoption*classes plus the MCP budget, guide, heads-data, page-contract and payload-contract classes, both hourly routing live classes, both*HourlyRoutingTests,StitchedRelationSqlTests,CpuAttributionTests,DocCommentHygieneTests, the store command timeout classes: 43 classes, 586 tests, 0 failed, 0 skipped (live rig attached). Lite.Tests builds with 0 warnings and 0 errors (build-only; it cannot run here).Lite/Mcp/McpQueryTools.cs: "The filter was applied in SQL over the whole window, so this is the window's answer rather than a page artefact — drop parallel_only / min_dop to see the unfiltered ranking, or confirm current parallelism with analyze_query_plan."Exactness fixes, third pass: tests
HourlyRouted_EndBeyondTheMaterializationCeiling_SaysNothingAfterItWasRead(live, extended): a bucket materialized past the ceiling is not read (RED without the clause:Assert.Singlesees 2 rows; GREEN: 7/7).sql_cpu_seconds_in_windowagainst seeded samples over a known span (RED with the CPU call site reverted to the requested window: expected 7200, actual 10800; GREEN: 7/7).HourlyWindowEdgesTests.NullCeiling_SaysTheCeilingIsUnknownandHourlyAttributionSpanTests.Hourly_NullCeiling_SaysUnknown_NotThatNoSpanWasServed: green after the wording change.McpToolsListBudgetTests,McpToolGuideTests,McpToolGuideHeadsDataTests,McpPayloadContractCensusTests,McpPageContractTests,StitchedRelationSqlTests,StorageCommandTimeoutTests,McpReadCommandTimeoutTests,StartupCommandTimeoutTests,DocCommentHygieneTests, the Adoption classes.CHANGELOG
None: every defect fixed here is in the hourly routing and the window disclosure that are new in 3.9 (#4396, #4413, #4278 and #4279; none is in v3.8.0), so nothing a 3.8 user has seen changes. The 3.9 entries for those changes will describe this final behavior.