Repository navigation
Darling's get_pvs_stats trend drew an unmeasured pass as 0 MB: the point is now null with pvs_measured beside it, the same two keys Lite's twin has carried since #3666, and a measured zero is still a zero (#3653) - #3682
Merged
Conversation
…lingPvsReader read persistent_version_store_size_mb as a bare double with IsDBNull ? 0, so a collection on which the DMV reported no size for a database became a real zero in the top-5 series — a cliff in a series that had none. The point is now null with a pvs_measured flag beside it, the same two keys Lite's twin has carried since #3666, and a measured 0 MB still travels as 0 (#3653)
Closed
39 tasks done
This was referenced Sep 19, 2026
This was referenced Oct 12, 2026
Merged
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.
Part of #3653 (the "
PvsTrendPoint.PvsSizeMbcoerces NULL to 0 on the top-5 trend series (both SKUs, rare)" clause under the viewer-calendar item; #3666 landed Lite's half and the Darling Viewer's chart, this is the Darling MCP half). Does not close it.The lie
get_pvs_statswithtrend_hours_back > 0returns the top-5 databases' PVS size series. On Darling the reader behind it (DarlingPvsReader.GetPvsTrendAsync) readpersistent_version_store_size_mbas a baredoublewithreader.IsDBNull(2) ? 0 : …. A collection on whichsys.dm_tran_persistent_version_store_statsreported no size for a database — the collector ran, the row exists, the size is NULL — was published aspvs_size_mb: 0: a real zero, the healthy fully-cleaned state, drawn into a series that had a gap. Beside a neighbouring 912 MB point that reads as a cliff, and the tool's own description sends a caller here "when ADR cleanup looks stuck" — a fabricated drop to zero is the worst possible artefact on that question.The latest-snapshot rows were already right (#3541 A12 made
PvsStatsRow.PvsSizeMbnullable with apvs_measuredflag and apct_of_database_reason); the trend arm was the one place the NULL still became a number. Lite's shared reader and tool got the fix in #3666 (double? PvsSizeMb,pvs_measuredper point, the FinOps chart skipping unmeasured points); the Darling Viewer's chart reader also landed there (it skips the NULL row at read time). The Darling service reader — the one the MCP tool and the web read through — did not.The fix
DarlingPvsReader.PvsTrendPoint.PvsSizeMbbecomesdouble?and the trend read keeps a NULL as null. The tool's trend point gainspvs_measured = p.PvsSizeMb.HasValuebesidepvs_size_mb— the same two keys, spelled identically, that Lite'sMcpPvsTools.cshas carried since #3666, so the cross-SKU payload shape holds. A measured 0 MB still travels as0withpvs_measured: true;pct_of_databasefor an unmeasured point was already null (the SQL's CASE divides a NULL numerator to NULL) and stays so.The tool description is untouched: it is byte-identical to Lite's and already says "pvs_measured says whether the DMV reported a size for that database at all".
What it does NOT do
FinOpsTab.Loaders.cs/ViewerDataService.FinOps.Pvs.cs: the Darling Viewer's own reader alreadycontinues past a NULL size (The Darling viewer's trend charts and calendar tell the same truth the MCP tools learned today: routed by retention tier and saying so, no fabricated first point, and a purged day is grey, not green (#3653 viewer ports) #3666), so its chart receives only measured points and needs noWhere(HasValue). The Viewer'sPvsTrendPointrecord is a separate type and is unchanged.server-tabs.jsrendersget_pvs_stats'databasesgrid only; nothing on the web reads the trend points.Tests
McpZeroIsAMeasurementTests(§5, PVS):ThePvsShare_DividesAnyMeasuredSize_AndSaysWhyWhenItCannot(Theory over both SKUs' tool files) now also assertspvs_measured = p.PvsSizeMb.HasValue,in the trend arm — Lite already had it, Darling now does.TheDarlingPvsTrendReader_CarriesAnUnmeasuredPointAsNull_NeverZero— the record signature isdouble? PvsSizeMb,and the trend read isIsDBNull(2) ? null, never? 0(the same two shapesViewerTrendRoutingPortTests.PvsTrend_BothSkus_NeverPlotAnUnmeasuredPointAsZeropins on Lite's shared reader).BothSkusPvsDescriptions_StayByteIdentical_AndTeachPvsMeasured— the twoget_pvs_statsdescriptions are equal and teach the flag.McpZeroIsAMeasurementLivePostgresTests.AMeasuredZeroPvs_IsAMeasurement_AndAnUnmeasuredOneSaysSo— extended: an EARLIER pass is seeded on whichBusyDbwas unmeasured;trend_hours_back: 24must returnBusyDbas[null/unmeasured, 912.82/measured],CleanDbas two measured zeros withpct_of_database 0.00,UnreadDbas two nulls.Executed on this Mac via the mactest harness against
timescale/timescaledb:2.28.1-pg18:McpZeroIsAMeasurementTests+McpZeroIsAMeasurementLivePostgresTests(24 tests) plus the harness's other classes — 83 total, 0 failed, 0 skipped. Positive control: with the reader reverted toIsDBNull(2) ? 0both the source pin and the live test fail (Expected: Null, Actual: Numberon the earlier BusyDb point). Service and Darling.Tests build-c Release -p:EnableWindowsTargeting=truewith 0 warnings.