Skip to content

Commit 3824774

Browse files
committed
fixed bug with replacing literal '?' with NULL
1 parent 65572ef commit 3824774

File tree

4 files changed

+37
-4
lines changed

4 files changed

+37
-4
lines changed

jdbc-v2/src/main/java/com/clickhouse/jdbc/PreparedStatementImpl.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ public ResultSetMetaData getMetaData() throws SQLException {
314314
// before execution
315315
if (statementType == StatementType.SELECT) {
316316
try {
317+
// Replace '?' with NULL to make SQL valid for DESCRIBE
317318
String sql = JdbcUtils.replaceQuestionMarks(originalSql, JdbcUtils.NULL);
318319
TableSchema tSchema = connection.getClient().getTableSchemaFromQuery(sql);
319320
resultSetMetaData = new ResultSetMetaDataImpl(tSchema.getColumns(),

jdbc-v2/src/main/java/com/clickhouse/jdbc/internal/JdbcUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ public static String escapeQuotes(String str) {
287287

288288
public static final String NULL = "NULL";
289289

290-
private static final Pattern REPLACE_Q_MARK_PATTERN = Pattern.compile("(\"[^\"]*\"|`[^`]*`)|(\\?)");
290+
private static final Pattern REPLACE_Q_MARK_PATTERN = Pattern.compile("(\"[^\"]*\"|`[^`]*`|'[^']*')|(\\?)");
291291

292292
public static String replaceQuestionMarks(String sql, String replacement) {
293293
Matcher matcher = REPLACE_Q_MARK_PATTERN.matcher(sql);

jdbc-v2/src/test/java/com/clickhouse/jdbc/PreparedStatementTest.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,6 @@ void testGetMetadata(String sql, int colCountBeforeExecution, Object[] values,
337337
Assert.assertEquals(metadataRs.getColumnCount(), colCountBeforeExecution);
338338

339339
for (int i = 1; i <= metadataRs.getColumnCount(); i++) {
340-
System.out.println("label=" + metadataRs.getColumnName(i) + " type=" + metadataRs.getColumnType(i));
341340
assertEquals(metadataRs.getSchemaName(i), stmt.getConnection().getSchema());
342341
}
343342

@@ -353,7 +352,6 @@ void testGetMetadata(String sql, int colCountBeforeExecution, Object[] values,
353352
assertNotNull(metadataRs);
354353
assertEquals(metadataRs.getColumnCount(), colCountAfterExecution);
355354
for (int i = 1; i <= metadataRs.getColumnCount(); i++) {
356-
System.out.println("label=" + metadataRs.getColumnName(i) + " type=" + metadataRs.getColumnType(i));
357355
assertEquals(metadataRs.getSchemaName(i), stmt.getConnection().getSchema());
358356
}
359357
}
@@ -503,7 +501,10 @@ void testMetabaseBug01() throws Exception {
503501
void testStatementSplit() throws Exception {
504502
try (Connection conn = getJdbcConnection()) {
505503
try (Statement stmt = conn.createStatement()) {
506-
stmt.execute("CREATE TABLE `with_complex_id` (`v?``1` Int32, \"v?\"\"2\" Int32,`v?\\`3` Int32, \"v?\\\"4\" Int32) ENGINE Memory;");
504+
stmt.execute("CREATE TABLE IF NOT EXISTS `with_complex_id` (`v?``1` Int32, " +
505+
"\"v?\"\"2\" Int32,`v?\\`3` Int32, \"v?\\\"4\" Int32) ENGINE MergeTree ORDER BY ();");
506+
stmt.execute("CREATE TABLE IF NOT EXISTS `test_stmt_split2` (v1 Int32, v2 String) ENGINE MergeTree ORDER BY (); ");
507+
stmt.execute("INSERT INTO `test_stmt_split2` VALUES (1, 'abc'), (2, '?'), (3, '?')");
507508
}
508509
String insertQuery = "-- line comment1 ?\n"
509510
+ "# line comment2 ?\n"
@@ -536,6 +537,20 @@ void testStatementSplit() throws Exception {
536537
assertEquals(rs.getString(7), "test string3 ?\\");
537538
}
538539
}
540+
541+
try (PreparedStatement stmt = conn.prepareStatement("SELECT v1 FROM `test_stmt_split2` WHERE v1 > ? AND v2 = '?'")) {
542+
stmt.setInt(1, 2);
543+
try (ResultSet rs = stmt.executeQuery()) {
544+
int count = 0;
545+
while (rs.next()) {
546+
count++;
547+
assertEquals(rs.getInt(1), 3);
548+
}
549+
550+
Assert.assertEquals(count, 1);
551+
}
552+
}
553+
539554
}
540555
}
541556
}

jdbc-v2/src/test/java/com/clickhouse/jdbc/internal/JdbcUtilsTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.clickhouse.jdbc.internal;
22

3+
import org.testng.annotations.DataProvider;
34
import org.testng.annotations.Test;
45

56
import java.util.List;
@@ -57,4 +58,20 @@ public void testEscapeQuotes() {
5758
assertEquals(JdbcUtils.escapeQuotes(inStr[i]), outStr[i]);
5859
}
5960
}
61+
62+
@Test(dataProvider = "testReplaceQuestionMark_dataProvider")
63+
public void testReplaceQuestionMark(String sql, String result) {
64+
assertEquals(JdbcUtils.replaceQuestionMarks(sql, "NULL"), result);
65+
}
66+
67+
@DataProvider(name = "testReplaceQuestionMark_dataProvider")
68+
public static Object[][] testReplaceQuestionMark_dataProvider() {
69+
return new Object[][] {
70+
{"", ""},
71+
{" ", " "},
72+
{"SELECT * FROM t WHERE a = '?'", "SELECT * FROM t WHERE a = '?'"},
73+
{"SELECT `v2?` FROM t WHERE `v1?` = ?", "SELECT `v2?` FROM t WHERE `v1?` = NULL"},
74+
{"INSERT INTO \"t2?\" VALUES (?, ?, 'some_?', ?)", "INSERT INTO \"t2?\" VALUES (NULL, NULL, 'some_?', NULL)"}
75+
};
76+
}
6077
}

0 commit comments

Comments
 (0)