Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
d1703cc
fixes CTE parsing issue and using table as alias
chernser Sep 10, 2025
1f30b73
Merge branch 'main' into jdbc_fix_cte_parse
chernser Sep 25, 2025
e9fe471
Merge branch 'main' into jdbc_fix_cte_parse
chernser Sep 28, 2025
9f4aa7a
Added more tests
chernser Oct 1, 2025
2113b87
filled test statements
chernser Oct 3, 2025
3a96804
moved parser to separate package to track coverage
chernser Oct 3, 2025
25cca50
fixed show statement tests
chernser Oct 6, 2025
6f7e415
Fixed statements with result set and several other
chernser Oct 7, 2025
b2d2399
fixed GRANT stmts and added REVOKE statements
chernser Oct 7, 2025
dfc938c
fixed more statement tests
chernser Oct 7, 2025
aefc7c9
added MOVE and UNDROP statements
chernser Oct 7, 2025
4efa2c1
Fixed quota statements
chernser Oct 7, 2025
25549e7
Fixed insert statements
chernser Oct 7, 2025
f9dd217
Fixed CTE and some minor bugs
chernser Oct 9, 2025
8db01eb
fixed CTE arguments positioning and fixed add column expression
chernser Oct 14, 2025
07eac76
fixed more statements
chernser Oct 14, 2025
0f04adf
fixed column position in alter statement and renamed QUERY to JDBC_PA…
chernser Oct 15, 2025
3e18522
created a SQL parser facade to implement SQL parser selection
chernser Oct 16, 2025
9cb7738
implemented antlr4 two variants
chernser Oct 17, 2025
0cbf958
Fixed issue with # comments
chernser Oct 17, 2025
505272d
Added javaCC parser implementation. not a default. some tests failing
chernser Oct 20, 2025
fdfc35b
Fixed javacc to support single line comments and some new statements
chernser Oct 22, 2025
f02382f
Fixed some keyword issues
chernser Oct 24, 2025
6372e4e
Fixed some more antlr4 issues
chernser Oct 25, 2025
cf863d4
Merge branch 'main' into jdbc_fix_cte_parse
chernser Oct 27, 2025
4f45dc8
Added a few SQL tests fro Statement/PreparedStatement. Addded more te…
chernser Oct 27, 2025
b930ca2
Fixed javaCC for set roles statements and getting correct table name
chernser Oct 27, 2025
24c8e81
Added new statements to javacc. fixed some existing statements
chernser Oct 27, 2025
5f172d2
fixed alter table - type is not required.
chernser Oct 27, 2025
967e7dc
added tests with lambda
chernser Oct 28, 2025
8b2406e
fixed ANTLR4 for expressions with IP keyword
chernser Oct 29, 2025
2b108b0
fixed in statement with multiple arguments
chernser Oct 29, 2025
b773b7e
fixed problem with detecting function in insert statement
chernser Oct 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Fixed issue with # comments
  • Loading branch information
