-
Notifications
You must be signed in to change notification settings - Fork 860
Description
Summary
- Location:
src/query/ast/src/parser/parser.rs:218(insideassert_reparse) - Panic message:
error: join condition already set - Occurrences: 2
Likely trigger files
The panic SQL is captured verbatim in the log. These come from original DuckDB source tests
that the converter validated against the running server:
Case A — DuckDB source: test/sql/join/inner/test_using_join.test (or similar)
SELECT * FROM (VALUES(NULL)) AS tbl(i)
INNER JOIN (VALUES(NULL)) AS tbl2(i)
INNER JOIN (VALUES(NULL)) AS tbl3(i) ON tbl2.i = tbl3.i USING(i);Case B — DuckDB source: test/sql/join/left_outer/left_join_issue_15316.test
Converted file: sql/join/left_outer/left_join_issue_15316.test (query already commented out as TODO: unsupported feature)
SELECT i1.i AS i1_i, i2.s, i3.i AS i3_i
FROM integers1 AS i1
LEFT OUTER JOIN integers2 AS i2
LEFT OUTER JOIN integers3 AS i3 ON i2.i = i3.i ON NULL;Related abort files (server crashed before these could be processed):
test/sql/join/left_outer/test_left_outer.test(abort) — containsON NULL<>NULLpatterntest/sql/join/right_outer/test_right_outer.test(abort) — containsON NULL<>NULLpatterntest/sql/join/inner/test_join.test(pass) — containsON NULL = 2but parsed successfully
Reproduction
-- Case A: INNER JOIN chain with ON + USING
SELECT * FROM (VALUES(NULL)) AS tbl(i)
INNER JOIN (VALUES(NULL)) AS tbl2(i)
INNER JOIN (VALUES(NULL)) AS tbl3(i) ON tbl2.i = tbl3.i USING(i);
-- Case B: LEFT OUTER JOIN chain with multiple ON clauses
SELECT i1.i AS i1_i, i2.s, i3.i AS i3_i
FROM integers1 AS i1
LEFT OUTER JOIN integers2 AS i2
LEFT OUTER JOIN integers3 AS i3 ON i2.i = i3.i ON NULL;Call chain
Planner::parse_sql (planner.rs:173)
→ parse_sql (parser.rs:65)
→ assert_reparse (parser.rs:218) ← PANIC
Key stack frames
| # | Function | File |
|---|---|---|
| 11 | assert_reparse |
parser.rs:218 |
| 14 | parse_sql |
parser.rs:65 |
| 15 | Planner::parse_sql |
planner.rs:173 |
Root cause
Databend's parser does not support DuckDB-style unparenthesized nested joins with multiple ON/USING clauses. The first parse succeeds, but assert_reparse (which re-parses the pretty-printed AST) fails because the re-serialized SQL loses the nesting structure. The assert_reparse function panics on parse failure instead of returning an error.
Fix direction
assert_reparseshould return an error (or log a warning), never panic. A parse round-trip failure is a quality issue, not a crash-worthy event.- Separately, consider whether to support this nested join syntax.