Skip to content

jdbc-v2: JavaCC grammar has no RECURSIVE token, so every recursive CTE logs a parse-failure WARN #3122

Description

@hrkim2

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

  1. Connect to a server that supports recursive CTEs (tested on 26.3.20.7).
  2. Prepare and execute any WITH RECURSIVE ... statement.
  3. 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

  • Cloud
  • Client version: 0.10.0 (clickhouse-jdbc:0.10.0:all, revision 57aacb1); grammars also checked on main
  • Language version: OpenJDK 25
  • OS: Linux

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions