Skip to content

fix(sql): fix empty result set from limit queries#6504

Merged
bluestreak01 merged 1 commit intomasterfrom
vi_fix_limit
Dec 5, 2025
Merged

fix(sql): fix empty result set from limit queries#6504
bluestreak01 merged 1 commit intomasterfrom
vi_fix_limit

Conversation

@bluestreak01
Copy link
Copy Markdown
Member

@bluestreak01 bluestreak01 commented Dec 4, 2025

fixes #6501

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Dec 4, 2025

Walkthrough

The PR removes the hasInterval() method from multiple partition frame cursor factory classes, adds underflow protection for intervalLo boundary checks, refactors switch expressions to enhanced syntax, changes column name resolution in SQL code generation, and updates test expectations to reflect corrected column naming conventions.

Changes

Cohort / File(s) Summary
Partition Frame Cursor API Changes
core/src/main/java/io/questdb/cairo/FullPartitionFrameCursorFactory.java,
core/src/main/java/io/questdb/cairo/IntervalPartitionFrameCursorFactory.java,
core/src/main/java/io/questdb/cairo/sql/PartitionFrameCursorFactory.java
Removed hasInterval() method from three factory classes (eliminating the public API definition and two implementations). Refactored switch expressions in base class to use enhanced syntax.
Boundary Condition Protection
core/src/main/java/io/questdb/cairo/IntervalBwdPartitionFrameCursor.java
Added underflow guard when intervalLo is Long.MIN_VALUE to skip timestamp lookup and assign lo = 0.
SQL Code Generation
core/src/main/java/io/questdb/griffin/SqlCodeGenerator.java
Changed column name source in generateTableQuery0 from Chars.toString(column.getName()) to metadata.getColumnName(columnIndex).
Test Expectation Updates
core/src/test/java/io/questdb/test/griffin/ClickBenchTest.java,
core/src/test/java/io/questdb/test/griffin/ExplainPlanTest.java,
core/src/test/java/io/questdb/test/griffin/engine/join/AsOfJoinTest.java
Updated test expectations for corrected column name casing (EventDate → Eventdate, ResolutionWidth, market_data_symbol). Refactored TestCase in ClickBenchTest from private class to private record.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • IntervalBwdPartitionFrameCursor.java: Logic change for underflow condition requires verification that the guard correctly handles the Long.MIN_VALUE edge case
  • SqlCodeGenerator.java: Column name source change from direct Chars conversion to metadata lookup needs validation to ensure behavioral equivalence across all column types and contexts
  • ClickBenchTest.java: Record refactoring and test expectation updates should be cross-checked for correctness

Possibly related PRs

Suggested labels

Core

Suggested reviewers

  • RaphDal

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 2 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The PR title 'fix(sql): fix empty result set from limit queries' is vague and does not match the actual changes, which are primarily about removing hasInterval() methods and refactoring switch expressions. The title describes an end-user-facing bug fix but the code changes appear to be internal refactoring. Clarify the PR title to accurately reflect the code changes: either describe the actual refactoring (method removal, switch expressions) or explain how these changes fix the LIMIT query issue.
Description check ❓ Inconclusive The PR description only contains 'fixes #6501' with no explanation of what changes were made or why. While it references the linked issue, it provides minimal context about the actual implementation. Expand the description to explain what code changes were made and how they fix the LIMIT query issue described in #6501.
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR addresses issue #6501 about ORDER BY DESC LIMIT returning empty result sets. The code changes include removing hasInterval() overrides and adding underflow guards, which appear aimed at fixing interval-based query handling that causes the bug.
Out of Scope Changes check ✅ Passed Changes include removal of hasInterval() methods, switch expression refactoring, column name resolution changes, and test updates that appear directly related to fixing the LIMIT query interval handling issue.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch vi_fix_limit

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ast-grep (0.40.0)
core/src/main/java/io/questdb/griffin/SqlCodeGenerator.java
core/src/test/java/io/questdb/test/griffin/ExplainPlanTest.java

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 and usage tips.

@bluestreak01 bluestreak01 added Bug Incorrect or unexpected behavior SQL Issues or changes relating to SQL execution labels Dec 4, 2025
@bluestreak01
Copy link
Copy Markdown
Member Author

@CodeRabbit review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Dec 4, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

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 (2)
core/src/main/java/io/questdb/cairo/IntervalBwdPartitionFrameCursor.java (1)

