Repository navigation
Field data confirms the interval-table fix removes the spill, ship it (#3953) - #4208
Merged
Merged
Conversation
…3953): V140 and the writer V140 adds collect.query_store_interval_latest (one row per Regular interval identity), its per-server coverage row, and a pending-replay table. The Query Store COPY applies each batch in its own transaction behind a savepoint with a 5 s lock_timeout; an apply fault rolls back to the savepoint, records the batch for replay and lets raw commit, so raw ingestion never depends on the table. Coverage creation and the hourly gap check run before the transaction with bare-parameter bounds, so nothing inside it reads raw except by the batch's collection_time. The viewer probe gets the V140 sentinel and top arm. Checkpoint: the readers do not use the table yet. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GdmA4ND1wLSqA91ax1m4xv
…coverage holds the raw read's snapshots (#3953) Both regression reads get a table twin that shares everything above the dedup with the shipped raw SQL (split into shared constants, byte-identical). The fact decides the source per server and pass (coverage start, pending batches, raw's chunk floor, the table's floor) and records it on the analysis context, so the drill-down reads the same source. Any fault in the decision reads raw. A live test seeds real regressions through the write path and pins the fact and drill-down rows identical from both sources, then shows only the table still reaching a best plan after raw is purged below it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GdmA4ND1wLSqA91ax1m4xv
DarlingRetention deletes the latest-snapshot table's intervals past QueryStoreIntervalLatestRetentionDays (15, on first_execution_time) and pending-replay rows past the same horizon, failure-isolated like every sibling. It stays out of RawTierCoverage and RetentionPolicies. The batched DELETE is the whole path until the table's hypertable conversion lands; drop_chunks joins then, in collection_log's shape. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GdmA4ND1wLSqA91ax1m4xv
…kips best plans older than 4 days (#3953) With the interval table the PLAN_REGRESSION window really reaches 14 days, so a best plan can be two weeks old. Both drill-downs (Darling's two twins through the shared tail, and Lite's) append best_plan_last_seen; the shared extractor carries it onto ForcePlanTarget, and ForcePlanBotPolicy blocks a target whose best plan last ran more than MaxBestPlanAgeDays (4, raw's retention) before the pass, with the new reason best_plan_stale. That keeps the would-force journal in the regime it has been scored in. A target with no age (a pre-#3953 finding) is not gated. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GdmA4ND1wLSqA91ax1m4xv
…read (#3953) Both fact reads (Darling's raw and table twins through the shared suffix, and Lite's) append the best plan's last run. The fact metadata gains best_plan_age_days and plan_regression_source (1 = interval table, 0 = raw; Lite is always 0), and the advice states the age: "the faster plan on record (it last ran 9 days ago)". The 10 CPU-second floor stays absolute. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GdmA4ND1wLSqA91ax1m4xv
…xcept by the batch's collection_time (#3953) Review finding 2 as a test: every statement the apply runs inside the raw COPY's transaction reads query_store_stats only under server_id = $1 AND collection_time = $2; the two wider reads run before it with bare-parameter bounds; the conflict target and batch key render from one identity constant. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GdmA4ND1wLSqA91ax1m4xv
…te path (#3953) QueryStoreIntervalLatestRungTests takes the "I am the top rung" claims off V139's test: the dense ladder (Scripts[^1]), the DDL (three engine-plain tables, one NULLS NOT DISTINCT unique index whose columns are the writer's conflict target), and the viewer probe's top arm. It also pins the coverage claim's first guard: no product source spells a write into query_store_stats, and no other generic-COPY site handles the Query Store collector; the #1912 slice repair is the named exception. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GdmA4ND1wLSqA91ax1m4xv
Dev grew its own V140 (checkpointer-timed-count, #4037) and V141 (collection-caveats, #3691) after this branch's V140 was cut. Renumbered the query-store-interval-latest migration to V142, the next free version, and updated every version-bump obligation: StorageVersion.SchemaVersion, the StoreSchemaProbeSql sentinel and its MapProbedSchemaVersion arm and parameter, the GetBoolean call list, and the rung test files' handoff chain (CollectionCaveatsRungTests no longer claims the top rung; QueryStoreIntervalLatestRungTests does). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TszxYhJJbTEh4LrZ56NYo3
CollectionCaveatsRungTests.TheRungIsRegisteredAtTheTopOfADenseLadder still asserted it was the top rung (RungVersion == SchemaVersion, Same(V141, Scripts[^1])), which stopped being true once V142 landed above it - mirroring the same fix CheckpointsTimedRungTests already carries from when V141 landed on it. QueryStoreIntervalLatestWriterTests had one hardcoded Scripts.Single(m => m.Version == 140) reference (re-running the rung's own SQL after dropping its index mid-test) that the standard version-bump obligations list doesn't cover. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TszxYhJJbTEh4LrZ56NYo3
The test built its "V141 sentinel absent" argument array with `i < arity - 1`, which meant "every parameter except the last one" back when V141 was the newest. V142 (#3953) appended its own parameter after hasCollectionCaveats, so `arity - 1` now names hasQueryStoreIntervalLatest instead, and the old test left hasCollectionCaveats itself true while turning off the wrong sentinel -- masked further by MapProbedSchemaVersion answering 142 outright once the V142 sentinel is true, regardless of V141's state. Finds hasCollectionCaveats by name via reflection and requires every sentinel from it up to be false, not just the literal last parameter. Also normalizes two files' line endings back to the repo's CRLF convention (git's clean filter had already silently fixed the committed blobs on the merge commit; only the on-disk working copy needed it, which is what a literal-CRLF pin elsewhere caught). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TszxYhJJbTEh4LrZ56NYo3
…PlanAgeDays gate (#4208) PR #4216 merged to dev using V142, so #4208's migration is renumbered to V143. All references updated: PgMigrations.cs (Migration ctor + const name + doc comment), StorageVersion.SchemaVersion, ViewerDataService.cs (probe comment + arm comment + return value), and all pin/rung tests (QueryStoreIntervalLatestRungTests, QueryStoreIntervalLatestWriterTests, CollectionCaveatsRungTests, PostmasterStartTimeRungTests, ViewerCollectionCaveatsTests). The PR body's CHANGELOG entry now includes a second bullet for the force-plan bot age gate (ForcePlanBotPolicy.MaxBestPlanAgeDays = 4), pinned by Assert.Equal(4, ForcePlanBotPolicy.MaxBestPlanAgeDays) in ForcePlanBotPolicyTests. Build: 0 warnings, 0 errors. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FVjn4PBJN71NQXdFo6ZxNQ
erikdarlingdata
marked this pull request as ready for review
September 25, 2026 04:44
erikdarlingdata
enabled auto-merge (squash)
September 25, 2026 04:44
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FVjn4PBJN71NQXdFo6ZxNQ
…corer (#4206) The parity test extracted from CollectAndScoreFactsAsync up to ComparePeriodsAsync. CollectConfigAuditFactsAsync sits between those two methods in DarlingAnalysisService.cs. After #4206 added _scorer.ScoreAll to the narrow pass, the extraction included two scorer calls instead of one, failing Assert.Equal(1, CountOf(code, Score)). ReadBody now stops at CollectConfigAuditFactsAsync when present (Darling only), falling back to ComparePeriodsAsync when not (Lite). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FVjn4PBJN71NQXdFo6ZxNQ
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FVjn4PBJN71NQXdFo6ZxNQ
…r before 143 Both 141→142 (index on index_object_stats.server_time) and 141→143 (#3953) branched from common ancestor 141. Merge resolution: - PgMigrations.cs: V142Sql added before V143Sql; migration list 141,142,143 in order - StorageVersion.cs: SchemaVersion = 143 (HEAD) - ViewerDataService.cs: probe SQL includes both V142 (pg_indexes) and V143 (information_schema.tables) probes; method signature adds hasIndexObjectStatsServerTimeIndex at ordinal 117 then hasQueryStoreIntervalLatest at 118; reader call extended to GetBoolean(118); V142 arm added between V141 and V143 arms - CollectionCaveatsRungTests.cs: dev's prose (V142 is the immediate handoff, not V143) - ViewerCollectionCaveatsTests.cs: dev's constant (ordinal 116 pinned by name) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FVjn4PBJN71NQXdFo6ZxNQ
8 of 9 tasks
…r from dev Merging dev into this branch left two declarations of `collectionCaveatsOrdinal` in ViewerCollectionCaveatsGateTests: the `var` added by V142's dev merge and the `const int 116` from this branch's original test. Remove the const; use the Array.FindIndex result throughout. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FVjn4PBJN71NQXdFo6ZxNQ
V142 (#4196) landed on dev after the fix/3953-qs-interval-latest branch was cut. Merging dev bumped V143's ProbeOrdinal from 117 to 118 and made V142 no longer the top rung. IndexObjectStatsServerTimeIndexRungTests (V142): - Remove "I am the top rung" assertions (Assert.Equal(RungVersion, SchemaVersion) and Assert.Same(V142, Scripts[^1])). Replace with Assert.True(RungVersion < SchemaVersion). - Change Assert.Equal(ProbeOrdinal, arity - 1) to Assert.True(ProbeOrdinal < arity - 1). - Add nextArm check that V143's arm sits above V142's in MapProbedSchemaVersion. - Update class summary and comments to say claims moved to QueryStoreIntervalLatestRungTests. QueryStoreIntervalLatestRungTests (V143): - Bump ProbeOrdinal from 117 to 118 (V142 is now at 117). - Bump PreviousVersion from 141 to 142 (V142 is the rung directly below V143). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FVjn4PBJN71NQXdFo6ZxNQ
This was referenced Sep 25, 2026
erikdarlingdata
added a commit
that referenced
this pull request
Sep 25, 2026
…ur (#3953) (#4311) Ruling item 2 on #3953: the slicer's collection_time floor already carries interval_start_time_utc <= collection_time as its real bound, so the extra day below the window start was pure clock-skew slack, over-broad by 23 hours. Narrowed to an hour, which still covers realistic skew between the monitored server's clock and the store's. The ceiling (30 days, covering Query Store's max interval length plus collector-outage catch-up) is a different bound and is untouched. QueryStoreSlicerSql_KeepsSlackenedCollectionTimeBoundsForChunkExclusion updated to pin the new hour literal instead of the old day literal. Ruling item 1 (moving this read, get_query_store_top and the WPF viewer's QueryStoreTopSql onto query_store_interval_latest) is parked: the table #4208 shipped is Regular-execution-type only (both by its write filter and by an identity that omits execution_type_desc) and is missing most of the columns these two reads select. Full analysis posted on #3953 (issuecomment-5835309188). Follow-up for the rest of the still-deduplicating Query Store reads filed as #4310. Claude-Session: https://claude.ai/code/session_01TszxYhJJbTEh4LrZ56NYo3 Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This was referenced Sep 25, 2026
erikdarlingdata
added a commit
that referenced
this pull request
Sep 26, 2026
erikdarlingdata
added a commit
that referenced
this pull request
Sep 26, 2026
…33Z UTC (#4440) Moves the CHANGELOG entries carried in merged pull-request descriptions into [Unreleased]. The cut is PRs merged at or before 2026-09-26T17:37:33Z; the next splice starts after it. - 128 PRs are spliced: Fixed 87, Changed 20, Added 17 and Security 5. Each entry sits at the top of its section, newest PR first, and its link definition joins the trailing block. - 22 PRs have no user-visible entry (None, test-only, or deferred to a parent). - Three entries had no section in their description, and each was assigned from its diff: #4363, #4383 and #4380 go under Security. - Link fixes: the #4198 references point at the issue, and #4360's [#4203] label points at issue 4203. - #4208's entry is taken from its diff. - Two security entries are worded to the current state: #4351's rotation note, and #4363's journal-read line. - Only CHANGELOG.md changes.
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 #3953.
Why
#3953 was built, tested, and shelved on 2026-09-23. The shelving measurement was on a small rig. It found a
full 14-day pass only went from about 6.5s to 5.5s. The drill-down got 4x slower (71ms to 286ms). That did
not justify three new tables, a writer inside the Query Store COPY transaction, a replay path, and a
compression-band conflict. The ruling was to reopen if field data from the busy client-site server showed
PLAN_REGRESSIONdominating.It now does. The store ingests 43 SQL Servers' Query Store data (build 3.8.0-nightly.20260924.467, about 5
hours of steady-state passes). On it,
PlanRegressionSql, the raw whole-slice dedup this issue targets, isthe store's single heaviest statement:
At that rate the spill alone is roughly 400GB/day of temp writes. That is exactly the write-amplification
input the original ruling named as a first-class factor. The small rig's 14-day pass never spilled to temp,
which is why it missed this.
What changes
This is the branch built for the original ruling (design v2, adversarial-reviewed before code). A
collector-written table,
collect.query_store_interval_latest, holds the latest Regular snapshot per QueryStore interval, with a 15-day horizon.
PLAN_REGRESSIONand its drill-down aggregate the table instead ofdeduplicating raw. Each server and pass reads the table only when coverage matches the raw read's scope
and there are no pending (failed-apply) batches. Otherwise the read falls back to the shipped
raw SQL, unchanged. Full design is in the issue's 2026-09-23 comments.
This lane's own work was the merge and the re-measurement:
origin/dev. The branch's migration was V140. Dev had since grown its own V140(
checkpointer-timed-count, Store Checkpointer Pressure compares an hourly sync sum to a per-checkpoint bar, so it fires permanently on healthy stores #4037) and V141 (collection-caveats, PostgreSQL-target analysis engine: v2/v3 slices and the v1 lanes' residue (from #3542) #3691). Renumbered this branch'smigration to V143, the next free version. Updated every version-bump obligation:
StorageVersion.SchemaVersion,StoreSchemaProbeSqlsentinel (arm and parameter), theGetBooleancalllist, and the rung test files' handoff chain.
QueryStoreIntervalLatestRungTestsnow claims the top rung.CollectionCaveatsRungTestsdoes not.CollectionCaveatsRungTestsstill asserted it was the toprung.
QueryStoreIntervalLatestWriterTestshad one hardcodedScripts.Single(m => m.Version == 140).ViewerCollectionCaveatsGateTestsbuilt its "V141 absent" argument array asi < arity - 1, which silentlystopped meaning "V141's own ordinal" the moment V143 appended a parameter after it. Fixed by finding the
parameter by name via reflection instead.
.gitattributespins.csfiles to CRLF. A Python read/write round-trip during conflict resolution hadsilently flattened both files to LF-only on disk. Git's own clean filter had already fixed the committed
blob, which is why only the working copy needed the fix.
OversizedPlanBacklogPinscaught it, since itpins a literal CRLF sequence in the migration SQL text.
Re-measurement
The small rig never spilled. This time the seed was sized to make the OLD read spill. Seed: one server, 14
days, 500 queries x 2 plans x 336 hourly Query Store intervals x 4 re-collections per open
interval. That is 1,344,000 raw rows, deduplicating to 336,000 latest-interval rows, against a plain
PostgreSQL 18 + TimescaleDB rig at default
work_mem(4MB).EXPLAIN (ANALYZE, BUFFERS)on both statements,same parameters, same snapshots:
The old plan's
Sortnode readsSort Method: external merge Disk: 57888kBper parallel worker. That spillsthe full 1.34M-row slice three times over, once per worker, on top of two more external-merge spills at the
GroupAggregate stages above it. The new plan reads the pre-deduplicated 336,000-row table directly. Its
worker-level sort still spills modestly (about 34MB total), but nothing upstream of it does.
This reproduces the field mechanism: heavy temp writes from sorting the whole raw slice. The scale is about
1/40th of one server's share of the real store's roughly 5-hour window. The new shape removes the great
majority of it there. Given the lane's time budget, I did not additionally scale up to the full field row
count. The ratios above are squarely consistent with the field numbers' 22.5%-of-store-time and
91%-of-temp-writes shares.
Result identity is proven at real scale through the real write path. An md5
oracle covers the fact and drill-down, table vs. raw, including a purge-boundary case
(
PlanRegressionIntervalTableEquivalenceTests). It was re-run live against this lane's rig and passed,unchanged by the merge.
Lite parity
S1's claim above ("Lite... I did not change it") is incomplete: this branch's diff against
origin/devalready touches 8 files outside Darling. They predate this lane, inherited from the branch's 2026-09-23 revival, not written by S1. Per this lane's brief, they are accounted for here rather than reverted. The PR tender decides what to do with them:Lite/Analysis/DuckDbFactCollector.QueryPerf.cs(+28)best_last_execthrough the fact'scomparedCTE and SELECT. Computesbest_plan_age_daysmetadata and aplan_regression_sourceflag (0= Lite's raw read,1= Darling's interval table) on thePLAN_REGRESSIONfact.Lite/Analysis/DrillDownCollector.Queries.cs(+11/-2)best_plan_last_seento the drill-down'scomparedCTE and output row.PerformanceMonitor.Analysis/AnalysisContext.cs(+9)PlanRegressionReadsIntervalTable(nullable bool): which source Darling's fact read this pass. The drill-down reads the same source, so it never shows a best plan the interval table still holds but raw has already purged.PerformanceMonitor.Analysis/FactAdvice.cs(+7/-1)best_plan_age_daysis present.PerformanceMonitor.Analysis/FactRemediation.cs(+15/-1)best_plan_last_seenoff the drill-down row into a newBestPlanLastSeenUtconForcePlanTarget.PerformanceMonitor.Analysis/RemediationAction.cs(+7/-1)BestPlanLastSeenUtcto theForcePlanTargetrecord, defaulted for wire compatibility.PerformanceMonitor.Analysis/ForcePlanBotPolicy.cs(+23)ReasonBestPlanStaleandMaxBestPlanAgeDays = 4. The unattended force-plan bot now blocks on a target whose best plan last ran more than 4 days before the pass.PerformanceMonitor.Collectors/CollectorContext.cs(+9)QueryStoreIntervalMisses, a per-cycle count of batches that stored raw rows but missed Darling's interval table and were queued for replay.All eight are #3953-scoped. None looked unrelated enough to flag for reversion. None are mentioned in the
## CHANGELOG entrybelow, which as written only covers the Darling interval-table read. Whether the advice-text and force-plan-bot behavior changes need their own CHANGELOG line is a coordinator call before this leaves draft.One correction to S1's description while verifying it: the Lite dedup CTE does not use
array_agg(...). Like the text above, it isROW_NUMBER() OVER (... ORDER BY collection_time DESC, execution_count DESC)filtered torn = 1, with the same effect through a different construct. The description was off. The scale claim next to it is the one this lane was sent to actually measure.Measuring Lite's twin read at the top of its scale
Seeded Lite's own
query_store_statsDuckDB table through the realDuckDbInitializer.InitializeAsync()/CreateArchiveViewsAsync()(production schema, not hand-transcribed), on the same connection string Lite itself uses (memory_limit=1GB;checkpoint_threshold=1GB). The seed:query_storecollector caps at the top 100 queries per database).query_storeschedule polls every 5 minutes. A Query Store interval is 60 minutes, so 60 / 5 = 12.That is 12,096,000 raw rows, of which 2,419,200 are the one server's slice a single
server_id = $1call reads. Same shape as S1's re-measurement above, scaled down to Lite's real ceiling of a handful of servers instead of 43.EXPLAIN ANALYZEon both reads against that seed, server 1, params matching production exactly, such ascontext.TimeRangeStart.AddDays(-14):CollectPlanRegressionFactsAsync(DuckDbFactCollector.QueryPerf.cs), unconditional every pass, Lite's actual parity twin ofPlanRegressionSql(4 runs)TABLE_SCAN, confirmed in the plan)SPILL/external/ temp-file text anywhere in the planCollectRegressedQueries(DrillDownCollector.Queries.cs), filtered to the fact's own offenders, the only path the running app actually takes (see below) (1 run)EXPLAIN ANALYZE's own reported total)$5 IS NULLbranch (4 runs)The unfiltered branch is real SQL, but its only call site never reaches it.
DrillDownCollector.csgates the call onpathKeys.Contains("PLAN_REGRESSION"). The fact setscontext.PlanRegressionOffendersto that pass's own (<=20) results before deciding whether to create the finding the drill-down keys off. Every real invocation already carries a non-empty offender list, so in the running app$5/$6are never actually null.The 1.3-1.6s number is real, but it is dead code today, not the steady-state cost. I did not change that: it is out of scope for this lane. Noted here for whoever next touches this file.
Peak memory needed a different check.
duckdb_memory(), polled every 40ms during each run, read 0.0 in every case, including runs known to use real memory (below). It is not a trustworthy instrument for this workload on this version, so I did not rely on it.Instead, a calibration sweep throttled
memory_limiton the identical seeded data and the identical FACT query. This is not Lite's real 1GB setting. It completed at 300MB (2 runs, 1,673-1,886 ms, still no spill). It hard-failed at both 150MB and 75MB (2 runs each): aDuckDBException: Out of Memory Error, not a graceful spill, every time at "143.0-144.1 MiB used". That pins this read's actual peak working set between about 143MB and 300MB. Lite's real budget, 1GB, sits roughly 3.4x-7x above that range.Decision: do not port
Both of Lite's real code paths finish in under a second: FACT at 530-981ms, the drill-down's only reachable path at 373ms. Neither spills or comes close to Lite's 1GB ceiling, even in the unreachable worst case. That is short of the brief's "over about 1s, or a large spill" bar for porting.
It also matches the structural reason S1 gave without a number behind it. Every Lite call reads exactly one server's slice under a fixed 1GB budget on a vectorized columnar engine. It never reads several servers' slices competing for one shared 4MB
work_mem, the way 43 concurrent Postgres passes do on Darling's store. The conclusion is unchanged from S1's. It now rests on a measurement instead of an assertion about scale.Test plan
dotnet build Darling/Darling.Tests/Darling.Tests.csproj: 0 Warning(s), 0 Error(s).QueryStoreIntervalLatestRungTests,CollectionCaveatsRungTests,CheckpointsTimedRungTests,PostmasterStartTimeRungTests,ViewerSchemaVersionGateTests,QueryStoreIntervalLatestWriterTests,PlanRegressionIntervalTableEquivalenceTests,PgFactCollectorTests,DarlingAnalysisPipelineTests,ForcePlanBotPolicyTests,PlanRegressionReadShapeTests,ViewerCollectionCaveatsGateTests,OversizedPlanBacklogPins. All pass, including the live (DARLING_TEST_PG) cases.Darling.Testssuite, run once: 13,763 total, 2 failed, 696 skipped (no live Postgres orpg-runtime for that pass). Both failures were the line-ending drift and the
ViewerCollectionCaveatsGateTestsarity assumption above. Both were fixed and individually reverified passing afterward.
budget. The affected classes were reverified individually. The rest of the suite did not
depend on either fix (a line-ending pin and one test's own argument construction).
EXPLAIN (ANALYZE, BUFFERS)re-measurement above, on a throwawayprobedatabase, notthe suite's
darlingtest.C:\GitHub\worktrees\rig-s1, stopped and deleted after use.CHANGELOG entry