chernser committed Oct 17, 2025
commit 0cbf9580bc4cc7b00e5214095a32ad4dec551adc
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,9 @@ public ConnectionImpl(String url, Properties info) throws SQLException {
this.metadata = new DatabaseMetaDataImpl(this, false, url);
this.defaultCalendar = Calendar.getInstance();

this.sqlParser = SqlParserFacade.getParser(SqlParserFacade.SQLParser.ANTLR4_PARAMS_PARSER.name()); // TODO: path config string here

this.sqlParser = SqlParserFacade.getParser(config.getDriverProperty(DriverProperties.SQL_PARSER.getKey(),
DriverProperties.SQL_PARSER.getDefaultValue()));
this.featureManager = new FeatureManager(this.config);
} catch (SQLException e) {
throw e;
Expand Down
10 changes: 10 additions & 0 deletions jdbc-v2/src/main/java/com/clickhouse/jdbc/DriverProperties.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,16 @@ public enum DriverProperties {
*
*/
USE_MAX_RESULT_ROWS("jdbc_use_max_result_rows", String.valueOf(Boolean.FALSE)),

/**
* Configures what SQL parser will be used. Choices:
* <ul>
* <li>ANTLR4 - parser extracts required information but PreparedStatement parameters parsed separately.</li>
* <li>ANTLR4_PARAMS_PARSER - parser extracts required information AND parameter positions.</li>
* <li>JAVACC - parser extracts required information but PreparedStatement parameters parsed separately.</li>
* </ul>
*/
SQL_PARSER("jdbc_sql_parser", "ANTLR4", List.of("ANTLR4", "ANTLR4_PARAMS_PARSER", "JAVACC")),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting to ANTLR4 means that we are using ANTLR4 as the default one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for catching it!
Yes, we need to use JAVACC by default.

;


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ private static void parseParameters(String originalQuery, ParsedPreparedStatemen
continue;
} else if (i + 1 < len) {
char nextCh = originalQuery.charAt(i + 1);
if (ch == '-' && nextCh == ch) {
if ((ch == '-' && nextCh == ch) || (ch == '#')) {
i = ClickHouseUtils.skipSingleLineComment(originalQuery, i + 2, len) - 1;
} else if (ch == '/' && nextCh == '*') {
i = ClickHouseUtils.skipMultiLineComment(originalQuery, i + 2, len) - 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,36 +11,6 @@

public abstract class BaseSqlParserFacadeTest {

// @Test(groups = {"integration"})
// public void testWithComments() throws Exception {
// assertEquals(SqlParser.parseStatementType(" /* INSERT TESTING */\n SELECT 1 AS num").getType(), SqlParser.StatementType.SELECT);
// assertEquals(SqlParser.parseStatementType("/* SELECT TESTING */\n INSERT INTO test_table VALUES (1)").getType(), SqlParser.StatementType.INSERT);
// assertEquals(SqlParser.parseStatementType("/* INSERT TESTING */\n\n\n UPDATE test_table SET num = 2").getType(), SqlParser.StatementType.UPDATE);
// assertEquals(SqlParser.parseStatementType("-- INSERT TESTING */\n SELECT 1 AS num").getType(), SqlParser.StatementType.SELECT);
// assertEquals(SqlParser.parseStatementType(" -- SELECT TESTING \n -- SELECT AGAIN \n INSERT INTO test_table VALUES (1)").getType(), SqlParser.StatementType.INSERT);
// assertEquals(SqlParser.parseStatementType(" SELECT 42 -- INSERT TESTING").getType(), SqlParser.StatementType.SELECT);
// assertEquals(SqlParser.parseStatementType("#! INSERT TESTING \n SELECT 1 AS num").getType(), SqlParser.StatementType.SELECT);
// assertEquals(SqlParser.parseStatementType("#!INSERT TESTING \n SELECT 1 AS num").getType(), SqlParser.StatementType.SELECT);
// assertEquals(SqlParser.parseStatementType("# INSERT TESTING \n SELECT 1 AS num").getType(), SqlParser.StatementType.SELECT);
// assertEquals(SqlParser.parseStatementType("#INSERT TESTING \n SELECT 1 AS num").getType(), SqlParser.StatementType.SELECT);
// assertEquals(SqlParser.parseStatementType("\nINSERT TESTING \n SELECT 1 AS num").getType(), SqlParser.StatementType.INSERT_INTO_SELECT);
// assertEquals(SqlParser.parseStatementType(" \n INSERT TESTING \n SELECT 1 AS num").getType(), SqlParser.StatementType.INSERT_INTO_SELECT);
// assertEquals(SqlParser.parseStatementType("INSERT INTO t SELECT 1 AS num").getType(), SqlParser.StatementType.INSERT_INTO_SELECT);
// assertEquals(SqlParser.parseStatementType("select 1 AS num").getType(), SqlParser.StatementType.SELECT);
// assertEquals(SqlParser.parseStatementType("insert into test_table values (1)").getType(), SqlParser.StatementType.INSERT);
// assertEquals(SqlParser.parseStatementType("update test_table set num = 2").getType(), SqlParser.StatementType.UPDATE);
// assertEquals(SqlParser.parseStatementType("delete from test_table where num = 2").getType(), SqlParser.StatementType.DELETE);
// assertEquals(SqlParser.parseStatementType("sElEcT 1 AS num").getType(), SqlParser.StatementType.SELECT);
// assertEquals(SqlParser.parseStatementType(null).getType(), SqlParser.StatementType.OTHER);
// assertEquals(SqlParser.parseStatementType("").getType(), SqlParser.StatementType.OTHER);
// assertEquals(SqlParser.parseStatementType(" ").getType(), SqlParser.StatementType.OTHER);
// }
//
// @Test(groups = {"integration"})
// public void testParseStatementWithClause() throws Exception {
// assertEquals(SqlParser.parseStatementType("with data as (SELECT number FROM numbers(100)) select * from data").getType(), SqlParser.StatementType.SELECT);
// }

private SqlParserFacade parser;

public BaseSqlParserFacadeTest(String name) throws Exception {
Expand Down Expand Up @@ -353,9 +323,30 @@ public Object[][] testMiscStmtDp() {
{"insert into t (i, t) values (1, timestamp '2010-01-01 00:00:00')", 0},
{"insert into t (i, t) values (1, date '2010-01-01')", 0},
{"SELECT timestamp '2010-01-01 00:00:00' as ts, date '2010-01-01' as d", 0},
{INSERT_WITH_COMMENTS, 4},
{" /* INSERT TESTING ?? */\n SELECT ? AS num", 1},
{"/* SELECT ? TESTING */\n INSERT INTO test_table VALUES (?)", 1},
{"/* INSERT ? T??ESTING */\n\n\n UPDATE test_table SET num = ?", 1},
{"-- INSERT ? TESTING */\n SELECT ? AS num", 1},
{" -- SELECT ? TESTING \n -- SELECT AGAIN ?\n INSERT INTO test_table VALUES (?)", 1},
{" SELECT ? -- INSERT ? TESTING", 1},
{"#! INSERT ? TESTING \n SELECT ? AS num", 1},
{"#!INSERT ? TESTING \n SELECT ? AS num", 1},
{"# INSERT ? TESTING \n SELECT ? AS num", 1},
{"#INSERT ? TESTING \n SELECT ? AS num", 1},
{"\nINSERT INTO TESTING \n SELECT ? AS num", 1},
{" \n INSERT INTO TESTING \n SELECT ? AS num", 1},
{" SELECT '##?0.1' as f, ? as a\n #this is debug \n FROM table", 1},
{"WITH '#!?0.1' as f, ? as a\n #this is debug \n SELECT * FROM a", 1},
};
}

private static final String INSERT_WITH_COMMENTS = "-- line comment1 ?\n"
+ "# line comment2 ?\n"
+ "#! line comment3 ?\n"
+ "/* block comment ? \n */"
+ "INSERT INTO `with_complex_id`(`v?``1`, \"v?\"\"2\",`v?\\`3`, \"v?\\\"4\") VALUES (?, ?, ?, ?);";

private static final String INSERT_INLINE_DATA =
"INSERT INTO `interval_15_XUTLZWBLKMNZZPRZSKRF`.`checkins` (`timestamp`, `id`) " +
"VALUES ((`now64`(9) + INTERVAL -225 second), 1)";
Expand Down