Skip to content

Commit d42b67a

Browse files
committed
implemented parameters are set check.
1 parent 9c6ba32 commit d42b67a

File tree

3 files changed

+93
-14
lines changed

3 files changed

+93
-14
lines changed

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

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -117,15 +117,18 @@ public PreparedStatementImpl(ConnectionImpl connection, String sql, ParsedPrepar
117117
}
118118
}
119119

120-
private String buildSQL() {
120+
private String buildSQL() throws SQLException {
121121
StringBuilder compiledSql = new StringBuilder(originalSql);
122122
int posOffset = 0;
123123
int[] positions = parsedPreparedStatement.getParamPositions();
124124
for (int i = 0; i < argCount; i++) {
125125
int p = positions[i] + posOffset;
126126
String val = values[i];
127-
compiledSql.replace(p, p+1, val == null ? "NULL" : val);
128-
posOffset += val == null ? 0 : val.length() - 1;
127+
if (val == null) {
128+
throw new SQLException("Parameter at position '" + i + "' is not set");
129+
}
130+
compiledSql.replace(p, p+1, val);
131+
posOffset += val.length() - 1;
129132
}
130133
return compiledSql.toString();
131134
}
@@ -134,7 +137,6 @@ private String buildSQL() {
134137
public ResultSet executeQuery() throws SQLException {
135138
ensureOpen();
136139
String buildSQL = buildSQL();
137-
LOG.debug("Executing SQL: " + buildSQL);
138140
return super.executeQueryImpl(buildSQL, localSettings);
139141
}
140142

@@ -894,12 +896,14 @@ private static String encodeCharacterStream(Reader reader, Long length) throws S
894896
}
895897

896898
StringBuilder sb = new StringBuilder();
897-
try (reader) {
899+
try {
898900
char[] buffer = new char[1024];
899901
int len;
900902
while ((len = reader.read(buffer)) != -1) {
901903
sb.append(buffer, 0, len);
902904
}
905+
906+
reader.close();
903907
} catch (IOException e) {
904908
LOG.error("Error reading string from input stream", e);
905909
throw new SQLException("Error reading string from input stream", ExceptionUtils.SQL_STATE_SQL_ERROR, e);
@@ -912,20 +916,35 @@ private static String encodeCharacterStream(Reader reader, Long length) throws S
912916
}
913917
}
914918

915-
private ClickHouseDataType jdbcType2ClickHouseDataType(JDBCType type) {
916-
return null;
919+
private ClickHouseDataType jdbcType2ClickHouseDataType(JDBCType type) throws SQLException{
920+
ClickHouseDataType clickHouseDataType = JdbcUtils.SQL_TO_CLICKHOUSE_TYPE_MAP.get(type);
921+
if (clickHouseDataType == null) {
922+
throw new SQLException("Cannot convert " + type + " to a ClickHouse one. Consider using java.sql.JDBCType or com.clickhouse.data.ClickHouseDataType");
923+
}
924+
925+
return clickHouseDataType;
917926
}
918927

919928
private ClickHouseDataType sqlType2ClickHouseDataType(SQLType type) throws SQLException {
929+
ClickHouseDataType clickHouseDataType = null;
920930
if (type instanceof JDBCType) {
921-
return jdbcType2ClickHouseDataType((JDBCType) type);
931+
clickHouseDataType = JdbcUtils.SQL_TO_CLICKHOUSE_TYPE_MAP.get(type);
922932
} else if (type instanceof ClickHouseDataType) {
923-
return (ClickHouseDataType) type;
933+
clickHouseDataType = (ClickHouseDataType) type;
924934
}
925-
throw new SQLException("Cannot convert " + type + " to a ClickHouse one. Consider using java.sql.JDBCType or com.clickhouse.data.ClickHouseDataType");
935+
936+
if (clickHouseDataType == null) {
937+
throw new SQLException("Cannot convert " + type + " to a ClickHouse one. Consider using java.sql.JDBCType or com.clickhouse.data.ClickHouseDataType");
938+
}
939+
940+
return clickHouseDataType;
926941
}
927942

928943
private String encodeObject(Object x, ClickHouseDataType clickHouseDataType, Integer scaleOrLength) throws SQLException {
929-
return encodeObject(x) + "::" + clickHouseDataType.name();
944+
String encodedObject = encodeObject(x);
945+
if (clickHouseDataType != null) {
946+
encodedObject += "::" + clickHouseDataType.name();
947+
}
948+
return encodedObject;
930949
}
931950
}

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.List;
2929
import java.util.Map;
3030
import java.util.TreeMap;
31+
import java.util.stream.Collectors;
3132

3233
public class JdbcUtils {
3334
//Define a map to store the mapping between ClickHouse data types and SQL data types
@@ -168,6 +169,35 @@ private static Map<ClickHouseDataType, Class<?>> getDataTypeClassMap() {
168169
return map;
169170
}
170171

172+
public static final Map<SQLType, ClickHouseDataType> SQL_TO_CLICKHOUSE_TYPE_MAP = createSQLToClickHouseDataTypeMap();
173+
174+
private static Map<SQLType, ClickHouseDataType> createSQLToClickHouseDataTypeMap() {
175+
Map<SQLType, ClickHouseDataType> map = new HashMap<>();
176+
map.put(JDBCType.TINYINT, ClickHouseDataType.Int8);
177+
map.put(JDBCType.SMALLINT, ClickHouseDataType.Int16);
178+
map.put(JDBCType.INTEGER, ClickHouseDataType.Int32);
179+
map.put(JDBCType.BIGINT, ClickHouseDataType.Int64);
180+
map.put(JDBCType.FLOAT, ClickHouseDataType.Float32);
181+
map.put(JDBCType.REAL, ClickHouseDataType.Float32);
182+
map.put(JDBCType.DOUBLE, ClickHouseDataType.Float64);
183+
map.put(JDBCType.BOOLEAN, ClickHouseDataType.Bool);
184+
map.put(JDBCType.DATE, ClickHouseDataType.Date32);
185+
map.put(JDBCType.TIME, ClickHouseDataType.Time);
186+
map.put(JDBCType.TIMESTAMP, ClickHouseDataType.DateTime64);
187+
map.put(JDBCType.TIMESTAMP_WITH_TIMEZONE, ClickHouseDataType.DateTime64);
188+
map.put(JDBCType.BINARY, ClickHouseDataType.String);
189+
map.put(JDBCType.VARBINARY, ClickHouseDataType.String);
190+
map.put(JDBCType.LONGVARBINARY, ClickHouseDataType.String);
191+
map.put(JDBCType.CHAR, ClickHouseDataType.String);
192+
map.put(JDBCType.NCHAR, ClickHouseDataType.String);
193+
map.put(JDBCType.VARCHAR, ClickHouseDataType.String);
194+
map.put(JDBCType.LONGNVARCHAR, ClickHouseDataType.String);
195+
map.put(JDBCType.NVARCHAR, ClickHouseDataType.String);
196+
map.put(JDBCType.DECIMAL, ClickHouseDataType.Decimal32);
197+
map.put(JDBCType.ARRAY, ClickHouseDataType.Array);
198+
return Collections.unmodifiableMap(map);
199+
}
200+
171201
public static SQLType convertToSqlType(ClickHouseDataType clickhouseType) {
172202
if (clickhouseType == null) {
173203
return JDBCType.OTHER;

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

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import static org.testng.Assert.assertNull;
4343
import static org.testng.Assert.assertThrows;
4444
import static org.testng.Assert.assertTrue;
45+
import static org.testng.Assert.expectThrows;
4546

4647
@Test(groups = { "integration" })
4748
public class PreparedStatementTest extends JdbcIntegrationTest {
@@ -1152,7 +1153,7 @@ public void testNullValues() throws Exception {
11521153
try (PreparedStatement stmt = conn.prepareStatement("INSERT INTO " + table + " VALUES (?, ?)")) {
11531154
stmt.setInt(1, 10);
11541155
// do not set second value
1155-
assertEquals(stmt.executeUpdate(), 1);
1156+
expectThrows(SQLException.class, stmt::executeUpdate);
11561157
stmt.setInt(1, 20);
11571158
stmt.setObject(2, null);
11581159
assertEquals(stmt.executeUpdate(), 1);
@@ -1167,7 +1168,7 @@ public void testNullValues() throws Exception {
11671168
assertNull(rs.getObject(2));
11681169
}
11691170

1170-
assertEquals(count, 2);
1171+
assertEquals(count, 1);
11711172
}
11721173
}
11731174
}
@@ -1261,7 +1262,6 @@ public void testWithInClause() throws Exception {
12611262

12621263
@Test(groups = {"integration"})
12631264
public void testTypeCasts() throws Exception {
1264-
12651265
try (Connection conn = getJdbcConnection()) {
12661266
try (PreparedStatement stmt = conn.prepareStatement("select ?, toTypeName(?)")) {
12671267
stmt.setObject(1, 100, ClickHouseDataType.Int8);
@@ -1274,6 +1274,36 @@ public void testTypeCasts() throws Exception {
12741274
}
12751275
}
12761276
}
1277+
}
1278+
1279+
@Test(groups = {"integration"})
1280+
public void testCheckOfParametersAreSet() throws Exception {
1281+
try (Connection conn = getJdbcConnection()) {
1282+
try (PreparedStatement stmt = conn.prepareStatement("select ? as v1, ? as v2, ? as v3")) {
1283+
stmt.setString(1, "Test");
1284+
stmt.setObject(2, null);
1285+
stmt.setString(3, null);
1286+
1287+
try (ResultSet rs = stmt.executeQuery()) {
1288+
rs.next();
1289+
Assert.assertEquals(rs.getString(1), "Test");
1290+
Assert.assertEquals(rs.getInt(2), 0);
1291+
Assert.assertTrue(rs.wasNull());
1292+
Assert.assertNull(rs.getString(2));
1293+
Assert.assertTrue(rs.wasNull());
1294+
}
1295+
1296+
stmt.clearParameters();
1297+
stmt.setString(1, "Test");
1298+
stmt.setObject(2, null);
1299+
Assert.expectThrows(SQLException.class, stmt::executeQuery);
1300+
}
1301+
1302+
try (PreparedStatement stmt = conn.prepareStatement("INSERT INTO t VALUES (?, ?, ?)")) {
1303+
stmt.setString(1, "Test");
12771304

1305+
Assert.expectThrows(SQLException.class, stmt::executeUpdate);
1306+
}
1307+
}
12781308
}
12791309
}

0 commit comments

Comments
 (0)