Skip to content

fix(metrics): build the bucket series in FROM, not the select list - #433

Open
vyruss wants to merge 1 commit into
mainfrom
fix/generate-series-in-from
Open

fix(metrics): build the bucket series in FROM, not the select list#433
vyruss wants to merge 1 commit into
mainfrom
fix/generate-series-in-from

Conversation

@vyruss

@vyruss vyruss commented Aug 27, 2026

Copy link
Copy Markdown

Summary

The gap-filling bucket series in the metrics time-series queries is
built with generate_series in the select list. This moves it into the
FROM clause. The two forms return identical rows in PostgreSQL, so
this is a pure rewrite of the query text with no behaviour change.

The reason for the change is that a set-returning function in a select
list has no equivalent in DuckDB. When the metrics.* tables are read
through a view whose query is executed by DuckDB rather than
PostgreSQL, DuckDB's timestamp generate_series returns a LIST in that
position instead of a set, and the read fails with:

Conversion Error: Unimplemented type for cast
(TIMESTAMP WITH TIME ZONE -> TIMESTAMP WITH TIME ZONE[])

It is the placement that matters, not the arguments; the failure
reproduces with all-literal arguments. Moving the call into FROM
works on both backends, so the change is applied unconditionally
rather than behind a flag.

Changes

Both sites are the all_buckets CTE, in BuildMetricsQuery and
BuildDerivedMetricsQuery.

Before:

all_buckets AS (
    SELECT generate_series($3::timestamptz, $4::timestamptz, $1::interval) AS bucket_time
)

After:

all_buckets AS (
    SELECT bucket_time
    FROM generate_series($3::timestamptz, $4::timestamptz, $1::interval) AS g(bucket_time)
)
  • server/src/internal/metrics/query.go: both all_buckets CTEs.

  • server/src/internal/metrics/query_test.go: the existing derived
    query assertion checked only the generate_series(...) substring,
    which both forms contain; it now asserts the full FROM generate_series(...) AS g(bucket_time) form. An equivalent
    assertion is added to TestBuildMetricsQuery so the placement is
    pinned at both sites.

Testing

  • cd server && make test passes; gofmt, go vet, and
    golangci-lint run ./internal/metrics/... are all clean.

  • BuildMetricsQuery and BuildDerivedMetricsQuery are both at 100%
    statement coverage in go tool cover -func.

Summary by CodeRabbit

  • Bug Fixes
    • Improved metrics query compatibility while preserving gap-filled time buckets for standard and derived metrics.
  • Tests
    • Updated coverage to verify the generated time-series buckets are constructed correctly.

The gap-filling `all_buckets` CTE in the metrics time-series queries
called `generate_series` from the select list. A set-returning function
in that position has no DuckDB equivalent: DuckDB's timestamp
`generate_series` returns a LIST there rather than a set, so reading
the `metrics.*` tables through a view executed by DuckDB fails with
"Unimplemented type for cast (TIMESTAMP WITH TIME ZONE -> TIMESTAMP
WITH TIME ZONE[])".

Move the call into the `FROM` clause at both sites, in
`BuildMetricsQuery` and `BuildDerivedMetricsQuery`. The two forms
return identical rows in PostgreSQL, so the rewrite is
backend-agnostic and needs no conditional.

The derived-query test asserted only the `generate_series(...)`
substring, which both forms contain; it now pins the full `FROM
generate_series(...) AS g(bucket_time)` form, and `TestBuildMetricsQuery`
gains the same assertion so neither site can regress.
@vyruss
vyruss force-pushed the fix/generate-series-in-from branch from b3b420b to 38557ae Compare August 27, 2026 17:44
@coderabbitai

coderabbitai Bot commented Aug 27, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: e6bea989-93f8-4085-9ba7-6925be6c54d2

📥 Commits

Reviewing files that changed from the base of the PR and between 4584222 and 38557ae.

📒 Files selected for processing (2)
  • server/src/internal/metrics/query.go
  • server/src/internal/metrics/query_test.go

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


Walkthrough

Both metrics query builders now generate bucket timestamps through a FROM generate_series(...) AS g(bucket_time) clause. Tests verify this SQL structure for standard and derived metrics queries.

Changes

Metrics query generation

Layer / File(s) Summary
Bucket generation and validation
server/src/internal/metrics/query.go, server/src/internal/metrics/query_test.go
The standard and derived metrics queries select bucket_time from an explicitly aliased generate_series table source. Tests verify the updated SQL clauses.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Merge Risk: ⚪ Minimal · up to 38557

The change moves bucket-series construction into the SQL FROM clause to support DuckDB while preserving PostgreSQL results; no actionable merge-blocking risk remains after normal checks and review.

Suggested reviewers: susan-pgedge

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: moving the bucket series construction from the SELECT list to the FROM clause.
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.
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/generate-series-in-from

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

@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 0 duplication

Metric Results
Duplication 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@vyruss
vyruss requested a review from dpage August 28, 2026 15:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant