Skip to content

TRT-2741: Add partitioned prefix sum tables for matview refresh optimization#3762

Merged
openshift-merge-bot[bot] merged 1 commit into
openshift:mainfrom
mstaeble:trt-2741-prefix-sum-tables
Jul 13, 2026
Merged

TRT-2741: Add partitioned prefix sum tables for matview refresh optimization#3762
openshift-merge-bot[bot] merged 1 commit into
openshift:mainfrom
mstaeble:trt-2741-prefix-sum-tables

Conversation

@mstaeble

@mstaeble mstaeble commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds two new LIST(release)->RANGE(date) partitioned tables: test_daily_totals and test_cumulative_summaries
  • test_daily_totals is a partitioned replacement for test_daily_summaries, populated in parallel
  • test_cumulative_summaries stores running prefix sums from test_daily_totals, enabling sub-second queries for any arbitrary date range via prefix sum subtraction (cum(end) - cum(start-1))
  • Variant grouping happens at query time via JOIN to prow_jobs, so variant changes are immediately reflected without any rebuild step
  • Phase 1 is additive only: new tables are populated alongside existing test_daily_summaries. Nothing reads from them yet. Later phases will switch query paths and remove the old matview dependency.
  • Includes sippy backfill CLI command and backfill-summaries.sh script for populating the tables
  • RefreshData now returns errors and short-circuits on failure
  • All refresh and backfill operations process data day-by-day, then release-by-release, for full partition pruning and restartability

Staging validation

Correctness

  • Full 91-day backfill completed on staging (prod-scale data)
  • test_daily_totals values verified identical to test_daily_summaries across 200 sampled rows (two releases, two dates)
  • Prefix sum subtraction verified correct: range queries match direct SUM from daily summaries (98/98 entities, 50/50 variant range queries)
  • Carry-forward behavior verified: gap-day cumulative values correctly equal previous day (5/5 entities)
  • Base case verified: first-day cumulative values equal raw daily values (100/100 entities)

Performance (warm queries, prod-scale staging data)

Query Matview Prefix Sum Speedup
Install page (filtered, release 5.0) 9.5s 200ms 47x
TestReportsByVariant (all tests, 4.22) 58s 3.4s 17x
CR ad-hoc query (28-day window) 47s 3.4s 14x
PlatformInfraSuccess 1.1s 0.6s 1.8x
Single test lookup 15ms 22ms ~tie

Refresh pipeline

Operation Non-partitioned Partitioned Speedup
Cumulative summary, single release+date 0.6s 0.11s 5.5x

Test plan

  • make lint passes
  • make test passes
  • make e2e passes (108 tests, 1 skipped)
  • sippy migrate creates partitioned tables on staging
  • sippy backfill creates partitions via gopar and populates data correctly
  • Partition names verified under 62-char PostgreSQL identifier limit

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added a CLI backfill command to backfill daily, totals, and cumulative summary data over a specified date range.
    • Added a batch backfill utility script with dry-run and progress reporting.
  • Improvements
    • Refresh now updates daily, totals, and cumulative summaries in a single flow, with an option to refresh only when empty.
    • Seeding now uses date-aligned backfill for derived data before running a full refresh.
    • Database now manages additional partitioned summary tables for totals and cumulative summaries.
  • Bug Fixes
    • Refresh failures are now surfaced and propagated more reliably.

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: automatic mode

@openshift-ci-robot

openshift-ci-robot commented Jul 12, 2026

Copy link
Copy Markdown

@mstaeble: This pull request references TRT-2741 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Summary

  • Adds three new LIST(release)->RANGE(date) partitioned tables: test_daily_totals, test_cumulative_summaries, variant_cumulative_summaries
  • Tables store pre-aggregated daily totals and running prefix sums, enabling sub-second queries for any arbitrary date range via prefix sum subtraction
  • Phase 1 is additive only: new tables are populated alongside existing test_daily_summaries. Nothing reads from them yet.
  • Includes sippy backfill CLI command and backfill-summaries.sh script for populating the tables
  • RefreshData now returns errors and short-circuits on failure

Test plan

  • make lint passes
  • make test passes
  • make e2e passes (108 tests, 1 skipped)
  • Deployed to staging, ran sippy migrate, verified partitioned tables created
  • Full 91-day backfill completed on staging, data verified correct against existing test_daily_summaries
  • Benchmarked: install page query goes from 9.5s (matview) to 200ms (prefix sum), CR ad-hoc queries from 47s to 3.4s

🤖 Generated with Claude Code

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jul 12, 2026
@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Adds civil-date daily and cumulative summary aggregation, partitioned storage, refresh orchestration, and CLI/OpenShift backfill workflows.

Changes

Summary pipeline