121-123: Underflow guard for intervalLo in calculateSize looks correct; consider mirroring in next() for consistency

The new ternary:

long lo = intervalLo > Long.MIN_VALUE ? timestampFinder.findTimestamp(intervalLo - 1, 0, hi) : 0;

correctly prevents intervalLo - 1 from underflowing when intervalLo == Long.MIN_VALUE, and mapping that specific case to lo = 0 matches the intended semantics for an open‑ended lower bound (start from the first row in the partition). Given that calculateSize only uses local copies of the cursor state, this is a safe, localized fix for size estimation in LIMIT scenarios.

There is a very similar use of intervalLo - 1 in next() (Line 212) without the same guard. If intervalLo can ever be Long.MIN_VALUE along that path as well, you may want to apply an analogous check there for robustness and symmetry, even if it doesn’t currently manifest as a bug.

Also applies to: 206-213

core/src/main/java/io/questdb/griffin/SqlCodeGenerator.java (1)

6218-6233: Use of physical column name in table-query metadata looks correct

Switching the TableColumnMetadata name to metadata.getColumnName(columnIndex) aligns result metadata with the physical table schema, which is consistent with how other parts of the generator treat base-table projections. The rest of the metadata (type, indexing, symbol flags, capacities) is still sourced from the same metadata instance, so behavior remains coherent.

If you want to micro-optimize, you could cache metadata.getColumnMetadata(columnIndex) into a local to avoid repeated calls, but it’s not critical.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7896064 and b58fbd1.

📒 Files selected for processing (8)
  • core/src/main/java/io/questdb/cairo/FullPartitionFrameCursorFactory.java (0 hunks)
  • core/src/main/java/io/questdb/cairo/IntervalBwdPartitionFrameCursor.java (1 hunks)
  • core/src/main/java/io/questdb/cairo/IntervalPartitionFrameCursorFactory.java (0 hunks)
  • core/src/main/java/io/questdb/cairo/sql/PartitionFrameCursorFactory.java (1 hunks)
  • core/src/main/java/io/questdb/griffin/SqlCodeGenerator.java (1 hunks)
  • core/src/test/java/io/questdb/test/griffin/ClickBenchTest.java (2 hunks)
  • core/src/test/java/io/questdb/test/griffin/ExplainPlanTest.java (1 hunks)
  • core/src/test/java/io/questdb/test/griffin/engine/join/AsOfJoinTest.java (4 hunks)
