Skip to content

fix: keep toStartOf* time filters inclusive regardless of dateRangeEndInclusive#1915

Open
sanjams2 wants to merge 1 commit intohyperdxio:mainfrom
sanjams2:fix/tostartof-exclusive-bounds
Open

fix: keep toStartOf* time filters inclusive regardless of dateRangeEndInclusive#1915
sanjams2 wants to merge 1 commit intohyperdxio:mainfrom
sanjams2:fix/tostartof-exclusive-bounds

Conversation

@sanjams2
Copy link

== Motivation ==

Time histograms on the search page silently drop data past an hour/minute boundary when the source timestampValueExpression includes a toStartOf* expression for primary key optimization.

== Details ==

When convertToTimeChartConfig aligns the date range to granularity it sets dateRangeEndInclusive: false, which is correct for the raw timestamp column (end was rounded up, so < gives equivalent coverage). But timeFilterExpr applies that same < uniformly to every expression in a compound timestampValueExpression. With a range ending at 04:08, this yields toStartOfHour(ts) < toStartOfHour(04:08) = < 04:00 — excluding the entire 04:xx hour.

The coarse filter exists only for index pruning; the raw column already enforces exact bounds. Making it wider by one interval is harmless, making it narrower drops real rows.

== Testing ==

  • yarn jest renderChartConfig.test.ts — 54 passed, 29 snapshots passed
  • Added cases for toStartOfHour with exclusive end, compound expr with exclusive end, and exclusive start

…dInclusive

== Motivation ==

Time histograms on the search page silently drop data past an hour/minute boundary when the source `timestampValueExpression` includes a `toStartOf*` expression for primary key optimization.

== Details ==

When `convertToTimeChartConfig` aligns the date range to granularity it sets `dateRangeEndInclusive: false`, which is correct for the raw timestamp column (end was rounded up, so `<` gives equivalent coverage). But `timeFilterExpr` applies that same `<` uniformly to every expression in a compound `timestampValueExpression`. With a range ending at `04:08`, this yields `toStartOfHour(ts) < toStartOfHour(04:08)` = `< 04:00` — excluding the entire `04:xx` hour.

The coarse filter exists only for index pruning; the raw column already enforces exact bounds. Making it wider by one interval is harmless, making it narrower drops real rows.

== Testing ==

- `yarn jest renderChartConfig.test.ts` — 54 passed, 29 snapshots passed
- Added cases for `toStartOfHour` with exclusive end, compound expr with exclusive end, and exclusive start
@changeset-bot
Copy link

changeset-bot bot commented Mar 14, 2026

🦋 Changeset detected

Latest commit: 3349461

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@hyperdx/common-utils Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link

vercel bot commented Mar 14, 2026

@sanjams2 is attempting to deploy a commit to the HyperDX Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions
Copy link
Contributor

PR Review

No critical issues found.

The fix is correct and well-reasoned:

  • The operator precedence on lines 636–637 (dateRangeStartInclusive || toStartOf ? '>=' : '>') evaluates as (dateRangeStartInclusive || toStartOf) ? '>=' : '>' since || binds tighter than ?: in JS — this is the intended behavior.
  • The logic correctly forces inclusive bounds when toStartOf is present, since the coarse index-pruning filter rounding down/up can silently drop an entire interval with strict operators.
  • Tests cover the key cases: toStartOf with exclusive end, compound expression with exclusive end, and toStartOf with exclusive start.

One minor observation: there's no test for a compound expression with dateRangeStartInclusive=false, but the fix is simple enough that the existing tests provide sufficient coverage.

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