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 javacc to support single line comments and some new statements
  • Loading branch information
chernser committed Oct 22, 2025
commit fdfc35b02b8ce4a19eae8c1262531037860fd3ff
3 changes: 1 addition & 2 deletions jdbc-v2/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<url>https://github.com/ClickHouse/clickhouse-java/tree/main/jdbc-v2</url>

<properties>
<javacc-plugin.version>4.1.4</javacc-plugin.version>
<javacc-plugin.version>5.0.0</javacc-plugin.version>
<spec.title>JDBC</spec.title>
<spec.version>4.2</spec.version>
<jackson.version>2.17.2</jackson.version>
Expand Down Expand Up @@ -197,7 +197,6 @@
<javadocFriendlyComments>true</javadocFriendlyComments>
<packageName>com.clickhouse.jdbc.internal.parser.javacc</packageName>
<sourceDirectory>src/main/javacc</sourceDirectory>
<outputDirectory>src/main/java</outputDirectory>
</configuration>
</execution>
</executions>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public final class ParsedPreparedStatement {

private int assignValuesListStopPosition = -1;

private int assignValuesGroups = -1;
private int assignValuesGroups = 0;

public void setHasResultSet(boolean hasResultSet) {
this.hasResultSet = hasResultSet;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,10 @@ public ParsedPreparedStatement parsePreparedStatement(String sql) {
stmt.setHasResultSet(isStmtWithResultSet(parsedStmt));
stmt.setTable(parsedStmt.getTable());
stmt.setInsertWithSelect(parsedStmt.containsKeyword("SELECT") && (parsedStmt.getStatementType() == StatementType.INSERT));
stmt.setAssignValuesGroups(parsedStmt.getValueGroups());

Integer startIndex = parsedStmt.getPositions().get(ClickHouseSqlStatement.KEYWORD_VALUES_START);
if (startIndex != null) {
stmt.setAssignValuesGroups(1);
int endIndex = parsedStmt.getPositions().get(ClickHouseSqlStatement.KEYWORD_VALUES_END);
stmt.setAssignValuesListStartPosition(startIndex);
stmt.setAssignValuesListStopPosition(endIndex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,20 @@ public class ClickHouseSqlStatement {
private final Map<String, Integer> positions;
private final Map<String, String> settings;
private final Set<String> tempTables;
private final int valueGroups;

public ClickHouseSqlStatement(String sql) {
this(sql, StatementType.UNKNOWN, null, null, null, null, null, null, null, null, null, null, null, null);
this(sql, StatementType.UNKNOWN, null, null, null, null, null, null, null, null, null, null, null, null, 0);
}

public ClickHouseSqlStatement(String sql, StatementType stmtType) {
this(sql, stmtType, null, null, null, null, null, null, null, null, null, null, null, null);
this(sql, stmtType, null, null, null, null, null, null, null, null, null, null, null, null, 0);
}

public ClickHouseSqlStatement(String sql, StatementType stmtType, String cluster, String database, String table,
String input, String compressAlgorithm, String compressLevel, String format, String file,
List<Integer> parameters, Map<String, Integer> positions, Map<String, String> settings,
Set<String> tempTables) {
Set<String> tempTables, int valueGroups) {
this.sql = sql;
this.stmtType = stmtType;

Expand All @@ -65,6 +66,7 @@ public ClickHouseSqlStatement(String sql, StatementType stmtType, String cluster
this.compressLevel = compressLevel;
this.format = format;
this.file = file;
this.valueGroups = valueGroups;

if (parameters != null && !parameters.isEmpty()) {
this.parameters = Collections.unmodifiableList(parameters);
Expand Down Expand Up @@ -297,6 +299,10 @@ public Map<String, Integer> getPositions() {
return this.positions;
}

public int getValueGroups() {
return valueGroups;
}

public Map<String, String> getSettings() {
return this.settings;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ private ClickHouseSqlStatement handleDelete(String sql, StatementType stmtType,
builder.append("TRUNCATE TABLE").append(sql.substring(index + 4));
}
return new ClickHouseSqlStatement(builder.toString(), stmtType, cluster, database, table, input,
compressAlgorithm, compressLevel, format, file, parameters, null, settings, null);
compressAlgorithm, compressLevel, format, file, parameters, null, settings, null, 0);
}

private ClickHouseSqlStatement handleUpdate(String sql, StatementType stmtType, String cluster, String database,
Expand All @@ -91,13 +91,13 @@ private ClickHouseSqlStatement handleUpdate(String sql, StatementType stmtType,
builder.append('`').append(table).append('`').append(" UPDATE"); // .append(sql.substring(index + 3));
addMutationSetting(sql, builder, positions, settings, index + 3);
return new ClickHouseSqlStatement(builder.toString(), stmtType, cluster, database, table, input,
compressAlgorithm, compressLevel, format, file, parameters, null, settings, null);
compressAlgorithm, compressLevel, format, file, parameters, null, settings, null, 0);
}

private ClickHouseSqlStatement handleInFileForInsertQuery(String sql, StatementType stmtType, String cluster,
String database, String table, String input, String compressAlgorithm, String compressLevel, String format,
String file, List<Integer> parameters, Map<String, Integer> positions, Map<String, String> settings,
Set<String> tempTables) {
String database, String table, String input, String compressAlgorithm, String compressLevel, String format,
String file, List<Integer> parameters, Map<String, Integer> positions, Map<String, String> settings,
Set<String> tempTables, int valueGroups) {
StringBuilder builder = new StringBuilder(sql.length());
builder.append(sql.substring(0, positions.get("FROM")));
Integer index = positions.get("SETTINGS");
Expand All @@ -115,7 +115,7 @@ private ClickHouseSqlStatement handleInFileForInsertQuery(String sql, StatementT
builder.append("FORMAT ").append(format);
}
return new ClickHouseSqlStatement(builder.toString(), stmtType, cluster, database, table, input,
compressAlgorithm, compressLevel, format, file, parameters, null, settings, null);
compressAlgorithm, compressLevel, format, file, parameters, null, settings, null, valueGroups);
}

private ClickHouseSqlStatement handleOutFileForSelectQuery(String sql, StatementType stmtType, String cluster,
Expand All @@ -129,14 +129,14 @@ private ClickHouseSqlStatement handleOutFileForSelectQuery(String sql, Statement
builder.append(sql.substring(index));
}
return new ClickHouseSqlStatement(builder.toString(), stmtType, cluster, database, table, input,
compressAlgorithm, compressLevel, format, file, parameters, null, settings, null);
compressAlgorithm, compressLevel, format, file, parameters, null, settings, null, 0);
}

@Override
public ClickHouseSqlStatement handleStatement(String sql, StatementType stmtType, String cluster, String database,
String table, String input, String compressAlgorithm, String compressLevel, String format, String file,
List<Integer> parameters, Map<String, Integer> positions, Map<String, String> settings,
Set<String> tempTables) {
Set<String> tempTables, int valueGroups) {
boolean hasFile = allowLocalFile && !ClickHouseChecker.isNullOrEmpty(file) && file.charAt(0) == '\'';
ClickHouseSqlStatement s = null;
if (stmtType == StatementType.DELETE) {
Expand All @@ -149,7 +149,7 @@ public ClickHouseSqlStatement handleStatement(String sql, StatementType stmtType
format, file, parameters, positions, settings, tempTables);
} else if (stmtType == StatementType.INSERT && hasFile) {
s = handleInFileForInsertQuery(sql, stmtType, cluster, database, table, input, compressAlgorithm,
compressLevel, format, file, parameters, positions, settings, tempTables);
compressLevel, format, file, parameters, positions, settings, tempTables, valueGroups);
} else if (stmtType == StatementType.SELECT && hasFile) {
s = handleOutFileForSelectQuery(sql, stmtType, cluster, database, table, input, compressAlgorithm,
compressLevel, format, file, parameters, positions, settings, tempTables);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public String handleParameter(String cluster, String database, String table, int
public ClickHouseSqlStatement handleStatement(String sql, StatementType stmtType, String cluster, String database,
String table, String input, String compressAlgorithm, String compressLevel, String format, String file,
List<Integer> parameters, Map<String, Integer> positions, Map<String, String> settings,
Set<String> tempTables) {
Set<String> tempTables, int valueGroup) {
return null;
}
}
16 changes: 11 additions & 5 deletions jdbc-v2/src/main/javacc/ClickHouseSqlParser.jj
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ TOKEN_MGR_DECLS: {
String compressLevel = null;
String format = null;
String file = null;
int valueGroups = 0;

final List<Integer> parameters = new ArrayList<>();
final Map<String, Integer> positions = new HashMap<>();
Expand Down Expand Up @@ -276,12 +277,12 @@ TOKEN_MGR_DECLS: {

if (handler != null) {
s = handler.handleStatement(
sqlStmt, stmtType, cluster, database, table, input, compressAlgorithm, compressLevel, format, file, parameters, positions, settings, tempTables);
sqlStmt, stmtType, cluster, database, table, input, compressAlgorithm, compressLevel, format, file, parameters, positions, settings, tempTables, valueGroups);
}

if (s == null) {
s = new ClickHouseSqlStatement(
sqlStmt, stmtType, cluster, database, table, input, compressAlgorithm, compressLevel, format, file, parameters, positions, settings, tempTables);
sqlStmt, stmtType, cluster, database, table, input, compressAlgorithm, compressLevel, format, file, parameters, positions, settings, tempTables, valueGroups);
}

// reset variables
Expand Down Expand Up @@ -323,6 +324,9 @@ TOKEN_MGR_DECLS: {

this.settings.put(key.toLowerCase(Locale.ROOT), value);
}
void incValueGroup() {
this.valueGroups++;
}
}

SKIP: {
Expand Down Expand Up @@ -366,7 +370,7 @@ SKIP: {
}
}
}
| <SINGLE_LINE_COMMENT: ("--" | "//") (~["\r", "\n"])*> { append(image); }
| <SINGLE_LINE_COMMENT: ("--" | "//" | "#" | "#!") (~["\r", "\n"])*> { append(image); }
| "/*" { commentNestingDepth = 1; append(image); }: MULTI_LINE_COMMENT
}

Expand Down Expand Up @@ -418,6 +422,7 @@ void stmt(): {} {
| optimizeStmt() { token_source.stmtType = StatementType.OPTIMIZE; }
| renameStmt() { token_source.stmtType = StatementType.RENAME; }
| revokeStmt() { token_source.stmtType = StatementType.REVOKE; }
| <LPAREN> selectStmt() <RPAREN> { token_source.stmtType = StatementType.SELECT; }
| selectStmt() { token_source.stmtType = StatementType.SELECT; }
| setStmt() { token_source.stmtType = StatementType.SET; }
| showStmt() { token_source.stmtType = StatementType.SHOW; }
Expand Down Expand Up @@ -569,12 +574,12 @@ void dataClause(): {} {
try {
LOOKAHEAD(2) <VALUES> { token_source.addPosition(token); }
<LPAREN> { token_source.addCustomKeywordPosition(ClickHouseSqlStatement.KEYWORD_VALUES_START, token); }
columnExprList()
columnExprList() { token_source.incValueGroup(); }
<RPAREN> { token_source.addCustomKeywordPosition(ClickHouseSqlStatement.KEYWORD_VALUES_END, token); }
(
LOOKAHEAD(2)
(<COMMA>)?
<LPAREN> { token_source.removePosition(ClickHouseSqlStatement.KEYWORD_VALUES_START); }
<LPAREN> { token_source.removePosition(ClickHouseSqlStatement.KEYWORD_VALUES_START); token_source.incValueGroup(); }
columnExprList()
<RPAREN> { token_source.removePosition(ClickHouseSqlStatement.KEYWORD_VALUES_END); }
)*
Expand Down Expand Up @@ -656,6 +661,7 @@ void showStmt(): {} {
LOOKAHEAD(2)
<CREATE>
(<DATABASE> databaseIdentifier(true))
| LOOKAHEAD(2) (LOOKAHEAD(1) <CREATE>)? (LOOKAHEAD(1) <SETTINGS>)? <PROFILE> anyIdentifier()
| LOOKAHEAD(2) (<DICTIONARY> tableIdentifier(true))
| LOOKAHEAD(2) ((LOOKAHEAD(2) <TEMPORARY>)? (LOOKAHEAD(2) <TABLE>)? tableIdentifier(true))
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,14 @@ public static Object[][] testPreparedStatementInsertSQLDP() {
+ "#! line comment3 ?\n"
+ "/* block comment ? \n */"
+ "INSERT INTO `with_complex_id`(`v?``1`, \"v?\"\"2\",`v?\\`3`, \"v?\\\"4\") VALUES (?, ?, ?, ?);", 1, false, 4},
{"-- 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 (?, ?, ?, ?);", 1, false, 4},
{ "INSERT INTO `test_stmt_split2` VALUES (1, 'abc'), (2, '?'), (3, '?')", 3, false, 0 },
{ "INSERT INTO `with_complex_id`(`v?``1`, \"v?\"\"2\",`v?\\`3`, \"v?\\\"4\") VALUES (?, ?, ?, ?);", 1, false, 4},
{ "INSERT INTO tt SELECT now(), 10, 20.0, 30", -1, true, 0 },
{ "INSERT INTO tt SELECT now(), 10, 20.0, 30", 0, true, 0 },
{ "INSERT INTO `users` (`name`, `last_login`, `password`, `id`) VALUES\n" +
" (?, `parseDateTimeBestEffort`(?, ?), ?, 1)\n", 1, false, 4 },
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import org.testng.annotations.Ignore;

@Ignore
//@Ignore
public class JavaCCParserTest extends BaseSqlParserFacadeTest {
public JavaCCParserTest() throws Exception {
super(SqlParserFacade.SQLParser.JAVACC.name());
Expand Down
Loading