💤 Files with no reviewable changes (2)
  • core/src/main/java/io/questdb/cairo/FullPartitionFrameCursorFactory.java
  • core/src/main/java/io/questdb/cairo/IntervalPartitionFrameCursorFactory.java
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-19T12:21:00.062Z
Learnt from: jerrinot
Repo: questdb/questdb PR: 6413
File: core/src/test/java/io/questdb/test/cutlass/pgwire/PGJobContextTest.java:11982-12002
Timestamp: 2025-11-19T12:21:00.062Z
Learning: QuestDB Java tests use a deterministic random seed. The test utilities (e.g., io.questdb.test.tools.TestUtils and io.questdb.std.Rnd) produce reproducible sequences, so rnd_* functions (including rnd_uuid4) yield deterministic outputs across runs. Do not flag tests in core/src/test/** that assert against values produced by rnd_* as flaky due to randomness.

Applied to files:

  • core/src/test/java/io/questdb/test/griffin/ClickBenchTest.java
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (36)
  • GitHub Check: New pull request (SelfHosted Running tests with cover on linux-other)
  • GitHub Check: New pull request (SelfHosted Running tests with cover on linux-pgwire)
  • GitHub Check: New pull request (SelfHosted Running tests with cover on linux-cairo-sub)
  • GitHub Check: New pull request (SelfHosted Running tests with cover on linux-cairo-root)
  • GitHub Check: New pull request (SelfHosted Running tests with cover on linux-fuzz2)
  • GitHub Check: New pull request (SelfHosted Running tests with cover on linux-fuzz1)
  • GitHub Check: New pull request (SelfHosted Running tests with cover on linux-griffin-sub)
  • GitHub Check: New pull request (SelfHosted Running tests with cover on linux-griffin-root)
  • GitHub Check: New pull request (Hosted Running tests on windows-other-2)
  • GitHub Check: New pull request (Hosted Running tests on windows-other-1)
  • GitHub Check: New pull request (Hosted Running tests on windows-pgwire)
  • GitHub Check: New pull request (Hosted Running tests on windows-cairo-2)
  • GitHub Check: New pull request (Hosted Running tests on windows-cairo-1)
  • GitHub Check: New pull request (Hosted Running tests on windows-fuzz2)
  • GitHub Check: New pull request (Hosted Running tests on windows-fuzz1)
  • GitHub Check: New pull request (Hosted Running tests on windows-griffin-sub)
  • GitHub Check: New pull request (Hosted Running tests on windows-griffin-base)
  • GitHub Check: New pull request (Hosted Running tests on mac-other)
  • GitHub Check: New pull request (Hosted Running tests on mac-pgwire)
  • GitHub Check: New pull request (Hosted Running tests on mac-cairo-fuzz)
  • GitHub Check: New pull request (Hosted Running tests on mac-cairo)
  • GitHub Check: New pull request (SelfHosted Cairo tests on linux-x64-zfs)
  • GitHub Check: New pull request (SelfHosted Cairo tests on linux-x86-graal)
  • GitHub Check: New pull request (Hosted Running tests on mac-griffin)
  • GitHub Check: New pull request (Trigger Enterprise CI Trigger Enterprise Pipeline)
  • GitHub Check: New pull request (SelfHosted Other tests on linux-x64-zfs)
  • GitHub Check: New pull request (SelfHosted Cairo tests on linux-arm64)
  • GitHub Check: New pull request (Rust Test and Lint on linux-jdk17)
  • GitHub Check: New pull request (SelfHosted Griffin tests on linux-x86-graal)
  • GitHub Check: New pull request (SelfHosted Other tests on linux-x86-graal)
  • GitHub Check: New pull request (SelfHosted Griffin tests on linux-x64-zfs)
  • GitHub Check: New pull request (SelfHosted Other tests on linux-arm64)
  • GitHub Check: New pull request (SelfHosted Griffin tests on linux-arm64)
  • GitHub Check: New pull request (Check Changes Check changes)
  • GitHub Check: build
  • GitHub Check: build
🔇 Additional comments (5)
core/src/test/java/io/questdb/test/griffin/ClickBenchTest.java (2)

231-239: Plan expectation now matches actual column name

Updating values: [min(Eventdate),max(Eventdate)] to use Eventdate aligns the Q6 plan expectation with the column name defined in the DDL and what the planner emits. Looks correct.


802-803: Good use of record for TestCase helper

Switching TestCase to a private record keeps the semantics (name/query/expectedPlan triple) while reducing boilerplate and enforcing immutability. No issues spotted.

core/src/main/java/io/questdb/cairo/sql/PartitionFrameCursorFactory.java (1)

49-63: Switch-expression refactor keeps ordering semantics intact

The new switch expressions in nameOf/reverse preserve the mapping of order constants to names and back, and handle unexpected values by falling back to "any"/ORDER_ANY. This is a clean, readable refactor.

core/src/test/java/io/questdb/test/griffin/engine/join/AsOfJoinTest.java (2)

866-882: Explain-plan expectation updated to correct symbol name

The expected plan for testAsOfJoinLinearSearchHint now checks filter: market_data_symbol='sym_1', matching the market_data_symbol column defined in the market_data table. This aligns the assertion with the real plan output.


1605-1618: Consistent symbol casing in second linear-hint plan expectation

Similarly, the Filtered AsOf Join Fast plan expectation now uses filter: market_data_symbol='sym_1', keeping the explain-text assertion consistent with the table schema and the first EXPLAIN in this test.

@glasstiger
Copy link
Copy Markdown
Contributor

[PR Coverage check]

😍 pass : 5 / 10 (50.00%)

file detail

path covered line new line coverage
🔵 io/questdb/cairo/sql/PartitionFrameCursorFactory.java 3 8 37.50%
🔵 io/questdb/cairo/IntervalBwdPartitionFrameCursor.java 1 1 100.00%
🔵 io/questdb/griffin/SqlCodeGenerator.java 1 1 100.00%

Copy link
Copy Markdown
Contributor

@nwoolmer nwoolmer left a comment

Choose a reason for hiding this comment

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

L G T M

@bluestreak01 bluestreak01 merged commit 606aace into master Dec 5, 2025
44 checks passed
@bluestreak01 bluestreak01 deleted the vi_fix_limit branch December 5, 2025 17:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Incorrect or unexpected behavior SQL Issues or changes relating to SQL execution

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ORDER BY … DESC LIMIT returns no rows when WHERE filter matches data

3 participants