Layer / File(s) Summary
Partitioned summary storage
pkg/db/migrations/*, pkg/db/models/prow.go, pkg/db/db.go
Adds partitioned daily-total and cumulative-summary tables, models, indexes, migration registration, and partition management.
Civil-date daily aggregation
pkg/db/dailysummary/*
Refactors aggregation to civil dates and adds refresh/backfill flows for daily summaries and totals.
Cumulative summary rollups
pkg/db/cumulativesummary/*
Adds bounded incremental refresh, explicit backfill, cumulative prefix-sum upserts, and date-range/error tests.
Refresh orchestration and integrations
pkg/sippyserver/server.go, cmd/sippy/*, scripts/updatesuites.go, pkg/flags/postgres_benchmarking_test.go
Sequences daily, totals, cumulative, and materialized-view refreshes through RefreshOptions, updating callers and error handling.
Backfill command and batch workflow
cmd/sippy/backfill.go, cmd/sippy/main.go, scripts/backfill-summaries.sh
Adds validated date-range backfill execution and batched OpenShift pod orchestration.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Operator
  participant BackfillScript
  participant BackfillCommand
  participant PostgreSQL
  Operator->>BackfillScript: provide table and batching options
  BackfillScript->>BackfillCommand: launch sippy backfill with date range
  BackfillCommand->>PostgreSQL: ensure partitions
  BackfillCommand->>PostgreSQL: write selected summary table
Loading

Possibly related PRs

  • openshift/sippy#3659: Updates overlapping daily-summary refresh integration points and RefreshData call behavior.

Suggested reviewers: smg247, xueqzhan


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (1 error, 3 warnings)

Check name Status Explanation Resolution
No-Sensitive-Data-In-Logs ❌ Error scripts/backfill-summaries.sh echoes the auto-detected image (Using image: $IMAGE), which can reveal internal registry hostnames. Stop printing the image, or redact the registry/host portion before echoing. Keep other logs limited to non-sensitive dates/table names.
Docstring Coverage ⚠️ Warning Docstring coverage is 20.83% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Test Coverage For New Features ⚠️ Warning New backfill CLI and sippyserver wrappers lack *_test.go coverage; dailysummary helpers like buildInsertSQL/buildOnConflictClause are also untested. Add unit tests for NewBackfillCommand/flag parsing, sippyserver.RefreshData/BackfillData dispatch/error paths, and dailysummary wrappers/helpers like buildInsertSQL/buildOnConflictClause.
Feature Documentation ⚠️ Warning PR adds new backfill/partitioned-summary flows but changes no docs; the only docs/features page is unrelated symptoms docs. Add or update a docs/features page covering the new partitioned-summary tables, backfill CLI, and refresh/backfill data flow.
✅ Passed checks (17 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding partitioned prefix-sum tables to optimize matview refreshes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Go Error Handling ✅ Passed New Go paths wrap errors with %w, propagate failures, and guard nil cache/summary pointers; panics are limited to fatal CLI startup paths.
Sql Injection Prevention ✅ Passed New SQL uses placeholders; backfill table input is whitelisted before dispatch, and dynamic identifiers come from internal constants, not user input.
Excessive Css In React Should Use Styles ✅ Passed No React/JSX files were changed in this PR; the diff is backend CLI/DB code, so the inline-style rule is not applicable.
Single Responsibility And Clear Naming ✅ Passed The new packages and types are cohesive and specifically named; orchestration stays at the top level, while detailed work is delegated to focused helpers.
Stable And Deterministic Test Names ✅ Passed No test titles include generated or dynamic values; the added tests use static Go names and no t.Run/formatted labels.
Test Structure And Quality ✅ Passed Touched tests are plain unit tests using fakes only; no Ginkgo, cluster resources, or waits, and no cleanup/timeouts issues were found.
Microshift Test Compatibility ✅ Passed The PR adds only plain Go unit tests; no new Ginkgo e2e specs or MicroShift-sensitive APIs/features were introduced.
Single Node Openshift (Sno) Test Compatibility ✅ Passed No new Ginkgo/e2e tests were added; the changed test files are standard Go unit tests and contain no SNO-sensitive assumptions.
Topology-Aware Scheduling Compatibility ✅ Passed PR only changes CLI/db/scripts and uses oc run with no node selectors, affinity, PDBs, or spread constraints; no deployment/controller scheduling changes.
Ote Binary Stdout Contract ✅ Passed No PR changes add stdout writes in main/init/suite setup; new backfill command uses logrus, and cmd/sippy/main.go only registers it.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed The diff adds only unit/benchmark tests; no new Ginkgo e2e specs, IPv4 literals, or public internet dependencies were found.
No-Weak-Crypto ✅ Passed Changed files show no MD5/SHA1/DES/RC4/3DES/Blowfish/ECB or secret-comparison usage; only SHA-256 schema hashing appears, which is not weak.
Container-Privileges ✅ Passed No changed manifest or script introduces privileged:true, hostPID/hostNetwork/hostIPC, allowPrivilegeEscalation:true, SYS_ADMIN, or root/runAsNonRoot:false settings.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 12, 2026
@openshift-ci

openshift-ci Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@mstaeble mstaeble force-pushed the trt-2741-prefix-sum-tables branch from 8d46f4f to 844e9a6 Compare July 12, 2026 16:01
@mstaeble mstaeble changed the title TRT-2741: Add partitioned prefix sum tables for matview refresh optimization [WIP] TRT-2741: Add partitioned prefix sum tables for matview refresh optimization Jul 12, 2026
@mstaeble mstaeble force-pushed the trt-2741-prefix-sum-tables branch 2 times, most recently from 30b569d to ab4daf2 Compare July 12, 2026 18:30

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (7)
pkg/db/dailysummary/dailysummary.go (3)

200-209: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider a brief godoc for startDateFromMax.

The function always caps the returned start at yesterday even when maxSummary is more recent (or invalid/in the future) — this "always re-process at least yesterday+today" behavior isn't obvious from the name alone.

📝 Suggested doc comment
+// startDateFromMax returns the earliest date to re-aggregate. It always
+// includes at least yesterday and today (since "today" data is still
+// arriving), and falls back to defaultLookbackDays when the table is empty.
 func startDateFromMax(maxSummary *civil.Date, today civil.Date) civil.Date {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/db/dailysummary/dailysummary.go` around lines 200 - 209, Add a brief Go
doc comment immediately above startDateFromMax describing that it derives the
processing start date and caps maxSummary at yesterday, ensuring yesterday and
today are reprocessed; mention the default lookback behavior when maxSummary is
nil.

Source: Path instructions


23-60: 🔒 Security & Privacy | 🔵 Trivial | 💤 Low value

Identifier interpolation via fmt.Sprintf — safe here, but worth a defensive allow-list.

buildInsertSQL/buildOnConflictClause (and MaxSummaryDate at line 220) interpolate tableName/dateColumn into SQL text via fmt.Sprintf. Since these are compile-time literals from the two pgStore{...} construction sites in this file, there's no injection path today. As per path instructions, database/sql calls should use placeholders and avoid fmt.Sprintf in queries; since identifiers can't be parameterized, consider at least validating tableName/dateColumn against a small allow-list inside these helpers as defense-in-depth against a future caller passing a non-literal value.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/db/dailysummary/dailysummary.go` around lines 23 - 60, Add
defense-in-depth validation in buildInsertSQL and buildOnConflictClause, and
apply the same validation to MaxSummaryDate, restricting tableName and
dateColumn to the known allowed identifiers before interpolating them into SQL.
Preserve the existing SQL generation for valid compile-time values and reject or
fail safely for unsupported identifiers.

Source: Path instructions


110-167: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

backfillSummaries and doAggregate are near-duplicate day-loop implementations.

Both query releases, log identical fields, loop day-by-day calling aggregateReleases, and log elapsed time — differing only in log level (Info vs Debug) and the error-message prefix ("backfilling" vs "aggregating"). Consider extracting the shared day-loop into one helper parameterized by a log level/verb, reducing duplicated control flow.

♻️ Suggested consolidation
func processDateRange(store summaryStore, releases []string, startDate, endDate civil.Date, skipConflictDetection bool, verb string, logFn func(args ...interface{})) error {
	for date := startDate; !date.After(endDate); date = date.AddDays(1) {
		dayStart := time.Now()
		if err := aggregateReleases(store, releases, date, date, skipConflictDetection); err != nil {
			return fmt.Errorf("%s %s: %w", verb, date, err)
		}
		log.WithFields(log.Fields{"date": date, "elapsed": time.Since(dayStart)}).Info("processed date")
	}
	return nil
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/db/dailysummary/dailysummary.go` around lines 110 - 167, Extract the
duplicated date-processing loop from backfillSummaries and doAggregate into a
shared helper, such as processDateRange, parameterized by releases,
skipConflictDetection, and the operation verb. Preserve each caller’s error
prefix and per-day log level (Info for backfill, Debug for aggregation), then
have both functions invoke the helper while retaining their existing range-level
logging.
pkg/db/dailysummary/dailysummary_test.go (1)

187-207: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use sets.New[string]() instead of map[string]bool.

seen := make(map[string]bool) is a hand-rolled set for tracking processed releases. As per coding guidelines, k8s.io/apimachinery/pkg/util/sets (e.g. sets.New[string]()) should be used instead of map[string]bool for this pattern.

♻️ Suggested fix
-	seen := make(map[string]bool)
+	seen := sets.New[string]()
 	for _, call := range calls {
-		seen[call.release] = true
+		seen.Insert(call.release)
 		assert.Equal(t, call.start, call.end, "each call should be a single day")
 	}
 	for _, rel := range releases {
-		assert.True(t, seen[rel], "release %s not processed", rel)
+		assert.True(t, seen.Has(rel), "release %s not processed", rel)
 	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/db/dailysummary/dailysummary_test.go` around lines 187 - 207, In
TestRefresh_ProcessesAllReleasesPerDay, replace the hand-rolled seen map with a
k8s.io/apimachinery/pkg/util/sets Set initialized via sets.New[string](). Add
each call.release using the set API and update the release-presence assertion to
use the set’s membership method.

Source: Coding guidelines

pkg/db/db.go (1)

32-33: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Table-name constants duplicated as raw literals elsewhere.

partitionedTableTestDailyTotals/partitionedTableTestCumulativeSummaries are unexported here, so pkg/db/dailysummary/dailysummary.go ("test_daily_totals") and pkg/db/cumulativesummary/cumulative_summary.go ("test_daily_totals", "test_cumulative_summaries") must re-declare the same strings as bare literals. A future rename here would silently desync from those packages (compiles fine, breaks at runtime).

Consider exporting these as shared constants (e.g. in pkg/db or a small shared package) so all three files reference one source of truth.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/db/db.go` around lines 32 - 33, Export the partitioned table-name
constants currently defined in db.go, then update dailysummary.go and
cumulative_summary.go to reference those shared db constants instead of
repeating raw table-name literals. Preserve the existing names and table
mappings while establishing one source of truth for both daily and cumulative
summary tables.
pkg/db/cumulativesummary/cumulative_summary.go (1)

100-120: 🚀 Performance & Scalability | 🔵 Trivial

Ensure MAX(date) on the new partitioned tables uses an index-friendly plan.

MaxCumulativeSummaryDate/MaxDailySummaryDate run an unfiltered MAX(date) over partitioned tables on every refresh. Worth confirming this reliably uses a per-partition index scan (e.g. via enable_partitionwise_aggregate or a backward index scan on the newest partition) rather than scanning every partition, especially as partition count grows over time.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/db/cumulativesummary/cumulative_summary.go` around lines 100 - 120,
Update MaxCumulativeSummaryDate and MaxDailySummaryDate so MAX(date) on the
partitioned tables uses an index-friendly per-partition plan, such as enabling
partitionwise aggregation or issuing a backward index scan against the newest
partition. Verify the resulting queries avoid scanning every partition as
partition count increases while preserving the existing return and error
behavior.
pkg/db/cumulativesummary/date_range_test.go (1)

1-61: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

LGTM! The tests cover all main branches of resolveStartDate with descriptive names and a fixed testToday for determinism.

Optionally, these could be consolidated into a table-driven test for conciseness and easier extension, per the project's preference for table-driven tests.

♻️ Optional table-driven refactor
 func TestResolveStartDate(t *testing.T) {
-	earliestChanged := testToday.AddDays(-3)
-	result := resolveStartDate(earliestChanged, nil, testToday)
-	assert.Equal(t, earliestChanged, result)
-}
-
-func TestResolveStartDate_UsesMaxPlusOneWhenEarlier(t *testing.T) {
-	earliestChanged := testToday.AddDays(-1)
-	maxExisting := testToday.AddDays(-5)
-	result := resolveStartDate(earliestChanged, &maxExisting, testToday)
-	assert.Equal(t, maxExisting.AddDays(1), result)
-}
-
-func TestResolveStartDate_UsesEarliestChangedWhenEarlierThanMax(t *testing.T) {
-	earliestChanged := testToday.AddDays(-5)
-	maxExisting := testToday.AddDays(-2)
-	result := resolveStartDate(earliestChanged, &maxExisting, testToday)
-	assert.Equal(t, earliestChanged, result)
-}
-
-func TestResolveStartDate_ClampsToFloor(t *testing.T) {
-	earliestChanged := testToday.AddDays(-30)
-	result := resolveStartDate(earliestChanged, nil, testToday)
-	assert.Equal(t, testToday.AddDays(-maxAutoFillDays), result)
-}
-
-func TestResolveStartDate_ClampsMaxPlusOneToFloor(t *testing.T) {
-	earliestChanged := testToday.AddDays(-1)
-	maxExisting := testToday.AddDays(-30)
-	result := resolveStartDate(earliestChanged, &maxExisting, testToday)
-	assert.Equal(t, testToday.AddDays(-maxAutoFillDays), result)
-}
-
-func TestResolveStartDate_DoesNotClampWhenWithinFloor(t *testing.T) {
-	earliestChanged := testToday.AddDays(-7)
-	result := resolveStartDate(earliestChanged, nil, testToday)
-	assert.Equal(t, earliestChanged, result)
+	tests := []struct {
+		name            string
+		earliestChanged civil.Date
+		maxExisting     *civil.Date
+		want            civil.Date
+	}{
+		{"UsesEarliestChanged", testToday.AddDays(-3), nil, testToday.AddDays(-3)},
+		{"UsesMaxPlusOneWhenEarlier", testToday.AddDays(-1), ptrDate(testToday.AddDays(-5)), testToday.AddDays(-4)},
+		{"UsesEarliestChangedWhenEarlierThanMax", testToday.AddDays(-5), ptrDate(testToday.AddDays(-2)), testToday.AddDays(-5)},
+		{"ClampsToFloor", testToday.AddDays(-30), nil, testToday.AddDays(-maxAutoFillDays)},
+		{"ClampsMaxPlusOneToFloor", testToday.AddDays(-1), ptrDate(testToday.AddDays(-30)), testToday.AddDays(-maxAutoFillDays)},
+		{"DoesNotClampWhenWithinFloor", testToday.AddDays(-7), nil, testToday.AddDays(-7)},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			assert.Equal(t, tt.want, resolveStartDate(tt.earliestChanged, tt.maxExisting, testToday))
+		})
+	}
 }
+
+func ptrDate(d civil.Date) *civil.Date { return &d }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/db/cumulativesummary/date_range_test.go` around lines 1 - 61, Optionally
consolidate the six resolveStartDate tests into a single table-driven test,
preserving each existing scenario, expected result, descriptive case names, and
the fixed testToday value. Keep the test focused on resolveStartDate without
changing production behavior.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cmd/sippy/backfill.go`:
- Around line 67-70: Wrap the error returned by GetDBClient in the backfill flow
with call-site context using fmt.Errorf and the %w verb, while preserving the
existing early return behavior and error chain.
- Around line 43-90: Validate f.Table against the known supported table names
immediately after the existing required-field checks and before parsing dates or
obtaining the DB client. Use k8s.io/apimachinery/pkg/util/sets to define/check
the supported table set, return a clear error for unsupported values, and leave
valid-table backfill behavior unchanged.

In `@pkg/db/cumulativesummary/cumulative_summary.go`:
- Around line 29-34: Update Backfill to require a continuous cumulative boundary
before calling refreshDateRange: verify that startDate-1 exists for every
release, fail fast when any prior-day boundary is missing, and avoid mutating
cumulative data in that case. Preserve normal backfill behavior when all release
boundaries are present.

In `@pkg/sippyserver/server.go`:
- Around line 405-430: Update refreshMaterializedViews and its refreshMatview
path to return and propagate materialized-view refresh errors instead of only
logging them. In RefreshData, handle the returned error from
refreshMaterializedViews and return it with context, preserving the existing
successful refresh flow.
- Around line 432-451: Define shared constants for the supported table names and
replace the duplicated literals in BackfillData and the corresponding seed-data
dispatch code. Add unit tests covering RefreshData and BackfillData dispatch for
each supported table and asserting unknown table names return an error.

In `@scripts/backfill-summaries.sh`:
- Around line 86-89: Update the batch_end_offset lower-bound clamp in the
backfill calculation to use 1 instead of 0, preventing the final batch from
including today when DAYS is not divisible by BATCH. Preserve the existing
offset calculation and all other batching behavior.
- Around line 107-125: Update the oc run invocation in the backfill execution
loop to explicitly redirect standard input from /dev/null while preserving --rm
-i and the existing output filtering. Ensure interactive shell usage cannot
leave the command waiting for input and stall the loop.

---

Nitpick comments:
In `@pkg/db/cumulativesummary/cumulative_summary.go`:
- Around line 100-120: Update MaxCumulativeSummaryDate and MaxDailySummaryDate
so MAX(date) on the partitioned tables uses an index-friendly per-partition
plan, such as enabling partitionwise aggregation or issuing a backward index
scan against the newest partition. Verify the resulting queries avoid scanning
every partition as partition count increases while preserving the existing
return and error behavior.

In `@pkg/db/cumulativesummary/date_range_test.go`:
- Around line 1-61: Optionally consolidate the six resolveStartDate tests into a
single table-driven test, preserving each existing scenario, expected result,
descriptive case names, and the fixed testToday value. Keep the test focused on
resolveStartDate without changing production behavior.

In `@pkg/db/dailysummary/dailysummary_test.go`:
- Around line 187-207: In TestRefresh_ProcessesAllReleasesPerDay, replace the
hand-rolled seen map with a k8s.io/apimachinery/pkg/util/sets Set initialized
via sets.New[string](). Add each call.release using the set API and update the
release-presence assertion to use the set’s membership method.

In `@pkg/db/dailysummary/dailysummary.go`:
- Around line 200-209: Add a brief Go doc comment immediately above
startDateFromMax describing that it derives the processing start date and caps
maxSummary at yesterday, ensuring yesterday and today are reprocessed; mention
the default lookback behavior when maxSummary is nil.
- Around line 23-60: Add defense-in-depth validation in buildInsertSQL and
buildOnConflictClause, and apply the same validation to MaxSummaryDate,
restricting tableName and dateColumn to the known allowed identifiers before
interpolating them into SQL. Preserve the existing SQL generation for valid
compile-time values and reject or fail safely for unsupported identifiers.
- Around line 110-167: Extract the duplicated date-processing loop from
backfillSummaries and doAggregate into a shared helper, such as
processDateRange, parameterized by releases, skipConflictDetection, and the
operation verb. Preserve each caller’s error prefix and per-day log level (Info
for backfill, Debug for aggregation), then have both functions invoke the helper
while retaining their existing range-level logging.

In `@pkg/db/db.go`:
- Around line 32-33: Export the partitioned table-name constants currently
defined in db.go, then update dailysummary.go and cumulative_summary.go to
reference those shared db constants instead of repeating raw table-name
literals. Preserve the existing names and table mappings while establishing one
source of truth for both daily and cumulative summary tables.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: ac6762e2-c6a7-4607-963e-0cfc2f15918b

📥 Commits

Reviewing files that changed from the base of the PR and between 9370b21 and ab4daf2.

📒 Files selected for processing (20)
  • cmd/sippy/backfill.go
  • cmd/sippy/load.go
  • cmd/sippy/main.go
  • cmd/sippy/refresh.go
  • cmd/sippy/seed_data.go
  • pkg/db/cumulativesummary/cumulative_summary.go
  • pkg/db/cumulativesummary/cumulative_summary_test.go
  • pkg/db/cumulativesummary/date_range.go
  • pkg/db/cumulativesummary/date_range_test.go
  • pkg/db/dailysummary/dailysummary.go
  • pkg/db/dailysummary/dailysummary_test.go
  • pkg/db/db.go
  • pkg/db/migrations/000006_partition_cumulative_tables.down.sql
  • pkg/db/migrations/000006_partition_cumulative_tables.up.sql
  • pkg/db/migrations/MANIFEST
  • pkg/db/models/prow.go
  • pkg/flags/postgres_benchmarking_test.go
  • pkg/sippyserver/server.go
  • scripts/backfill-summaries.sh
  • scripts/updatesuites.go

Comment thread cmd/sippy/backfill.go
Comment thread cmd/sippy/backfill.go
Comment thread pkg/db/cumulativesummary/cumulative_summary.go
Comment thread pkg/sippyserver/server.go
Comment thread pkg/sippyserver/server.go
Comment thread scripts/backfill-summaries.sh
Comment thread scripts/backfill-summaries.sh Outdated
@mstaeble mstaeble force-pushed the trt-2741-prefix-sum-tables branch from ab4daf2 to cfc1cec Compare July 12, 2026 19:38
@mstaeble mstaeble changed the title [WIP] TRT-2741: Add partitioned prefix sum tables for matview refresh optimization TRT-2741: Add partitioned prefix sum tables for matview refresh optimization Jul 12, 2026
@mstaeble mstaeble marked this pull request as ready for review July 12, 2026 19:43
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 12, 2026
@openshift-ci openshift-ci Bot requested review from smg247 and xueqzhan July 12, 2026 19:43
@mstaeble mstaeble force-pushed the trt-2741-prefix-sum-tables branch from cfc1cec to d5e4e2f Compare July 12, 2026 20:58

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/db/dailysummary/dailysummary_test.go (1)

93-103: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Strengthen the assertion in TestRefresh_IncrementalCapsAtYesterday.

The test name implies verifying that the refresh caps at yesterday, but the assertion calls[0].start.Before(future) is trivially true for any reasonable date. Add an assertion that the end date is at most yesterday:

 	require.NotEmpty(t, calls)
-	assert.True(t, calls[0].start.Before(future))
+	assert.True(t, calls[0].start.Before(future))
+	today := civil.DateOf(time.Now().UTC())
+	assert.True(t, calls[len(calls)-1].end.Before(today),
+		"end date should be capped at yesterday, not extend to today or beyond")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/db/dailysummary/dailysummary_test.go` around lines 93 - 103, Strengthen
TestRefresh_IncrementalCapsAtYesterday by asserting that the first refresh
call’s end date does not exceed yesterday, using the existing date
representation and current-date helper. Keep the existing non-empty and
start-before-future assertions unchanged.
🧹 Nitpick comments (1)
pkg/db/models/prow.go (1)

187-220: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider using civil.Date consistently for date-only columns.

TestDailyTotal.Date uses time.Time while TestCumulativeSummary.Date uses civil.Date. Both map to PostgreSQL date correctly, but civil.Date is semantically more precise for date-only columns and matches the downstream code pattern (e.g., cumulativesummary.go uses civil.Date throughout). Using civil.Date in both models would improve consistency across the new partitioned summary tables.

This is optional since TestDailyTotal mirrors the existing TestDailySummary which also uses time.Time, and the downstream write paths use raw SQL rather than GORM model methods.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/db/models/prow.go` around lines 187 - 220, Update TestDailyTotal.Date
from time.Time to civil.Date while preserving its date column mapping and
constraints, matching TestCumulativeSummary.Date and downstream date-only usage.
Leave the other model fields and schema tags unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@pkg/db/dailysummary/dailysummary_test.go`:
- Around line 93-103: Strengthen TestRefresh_IncrementalCapsAtYesterday by
asserting that the first refresh call’s end date does not exceed yesterday,
using the existing date representation and current-date helper. Keep the
existing non-empty and start-before-future assertions unchanged.

---

Nitpick comments:
In `@pkg/db/models/prow.go`:
- Around line 187-220: Update TestDailyTotal.Date from time.Time to civil.Date
while preserving its date column mapping and constraints, matching
TestCumulativeSummary.Date and downstream date-only usage. Leave the other model
fields and schema tags unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: f733f060-15cf-46cb-867c-d7eaa31e7e02

📥 Commits

Reviewing files that changed from the base of the PR and between cfc1cec and d5e4e2f.

📒 Files selected for processing (20)
  • cmd/sippy/backfill.go
  • cmd/sippy/load.go
  • cmd/sippy/main.go
  • cmd/sippy/refresh.go
  • cmd/sippy/seed_data.go
  • pkg/db/cumulativesummary/cumulative_summary.go
  • pkg/db/cumulativesummary/cumulative_summary_test.go
  • pkg/db/cumulativesummary/date_range.go
  • pkg/db/cumulativesummary/date_range_test.go
  • pkg/db/dailysummary/dailysummary.go
  • pkg/db/dailysummary/dailysummary_test.go
  • pkg/db/db.go
  • pkg/db/migrations/000006_partition_cumulative_tables.down.sql
  • pkg/db/migrations/000006_partition_cumulative_tables.up.sql
  • pkg/db/migrations/MANIFEST
  • pkg/db/models/prow.go
  • pkg/flags/postgres_benchmarking_test.go
  • pkg/sippyserver/server.go
  • scripts/backfill-summaries.sh
  • scripts/updatesuites.go
🚧 Files skipped from review as they are similar to previous changes (14)
  • pkg/db/cumulativesummary/date_range_test.go
  • cmd/sippy/backfill.go
  • pkg/db/migrations/000006_partition_cumulative_tables.up.sql
  • pkg/db/cumulativesummary/date_range.go
  • pkg/db/migrations/MANIFEST
  • pkg/flags/postgres_benchmarking_test.go
  • pkg/db/cumulativesummary/cumulative_summary.go
  • pkg/db/db.go
  • cmd/sippy/refresh.go
  • scripts/backfill-summaries.sh
  • pkg/db/dailysummary/dailysummary.go
  • scripts/updatesuites.go
  • pkg/db/cumulativesummary/cumulative_summary_test.go
  • pkg/sippyserver/server.go

@mstaeble mstaeble force-pushed the trt-2741-prefix-sum-tables branch 3 times, most recently from baac3a7 to 4039a46 Compare July 12, 2026 21:49
@mstaeble

Copy link
Copy Markdown
Contributor Author

@coderabbitai resolve

@openshift-ci openshift-ci Bot added the ready-for-human-review Indicates a PR has been reviewed by automated tools and is ready for human review label Jul 12, 2026
@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Comments resolved and changes approved.

@mstaeble

Copy link
Copy Markdown
Contributor Author

/test agentic-images

@mstaeble

Copy link
Copy Markdown
Contributor Author

/test images

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling required tests:
/test e2e

Comment thread pkg/db/models/prow.go
ProwJobID uint `gorm:"column:prow_job_id;not null"`
SuiteID uint `gorm:"column:suite_id;not null;default:0"`
Release string `gorm:"column:release;not null"`
Date civil.Date `gorm:"column:date;type:date;not null"`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noting the addition of civil.Date and the existing usage of time.Time including TestDailySummary for dates. Do you see us standardizing on civil.Date over time? If not is it worth introducing here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I am standardizing on civil.Date as the type used wherever dates are used.

#3716 has the wider effort.

Comment thread cmd/sippy/seed_data.go Outdated
seedStart := time.Now().Add(-190 * 24 * time.Hour)
sippyserver.RefreshData(dbc, nil, false, dailysummary.Options{StartOverride: &seedStart})
seedToday := civil.DateOf(time.Now().UTC())
seedStart := seedToday.AddDays(-91)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any idea why it went back 190 days previously? I'm fine with 91 if all works ok.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 4.19 release data is from -180 to -150 days ago.
The 4.20 release data is from -120 to -90 days ago.
The -190 days covered those releases.

I think that I changed this date to -91 days in the past for consistency with what would be produced in the real database. But it does mean that we would not be able to do CR queries against 4.19 and 4.20 data in phase 3 when the CR queries use the summary tables.

I'v changed it back to use -190 days.

…ization

Introduces two new LIST(release)->RANGE(date) partitioned tables that store
pre-aggregated daily totals and running prefix sums. These tables enable
sub-second queries for any arbitrary date range via prefix sum subtraction,
eliminating the need for matview refreshes that currently take 7+ minutes.

New tables:
- test_daily_totals: partitioned replacement for test_daily_summaries
- test_cumulative_summaries: running totals from test_daily_totals

Variant grouping happens at query time via JOIN to prow_jobs, which keeps
variant changes immediately reflected without any rebuild step.

Phase 1 is additive only: the new tables are populated alongside the existing
test_daily_summaries table. Nothing reads from them yet. Later phases will
switch query paths to use these tables and remove the old matview dependency.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@mstaeble mstaeble force-pushed the trt-2741-prefix-sum-tables branch from 4039a46 to f1c9d75 Compare July 13, 2026 19:18

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
pkg/db/dailysummary/dailysummary.go (1)

110-167: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

backfillSummaries and doAggregate are near-duplicate implementations.

Both query releases, compute days, log start/end/day/release counts, loop day-by-day calling aggregateReleases, and log a per-date summary — differing only in the log messages/levels and whether skipConflictDetection is hardcoded to false vs. passed through. This duplication risks divergence (e.g., a future fix to one loop not applied to the other).

♻️ Suggested consolidation
-func backfillSummaries(store summaryStore, startDate, endDate civil.Date) error {
-	loadStart := time.Now()
-	releases, err := store.Releases()
-	if err != nil {
-		return fmt.Errorf("querying releases: %w", err)
-	}
-
-	days := endDate.DaysSince(startDate) + 1
-	log.WithFields(log.Fields{
-		"start":    startDate,
-		"end":      endDate,
-		"days":     days,
-		"releases": len(releases),
-	}).Info("backfilling daily summaries")
-
-	for date := startDate; !date.After(endDate); date = date.AddDays(1) {
-		dayStart := time.Now()
-		if err := aggregateReleases(store, releases, date, date, false); err != nil {
-			return fmt.Errorf("backfilling %s: %w", date, err)
-		}
-		log.WithFields(log.Fields{
-			"date":    date,
-			"elapsed": time.Since(dayStart),
-		}).Info("backfilled daily summaries for date")
-	}
-
-	log.WithField("elapsed", time.Since(loadStart)).Info("daily summary backfill complete")
-	return nil
-}
-
-func doAggregate(store summaryStore, startDate, endDate civil.Date, skipConflictDetection bool, loadStart time.Time) error {
-	releases, err := store.Releases()
-	if err != nil {
-		return fmt.Errorf("querying releases: %w", err)
-	}
-
-	days := endDate.DaysSince(startDate) + 1
-	log.WithFields(log.Fields{
-		"start":    startDate,
-		"end":      endDate,
-		"days":     days,
-		"releases": len(releases),
-	}).Info("aggregating daily summaries")
-
-	for date := startDate; !date.After(endDate); date = date.AddDays(1) {
-		dayStart := time.Now()
-		if err := aggregateReleases(store, releases, date, date, skipConflictDetection); err != nil {
-			return fmt.Errorf("aggregating %s: %w", date, err)
-		}
-		log.WithFields(log.Fields{
-			"date":    date,
-			"elapsed": time.Since(dayStart),
-		}).Debug("aggregated daily summaries for date")
-	}
-
-	log.WithField("elapsed", time.Since(loadStart)).Info("daily summary refresh complete")
-	return nil
-}
+func aggregateDateRange(store summaryStore, startDate, endDate civil.Date, skipConflictDetection bool, action string, perDateLevel log.Level) error {
+	loadStart := time.Now()
+	releases, err := store.Releases()
+	if err != nil {
+		return fmt.Errorf("querying releases: %w", err)
+	}
+
+	days := endDate.DaysSince(startDate) + 1
+	log.WithFields(log.Fields{
+		"start":    startDate,
+		"end":      endDate,
+		"days":     days,
+		"releases": len(releases),
+	}).Infof("%s daily summaries", action)
+
+	for date := startDate; !date.After(endDate); date = date.AddDays(1) {
+		dayStart := time.Now()
+		if err := aggregateReleases(store, releases, date, date, skipConflictDetection); err != nil {
+			return fmt.Errorf("%s %s: %w", action, date, err)
+		}
+		log.WithFields(log.Fields{
+			"date":    date,
+			"elapsed": time.Since(dayStart),
+		}).Log(perDateLevel, action+"ed daily summaries for date")
+	}
+
+	log.WithField("elapsed", time.Since(loadStart)).Infof("daily summary %s complete", action)
+	return nil
+}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/db/dailysummary/dailysummary.go` around lines 110 - 167, Consolidate the
duplicated release-loading, range-logging, and day-by-day aggregation logic in
backfillSummaries and doAggregate into a shared helper. Parameterize the helper
for skipConflictDetection and the required overall/per-date log messages or
levels, then have both callers delegate to it while preserving their existing
error context and elapsed-time behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/db/dailysummary/dailysummary.go`:
- Around line 200-209: Update startDateFromMax to clamp any maxSummary older
than today.AddDays(-defaultLookbackDays) to that 14-day lookback boundary, while
preserving the existing yesterday behavior for recent summaries and the
empty-table fallback. Add a regression test covering a very stale maxSummary and
verifying the bounded start date used by refresh flows.

---

Nitpick comments:
In `@pkg/db/dailysummary/dailysummary.go`:
- Around line 110-167: Consolidate the duplicated release-loading,
range-logging, and day-by-day aggregation logic in backfillSummaries and
doAggregate into a shared helper. Parameterize the helper for
skipConflictDetection and the required overall/per-date log messages or levels,
then have both callers delegate to it while preserving their existing error
context and elapsed-time behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: ea4b77b5-026c-4d35-9746-d801a3a09c00

📥 Commits

Reviewing files that changed from the base of the PR and between d5e4e2f and f1c9d75.

📒 Files selected for processing (20)
  • cmd/sippy/backfill.go
  • cmd/sippy/load.go
  • cmd/sippy/main.go
  • cmd/sippy/refresh.go
  • cmd/sippy/seed_data.go
  • pkg/db/cumulativesummary/cumulative_summary.go
  • pkg/db/cumulativesummary/cumulative_summary_test.go
  • pkg/db/cumulativesummary/date_range.go
  • pkg/db/cumulativesummary/date_range_test.go
  • pkg/db/dailysummary/dailysummary.go
  • pkg/db/dailysummary/dailysummary_test.go
  • pkg/db/db.go
  • pkg/db/migrations/000006_partition_cumulative_tables.down.sql
  • pkg/db/migrations/000006_partition_cumulative_tables.up.sql
  • pkg/db/migrations/MANIFEST
  • pkg/db/models/prow.go
  • pkg/flags/postgres_benchmarking_test.go
  • pkg/sippyserver/server.go
  • scripts/backfill-summaries.sh
  • scripts/updatesuites.go
🚧 Files skipped from review as they are similar to previous changes (15)
  • cmd/sippy/main.go
  • pkg/db/migrations/MANIFEST
  • pkg/db/migrations/000006_partition_cumulative_tables.up.sql
  • pkg/db/models/prow.go
  • cmd/sippy/seed_data.go
  • cmd/sippy/load.go
  • cmd/sippy/refresh.go
  • pkg/db/db.go
  • scripts/backfill-summaries.sh
  • pkg/sippyserver/server.go
  • pkg/db/cumulativesummary/cumulative_summary_test.go
  • cmd/sippy/backfill.go
  • scripts/updatesuites.go
  • pkg/flags/postgres_benchmarking_test.go
  • pkg/db/cumulativesummary/cumulative_summary.go

Comment on lines +200 to 209
func startDateFromMax(maxSummary *civil.Date, today civil.Date) civil.Date {
yesterday := today.AddDays(-1)
if maxSummary != nil {
if maxSummary.Before(yesterday) {
return *maxSummary, nil
return *maxSummary
}
return yesterday, nil
return yesterday
}

return now.AddDate(0, 0, -defaultLookbackDays), nil
return today.AddDays(-defaultLookbackDays)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

ast-grep outline pkg/db/dailysummary/dailysummary.go --view expanded

Repository: openshift/sippy

Length of output: 1784


🏁 Script executed:

ast-grep outline pkg/db/cumulativesummary/date_range.go --view expanded

Repository: openshift/sippy

Length of output: 331


🏁 Script executed:

rg -n "startDateFromMax|resolveStartDate|RefreshTotals|maxAutoFillDays|defaultLookbackDays" pkg/db -g '*.go'

Repository: openshift/sippy

Length of output: 2364


🏁 Script executed:

sed -n '190,215p' pkg/db/dailysummary/dailysummary.go

Repository: openshift/sippy

Length of output: 644


🏁 Script executed:

sed -n '1,80p' pkg/db/cumulativesummary/date_range.go

Repository: openshift/sippy

Length of output: 1110


🏁 Script executed:

sed -n '1,180p' pkg/db/dailysummary/dailysummary_test.go

Repository: openshift/sippy

Length of output: 4758


Clamp stale daily summary refreshes to the 14-day lookback
startDateFromMax only applies defaultLookbackDays when the table is empty; a stale maxSummary still drives an unbounded catch-up in refreshSummaries and RefreshTotals. Clamp older dates to today.AddDays(-defaultLookbackDays) here, and add a regression test for a very stale maxSummary.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/db/dailysummary/dailysummary.go` around lines 200 - 209, Update
startDateFromMax to clamp any maxSummary older than
today.AddDays(-defaultLookbackDays) to that 14-day lookback boundary, while
preserving the existing yesterday behavior for recent summaries and the
empty-table fallback. Add a regression test covering a very stale maxSummary and
verifying the bounded start date used by refresh flows.

Source: Learnings

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling required tests:
/test e2e

@openshift-ci

openshift-ci Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

@mstaeble: all tests passed!

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@neisw

neisw commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Jul 13, 2026
@openshift-ci

openshift-ci Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: mstaeble, neisw

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jul 13, 2026
@openshift-merge-bot openshift-merge-bot Bot merged commit 8876d58 into openshift:main Jul 13, 2026
10 checks passed
@mstaeble mstaeble deleted the trt-2741-prefix-sum-tables branch July 13, 2026 20:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lgtm Indicates that a PR is ready to be merged. ready-for-human-review Indicates a PR has been reviewed by automated tools and is ready for human review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants