fix(sql): ensure FILL(LINEAR) respects the FROM clause#6790
fix(sql): ensure FILL(LINEAR) respects the FROM clause#6790bluestreak01 merged 3 commits intomasterfrom
FILL(LINEAR) respects the FROM clause#6790Conversation
SampleByInterpolateRecordCursorFactory (used for FILL(LINEAR)) was ignoring the FROM-TO clause when computing bucket boundaries. The factory and its inner cursor never received the sampleFromFunc / sampleToFunc parameters, so initTimestamps() fell back to calendar- aligned buckets (epoch-0 offset) instead of anchoring to the FROM timestamp. Pass sampleFromFunc / sampleToFunc through SqlCodeGenerator into the factory constructor and cursor. Update initTimestamps() to call sampler.setStart(from) when a FROM bound is present, matching the logic already used by AbstractNoRecordSampleByCursor. Co-Authored-By: Claude Opus 4.6 <[email protected]>
WalkthroughThis PR extends the SAMPLE BY interpolation functionality to support FROM/TO timestamp boundary functions, propagating these functions from the SQL code generator through the factory to the record cursor implementation. New fields and initialization logic are added to handle timestamp-based alignment when FROM/TO functions are provided. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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. Comment |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
core/src/main/java/io/questdb/griffin/engine/groupby/SampleByInterpolateRecordCursorFactory.java (1)
374-377: Consider movingsampleFromFunc.init()andsampleToFunc.init()intoparseParams()for consistency.
parseParams()already initializestimezoneNameFuncandoffsetFunc. Initializing the new functions outside of it breaks this pattern and could be missed ifparseParams()is overridden in a subclass.♻️ Proposed refactor — consolidate into parseParams()
parseParams(this, executionContext); - sampleFromFunc.init(managedCursor, executionContext); - sampleToFunc.init(managedCursor, executionContext); areTimestampsInitialized = false;In
parseParams():protected void parseParams(RecordCursor base, SqlExecutionContext executionContext) throws SqlException { timezoneNameFunc.init(base, executionContext); offsetFunc.init(base, executionContext); + sampleFromFunc.init(base, executionContext); + sampleToFunc.init(base, executionContext); rules = null;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@core/src/main/java/io/questdb/griffin/engine/groupby/SampleByInterpolateRecordCursorFactory.java` around lines 374 - 377, parseParams currently initializes timezoneNameFunc and offsetFunc but sampleFromFunc.init(...) and sampleToFunc.init(...) are called externally; move those two init calls into parseParams so all function initializations are consistent and won't be missed by subclasses overriding parseParams. Update parseParams to accept (or access) managedCursor and executionContext as needed, call sampleFromFunc.init(managedCursor, executionContext) and sampleToFunc.init(managedCursor, executionContext) there, remove the duplicate init calls from the caller (the block that sets areTimestampsInitialized = false), and ensure any subclasses of parseParams are updated if they override it.core/src/test/java/io/questdb/test/griffin/engine/groupby/SampleByTest.java (1)
6044-6044: Use underscore thousands separator in60000T.
60000Tappears on lines 6044, 6057, 6072, and 6352. Per coding guidelines, numbers with 5 or more digits must use underscores as thousands separators.Proposed fix (apply at all four locations)
- SAMPLE BY 60000T + SAMPLE BY 60_000TAs per coding guidelines: "Always use underscores as thousands separators in numbers of 5 digits or more in QuestDB SQL and implementation code."
Also applies to: 6057-6057, 6072-6072, 6352-6352
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@core/src/test/java/io/questdb/test/griffin/engine/groupby/SampleByTest.java` at line 6044, Replace the numeric literal using five digits without separators in the SAMPLE BY clauses: change every "SAMPLE BY 60000T" occurrence in SampleByTest (the SQL/text literal "SAMPLE BY 60000T") to use an underscore thousands separator ("SAMPLE BY 60_000T"); apply the same replacement for all other instances of 60000T in this file so numbers with 5+ digits follow the underscore separator rule.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@core/src/main/java/io/questdb/griffin/engine/groupby/SampleByInterpolateRecordCursorFactory.java`:
- Around line 265-269: The interpolate cursor currently ignores the query TO
boundary: ensure SampleByInterpolateRecordCursorFactory computes and uses
sampleToFunc and its type (sampleToFuncType) like other fill modes instead of
letting hiSample be only sampler.nextTimestamp(prevSample); fetch the TO
timestamp via sampleToFunc.getTimestamp(null), compute sampleToFuncType
(matching how sampleFromFuncType is set in the cursor), and cap hiSample with
that TO value before generating interpolated rows; also keep freeing
sampleToFunc in the existing cleanup path to avoid leaks.
---
Nitpick comments:
In
`@core/src/main/java/io/questdb/griffin/engine/groupby/SampleByInterpolateRecordCursorFactory.java`:
- Around line 374-377: parseParams currently initializes timezoneNameFunc and
offsetFunc but sampleFromFunc.init(...) and sampleToFunc.init(...) are called
externally; move those two init calls into parseParams so all function
initializations are consistent and won't be missed by subclasses overriding
parseParams. Update parseParams to accept (or access) managedCursor and
executionContext as needed, call sampleFromFunc.init(managedCursor,
executionContext) and sampleToFunc.init(managedCursor, executionContext) there,
remove the duplicate init calls from the caller (the block that sets
areTimestampsInitialized = false), and ensure any subclasses of parseParams are
updated if they override it.
In `@core/src/test/java/io/questdb/test/griffin/engine/groupby/SampleByTest.java`:
- Line 6044: Replace the numeric literal using five digits without separators in
the SAMPLE BY clauses: change every "SAMPLE BY 60000T" occurrence in
SampleByTest (the SQL/text literal "SAMPLE BY 60000T") to use an underscore
thousands separator ("SAMPLE BY 60_000T"); apply the same replacement for all
other instances of 60000T in this file so numbers with 5+ digits follow the
underscore separator rule.
.../src/main/java/io/questdb/griffin/engine/groupby/SampleByInterpolateRecordCursorFactory.java
Outdated
Show resolved
Hide resolved
[PR Coverage check]😍 pass : 15 / 15 (100.00%) file detail
|
FILL(LINEAR) respects the FROM-TO clauseFILL(LINEAR) respects the FROM clause
FILL(LINEAR)was disregardingFROM, meaning that it would returnCALENDARaligned results instead ofFROMaligned results.Note: there is no intent really for this to support fill expansion i.e. filling before and after the dataset. Only for
FROMto be anchoring the initial timestamp, andTOto apply as a bound. It's unclear at this stage how pre and post filling should operate with linear fills.