Description
The JavaCC grammar has no RECURSIVE token, so every recursive CTE — valid SQL that the server executes correctly — takes the parse-failure path and logs a WARN on each prepareStatement/createStatement call.
After <WITH>, sqlWithClause() goes straight into withExpr() (jdbc-v2/src/main/javacc/ClickHouseSqlParser.jj:660), so RECURSIVE is consumed as a CTE alias and parsing fails on the token after it. grep -ci recursive returns 0 for both grammars on main:
jdbc-v2/src/main/javacc/ClickHouseSqlParser.jj
clickhouse-jdbc/src/main/javacc/ClickHouseSqlParser.jj
The ANTLR4 backends do not accept the construct either (no viable alternative at input 'WITHRECURSIVEtaxidsAS('), but they report it through ParserErrorListener at DEBUG (jdbc-v2/.../SqlParserFacade.java:326), whereas the JavaCC path logs at WARN. The same unsupported construct is therefore reported at two different severities depending on jdbc_sql_parser.
Functionally nothing is broken — the fallback sends the original SQL and the query returns correct results (this is distinct from #2844, which was a real failure in 0.9.7 and was fixed in 0.9.8). The problem is that a correct application using a documented server feature emits a WARN on every statement preparation, with a message asking the user to open an issue. Hence this issue.
Related: #2844 (recursive CTE execution, fixed in 0.9.8), #2970 (the SQL-in-WARN part of this message; already improved on main after v0.10.0), #2839 (same shape: warning logged while execution succeeds).
Steps to reproduce
- Connect to a server that supports recursive CTEs (tested on 26.3.20.7).
- Prepare and execute any
WITH RECURSIVE ... statement.
- Observe the WARN, and that the query nevertheless returns the correct result.
Error Log or Exception StackTrace
WARN com.clickhouse.jdbc.internal.parser.javacc.ClickHouseSqlParser --
Parse error at line 1, column 16. Encountered: t. If you believe the SQL is valid,
please feel free to open an issue on Github with this warning and the following SQL attached.
WITH RECURSIVE t AS (SELECT 1 AS n UNION ALL SELECT n + 1 FROM t WHERE n < 5) SELECT sum(n) FROM t
>>> RESULT = 15
With jdbc_sql_parser=ANTLR4 the same statement produces, at DEBUG only:
DEBUG com.clickhouse.jdbc.internal.SqlParserFacade --
SQL syntax error at line: 1, pos: 25, no viable alternative at input 'WITHRECURSIVEtaxidsAS('
>>> RESULT = 15
Expected Behaviour
The grammar accepts WITH RECURSIVE <name> AS ( ... ) so that valid recursive CTEs parse cleanly and no warning is logged.
Failing that, an unsupported-but-recovered construct should be reported at a consistent level across parser backends (DEBUG, as the ANTLR4 path already does), since the driver falls back and the statement executes correctly.
Code Example
String sql = "WITH RECURSIVE t AS (SELECT 1 AS n UNION ALL SELECT n + 1 FROM t WHERE n < 5)"
+ " SELECT sum(n) FROM t";
Properties p = new Properties();
p.setProperty("user", "default");
p.setProperty("password", "");
// p.setProperty("jdbc_sql_parser", "ANTLR4"); // same failure, logged at DEBUG instead
try (Connection c = DriverManager.getConnection("jdbc:clickhouse://localhost:8123/default", p);
PreparedStatement ps = c.prepareStatement(sql);
ResultSet rs = ps.executeQuery()) {
while (rs.next()) System.out.println(">>> RESULT = " + rs.getLong(1)); // 15
}
Parameter binding is unaffected: the same statement with ? placeholders in the anchor term binds and returns correct results under all three jdbc_sql_parser values.
Configuration
Client Configuration
// defaults; jdbc_sql_parser left at JAVACC
Environment
ClickHouse Server
- ClickHouse Server version: 26.3.20.7
- ClickHouse Server non-default settings, if any: none relevant
CREATE TABLE statements for tables involved: none — the repro uses only a literal CTE
- Sample data for all these tables: n/a
Side note (separate from the above, happy to split it out)
clickhouse-jdbc/src/main/javacc/ClickHouseSqlParser.jj:102 on main still logs the full user SQL at WARN:
log.warn("%s. ... with this warning and the following SQL attached.\n%s", e.getMessage(), sql);
The fix from #2970 (generic WARN + SQL moved to DEBUG) appears to have been applied to jdbc-v2 only, so the v1 module still carries the PII/secret-exposure concern that issue raised.
Description
The JavaCC grammar has no
RECURSIVEtoken, so every recursive CTE — valid SQL that the server executes correctly — takes the parse-failure path and logs a WARN on eachprepareStatement/createStatementcall.After
<WITH>,sqlWithClause()goes straight intowithExpr()(jdbc-v2/src/main/javacc/ClickHouseSqlParser.jj:660), soRECURSIVEis consumed as a CTE alias and parsing fails on the token after it.grep -ci recursivereturns 0 for both grammars onmain:jdbc-v2/src/main/javacc/ClickHouseSqlParser.jjclickhouse-jdbc/src/main/javacc/ClickHouseSqlParser.jjThe ANTLR4 backends do not accept the construct either (
no viable alternative at input 'WITHRECURSIVEtaxidsAS('), but they report it throughParserErrorListenerat DEBUG (jdbc-v2/.../SqlParserFacade.java:326), whereas the JavaCC path logs at WARN. The same unsupported construct is therefore reported at two different severities depending onjdbc_sql_parser.Functionally nothing is broken — the fallback sends the original SQL and the query returns correct results (this is distinct from #2844, which was a real failure in 0.9.7 and was fixed in 0.9.8). The problem is that a correct application using a documented server feature emits a WARN on every statement preparation, with a message asking the user to open an issue. Hence this issue.
Related: #2844 (recursive CTE execution, fixed in 0.9.8), #2970 (the SQL-in-WARN part of this message; already improved on
mainafter v0.10.0), #2839 (same shape: warning logged while execution succeeds).Steps to reproduce
WITH RECURSIVE ...statement.Error Log or Exception StackTrace
With
jdbc_sql_parser=ANTLR4the same statement produces, at DEBUG only:Expected Behaviour
The grammar accepts
WITH RECURSIVE <name> AS ( ... )so that valid recursive CTEs parse cleanly and no warning is logged.Failing that, an unsupported-but-recovered construct should be reported at a consistent level across parser backends (DEBUG, as the ANTLR4 path already does), since the driver falls back and the statement executes correctly.
Code Example
Parameter binding is unaffected: the same statement with
?placeholders in the anchor term binds and returns correct results under all threejdbc_sql_parservalues.Configuration
Client Configuration
// defaults; jdbc_sql_parser left at JAVACCEnvironment
clickhouse-jdbc:0.10.0:all, revision 57aacb1); grammars also checked onmainClickHouse Server
CREATE TABLEstatements for tables involved: none — the repro uses only a literal CTESide note (separate from the above, happy to split it out)
clickhouse-jdbc/src/main/javacc/ClickHouseSqlParser.jj:102onmainstill logs the full user SQL at WARN:The fix from #2970 (generic WARN + SQL moved to DEBUG) appears to have been applied to
jdbc-v2only, so the v1 module still carries the PII/secret-exposure concern that issue raised.