Describe the bug
With an ANTLR4 parser backend selected (jdbc_sql_parser=ANTLR4 or ANTLR4_PARAMS_PARSER), the driver reports that an
INSERT ... VALUES list holds no function call while it does, when the values list contains a function call the bundled
ANTLR4 grammar cannot match. Function calls in a values list are reported by a listener callback on the parse tree
(insertParameterFuncExpr). A statement the grammar cannot match is still given a parse tree, completed by error
recovery, which skips the tokens the parser recovered on - the function call among them - so the callback never fires and
ParsedPreparedStatement.useFunction stays false.
With the beta RowBinary writer enabled (beta.row_binary_for_simple_insert=true) that flag is one of the conditions
ConnectionImpl#prepareStatement uses to decide whether an insert can be written with the RowBinary writer, which
requires a values list of parameter placeholders only. Such a statement is therefore routed to the RowBinary writer,
where the literal function-call column cannot be written.
The default JAVACC backend is not affected: it reports function usage from the SQL itself, not from a parse tree.
Steps to reproduce
Properties properties = new Properties();
properties.setProperty("beta.row_binary_for_simple_insert", "true");
properties.setProperty("jdbc_sql_parser", "ANTLR4"); // or ANTLR4_PARAMS_PARSER
try (Connection conn = DriverManager.getConnection(url, properties)) {
try (Statement stmt = conn.createStatement()) {
stmt.execute("CREATE TABLE t (v1 Int32, v2 String) Engine MergeTree ORDER BY ()");
}
// hex(x'AB') is valid ClickHouse; the bundled grammar has no hex string literal, so the
// statement is parsed with errors and the function call is skipped by error recovery
PreparedStatement ps = conn.prepareStatement("INSERT INTO t (v1, v2) VALUES (?, hex(x'AB'))");
System.out.println(ps.getClass()); // WriterStatementImpl - the RowBinary writer
}
Expected behaviour
The statement holds a function call in its values list, so it must be given the generic parameter substitution path
(PreparedStatementImpl), as it is with INSERT INTO t (v1, v2) VALUES (?, now()) (a function call the grammar does
match) and with the JAVACC backend, and the row must be stored with v2 = 'AB'.
Actual behaviour
ParsedPreparedStatement.useFunction is false, and the statement is routed to the RowBinary writer
(WriterStatementImpl).
Code example
See above.
Error log
n/a
Configuration
Environment
- Client version: 0.11.0-rc1 (
main)
- OS: Linux
ClickHouse server
- ClickHouse Server version: 26.3
Describe the bug
With an
ANTLR4parser backend selected (jdbc_sql_parser=ANTLR4orANTLR4_PARAMS_PARSER), the driver reports that anINSERT ... VALUESlist holds no function call while it does, when the values list contains a function call the bundledANTLR4 grammar cannot match. Function calls in a values list are reported by a listener callback on the parse tree
(
insertParameterFuncExpr). A statement the grammar cannot match is still given a parse tree, completed by errorrecovery, which skips the tokens the parser recovered on - the function call among them - so the callback never fires and
ParsedPreparedStatement.useFunctionstaysfalse.With the beta
RowBinarywriter enabled (beta.row_binary_for_simple_insert=true) that flag is one of the conditionsConnectionImpl#prepareStatementuses to decide whether an insert can be written with theRowBinarywriter, whichrequires a values list of parameter placeholders only. Such a statement is therefore routed to the
RowBinarywriter,where the literal function-call column cannot be written.
The default
JAVACCbackend is not affected: it reports function usage from the SQL itself, not from a parse tree.Steps to reproduce
Expected behaviour
The statement holds a function call in its values list, so it must be given the generic parameter substitution path
(
PreparedStatementImpl), as it is withINSERT INTO t (v1, v2) VALUES (?, now())(a function call the grammar doesmatch) and with the
JAVACCbackend, and the row must be stored withv2 = 'AB'.Actual behaviour
ParsedPreparedStatement.useFunctionisfalse, and the statement is routed to theRowBinarywriter(
WriterStatementImpl).Code example
See above.
Error log
n/a
Configuration
Environment
main)ClickHouse server