Skip to content

fix(sql): optimize error msg when invalid column references in JOIN queries#6332

Merged
bluestreak01 merged 3 commits intomasterfrom
issue#6329
Oct 31, 2025
Merged

fix(sql): optimize error msg when invalid column references in JOIN queries#6332
bluestreak01 merged 3 commits intomasterfrom
issue#6329

Conversation

@kafka1991
Copy link
Copy Markdown
Collaborator

@kafka1991 kafka1991 commented Oct 30, 2025

close #6329

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Oct 30, 2025

Walkthrough

Adds validation during top-down column processing in query generation to check if columns exist in table metadata before accessing them, preventing index-out-of-bounds exceptions. Includes a corresponding test validating error handling when joining with non-existent columns.

Changes

Cohort / File(s) Summary
Main fix: Column validation in code generation
core/src/main/java/io/questdb/griffin/SqlCodeGenerator.java
Adds safety check in generateTableQuery0 when iterating top-down columns: retrieves column via local variable, validates existence via metadata.getColumnIndexQuiet(), and throws invalidColumn SqlException if not found (index -1). Refactors to use local column variable consistently instead of re-reading from topDownColumns.getQuick(i).
Test coverage: Non-existent column validation
core/src/test/java/io/questdb/test/griffin/SqlCodeGeneratorTest.java
Adds testJoinUseNonExistColumn() test method that creates two tables and executes a LEFT OUTER JOIN with a non-existent column in the ON clause, asserting proper "Invalid column" error handling and leak checking.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • The fix is a straightforward validation guard with proper error handling in a critical code path
  • Test covers the new error scenario with standard assertion pattern
  • Consider verifying that the column index validation is comprehensive and handles all edge cases in join scenarios

Suggested labels

Bug, SQL

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
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.
✅ Passed checks (4 passed)
Check name Status Explanation
Title Check ✅ Passed The PR title "fix(sql): optimize error msg when invalid column references in JOIN queries" accurately captures the primary change in the pull request. The code modifications add validation to detect invalid column references early in the code generation process for JOIN queries, replacing an unsafe direct lookup with a guarded check that validates the column exists via metadata.getColumnIndexQuiet(). When an invalid column is found, the fix throws a proper SqlException instead of allowing an ArrayIndexOutOfBoundsException to propagate. The title clearly communicates that this addresses error handling for invalid column references in JOIN contexts.
Linked Issues Check ✅ Passed The linked issue #6329 requires fixing an ArrayIndexOutOfBoundsException that occurs when executing a LEFT OUTER JOIN combined with aggregation due to invalid column references. The PR changes directly address this by adding validation in SqlCodeGenerator.java to safely check if columns exist before processing them, throwing a proper invalidColumn SqlException instead of allowing the index out of bounds error to occur. The new test testJoinUseNonExistColumn() validates this error handling behavior for non-existent columns in JOIN queries, confirming the fix meets the core requirement.
Out of Scope Changes Check ✅ Passed All changes in this PR are directly scoped to addressing the linked issue #6329. The modifications to SqlCodeGenerator.java add validation for invalid column references in JOIN query processing, and the test addition verifies proper error handling for this scenario. No extraneous changes, refactoring, or unrelated functionality modifications are present in the changeset.
Description Check ✅ Passed The PR description "close #6329" is directly related to the changeset. Although minimal in detail, it explicitly references the linked issue that the PR addresses, providing sufficient context about the purpose of the changes. This is not off-topic or unrelated to the modification.
✨ 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 issue#6329

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.39.6)
core/src/main/java/io/questdb/griffin/SqlCodeGenerator.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.

@kafka1991 kafka1991 changed the title fix(sql):optimize error msg when invalid column references in JOIN queries fix(sql): optimize error msg when invalid column references in JOIN queries Oct 30, 2025
@bluestreak01
Copy link
Copy Markdown
Member

@CodeRabbit review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Oct 31, 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: 0

🧹 Nitpick comments (2)
core/src/main/java/io/questdb/griffin/SqlCodeGenerator.java (1)

5913-5924: Minor: cache column metadata to avoid repeated lookups.

Optional micro‑refactor: store metadata.getColumnMetadata(columnIndex) once and reuse for flags/capacity reads.

-                    queryMeta.add(new TableColumnMetadata(
-                            Chars.toString(column.getName()),
-                            type,
-                            metadata.isColumnIndexed(columnIndex),
-                            metadata.getIndexValueBlockCapacity(columnIndex),
-                            metadata.isSymbolTableStatic(columnIndex),
-                            metadata.getMetadata(columnIndex),
-                            -1,
-                            false,
-                            0,
-                            metadata.getColumnMetadata(columnIndex).isSymbolCacheFlag(),
-                            metadata.getColumnMetadata(columnIndex).getSymbolCapacity()
-                    ));
+                    final TableColumnMetadata baseMeta = metadata.getColumnMetadata(columnIndex);
+                    queryMeta.add(new TableColumnMetadata(
+                            Chars.toString(column.getName()),
+                            type,
+                            baseMeta.isSymbolIndexFlag(),
+                            baseMeta.getIndexValueBlockCapacity(),
+                            baseMeta.isSymbolTableStatic(),
+                            metadata.getMetadata(columnIndex),
+                            -1,
+                            false,
+                            0,
+                            baseMeta.isSymbolCacheFlag(),
+                            baseMeta.getSymbolCapacity()
+                    ));
core/src/test/java/io/questdb/test/griffin/SqlCodeGeneratorTest.java (1)

2514-2526: Solid regression test; tiny nits for robustness and naming

  • Approves: the test cleanly reproduces the join+agg invalid-column case and verifies the improved error message under leak checking. Good coverage.

  • Optional: the hard-coded position 136 can be fragile if the SQL is reformatted. Consider computing it from the token location to keep the test stable:

-            assertExceptionNoLeakCheck(
-                    "SELECT o.*, avg(p.bid) avg_big, avg(p.ask) avg_ask FROM orders o LEFT OUTER JOIN prices p ON p.sym = o.sym and p.ts >= dateadd('s', -1, o.ts) and p.ts <= dateadd('s', 1, o.ts);",
-                    136,
-                    "Invalid column: ts",
-                    sqlExecutionContext
-            );
+            final String sql =
+                    "SELECT o.*, avg(p.bid) avg_big, avg(p.ask) avg_ask FROM orders o LEFT OUTER JOIN prices p " +
+                    "ON p.sym = o.sym and p.ts >= dateadd('s', -1, o.ts) and p.ts <= dateadd('s', 1, o.ts);";
+            final int pos = sql.indexOf("o.ts") + "o.".length(); // point at 'ts'
+            assertExceptionNoLeakCheck(sql, pos, "Invalid column: ts", sqlExecutionContext);
  • Optional: rename to testJoinUsesNonexistentColumn for clarity.
📜 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 c544fb5 and b9f0055.

📒 Files selected for processing (2)
  • core/src/main/java/io/questdb/griffin/SqlCodeGenerator.java (1 hunks)
  • core/src/test/java/io/questdb/test/griffin/SqlCodeGeneratorTest.java (1 hunks)
⏰ 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). (26)
  • GitHub Check: New pull request (SelfHosted Griffin And Fuzz tests on linux-arm64)
  • GitHub Check: New pull request (SelfHosted Other tests on linux-x64-zfs)
  • GitHub Check: New pull request (SelfHosted Other tests on linux-arm64)
  • GitHub Check: New pull request (SelfHosted Griffin And Fuzz tests on linux-x64-zfs)
  • GitHub Check: New pull request (SelfHosted Other tests Start X64Zfs Agent)
  • GitHub Check: New pull request (Rust Test and Lint on linux-jdk17)
  • GitHub Check: New pull request (Hosted Running tests on windows-other)
  • GitHub Check: New pull request (Hosted Running tests on windows-pgwire)
  • GitHub Check: New pull request (Hosted Running tests on windows-cairo)
  • 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)
  • GitHub Check: New pull request (Hosted Running tests with cover on linux-other)
  • GitHub Check: New pull request (Hosted Running tests on mac-other)
  • GitHub Check: New pull request (Hosted Running tests with cover on linux-pgwire)
  • 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 with cover on linux-cairo)
  • GitHub Check: New pull request (Hosted Running tests on mac-cairo)
  • GitHub Check: New pull request (Hosted Running tests with cover on linux-fuzz)
  • GitHub Check: New pull request (SelfHosted Griffin And Fuzz tests Start ARM Agent)
  • GitHub Check: New pull request (SelfHosted Other tests Start ARM Agent)
  • GitHub Check: New pull request (Hosted Running tests with cover on linux-griffin)
  • GitHub Check: New pull request (Hosted Running tests on mac-griffin)
  • GitHub Check: New pull request (SelfHosted Griffin And Fuzz tests Start X64Zfs Agent)
  • GitHub Check: New pull request (Check Changes Check changes)
🔇 Additional comments (1)
core/src/main/java/io/questdb/griffin/SqlCodeGenerator.java (1)

5901-5905: Fail-fast check prevents AIOOBE; verified and approved.

The fix correctly calls getColumnIndexQuiet() and throws SqlException.invalidColumn() on -1 return, preventing index-out-of-bounds access. Test coverage is in place: testJoinUseNonExistColumn validates the scenario by referencing a non-existent column in a JOIN, confirming the error is surfaced with proper position and column name context.

@glasstiger
Copy link
Copy Markdown
Contributor

[PR Coverage check]

😍 pass : 5 / 5 (100.00%)

file detail

path covered line new line coverage
🔵 io/questdb/griffin/SqlCodeGenerator.java 5 5 100.00%

@bluestreak01 bluestreak01 merged commit 0e94455 into master Oct 31, 2025
34 checks passed
@bluestreak01 bluestreak01 deleted the issue#6329 branch October 31, 2025 17:33
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.

Index out of bounds when doing left outer join combined with aggregation

4 participants