Skip to content

Commit b6201fa

Browse files
authored
Merge pull request #2317 from ClickHouse/fix_minor_bugs
[jdbc-v2] Fixed some minor issues
2 parents 5a96f47 + e354baf commit b6201fa

File tree

3 files changed

+57
-35
lines changed

3 files changed

+57
-35
lines changed

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

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import java.time.format.DateTimeFormatterBuilder;
4545
import java.time.temporal.ChronoField;
4646
import java.util.ArrayList;
47+
import java.util.Arrays;
4748
import java.util.Calendar;
4849
import java.util.Collection;
4950
import java.util.Collections;
@@ -61,19 +62,20 @@ public class PreparedStatementImpl extends StatementImpl implements PreparedStat
6162

6263
private final Calendar defaultCalendar;
6364

64-
String originalSql;
65-
String [] sqlSegments;
66-
String [] valueSegments;
67-
Object [] parameters;
68-
String insertIntoSQL;
69-
StatementType statementType;
65+
private final String originalSql;
66+
private final String [] sqlSegments;
67+
private String [] valueSegments;
68+
private final Object [] parameters;
69+
private String insertIntoSQL;
70+
private final StatementType statementType;
7071

7172
private final ParameterMetaData parameterMetaData;
7273

7374
private ResultSetMetaData resultSetMetaData = null;
7475

7576
public PreparedStatementImpl(ConnectionImpl connection, String sql) throws SQLException {
7677
super(connection);
78+
this.isPoolable = true; // PreparedStatement is poolable by default
7779
this.originalSql = sql.trim();
7880
//Split the sql string into an array of strings around question mark tokens
7981
this.sqlSegments = splitStatement(originalSql);
@@ -216,11 +218,11 @@ public void setBinaryStream(int parameterIndex, InputStream x, int length) throw
216218
@Override
217219
public void clearParameters() throws SQLException {
218220
checkClosed();
219-
if (originalSql.contains("?")) {
220-
this.parameters = new Object[sqlSegments.length - 1];
221-
} else {
222-
this.parameters = new Object[0];
223-
}
221+
Arrays.fill(this.parameters, null);
222+
}
223+
224+
int getParametersCount() {
225+
return parameters.length;
224226
}
225227

226228
@Override
@@ -245,35 +247,53 @@ public boolean execute() throws SQLException {
245247
public void addBatch() throws SQLException {
246248
checkClosed();
247249
if (statementType == StatementType.INSERT) {
250+
// adding values to the end of big INSERT statement.
248251
addBatch(compileSql(valueSegments));
249252
} else {
250253
addBatch(compileSql(sqlSegments));
251254
}
252-
253255
}
254256

255257
@Override
256258
public int[] executeBatch() throws SQLException {
257259
checkClosed();
258260
if (statementType == StatementType.INSERT && !batch.isEmpty()) {
259-
List<Integer> results = new ArrayList<>();
260261
// write insert into as batch to avoid multiple requests
261262
StringBuilder sb = new StringBuilder();
262263
sb.append(insertIntoSQL).append(" ");
263264
for (String sql : batch) {
264265
sb.append(sql).append(",");
265266
}
266267
sb.setCharAt(sb.length() - 1, ';');
267-
results.add(executeUpdate(sb.toString()));
268+
int rowsInserted = executeUpdate(sb.toString());
268269
// clear batch and re-add insert into
270+
int[] results = new int[batch.size()];
271+
if (rowsInserted == batch.size()) {
272+
// each batch is effectively 1 row inserted.
273+
Arrays.fill(results, 1);
274+
} else {
275+
// we do not have information what rows are not inserted.
276+
// this should happen only with async insert when we do not wait final result
277+
Arrays.fill(results, PreparedStatement.SUCCESS_NO_INFO);
278+
}
269279
batch.clear();
270-
return results.stream().mapToInt(i -> i).toArray();
280+
return results;
271281
} else {
272282
// run executeBatch
273283
return super.executeBatch();
274284
}
275285
}
276286

287+
@Override
288+
public long[] executeLargeBatch() throws SQLException {
289+
int[] results = executeBatch();
290+
long[] longResults = new long[results.length];
291+
for (int i = 0; i < results.length; i++) {
292+
longResults[i] = results[i];
293+
}
294+
return longResults;
295+
}
296+
277297
@Override
278298
public void setCharacterStream(int parameterIndex, Reader x, int length) throws SQLException {
279299
checkClosed();
@@ -523,8 +543,7 @@ public void setObject(int parameterIndex, Object x, SQLType targetSqlType) throw
523543

524544
@Override
525545
public long executeLargeUpdate() throws SQLException {
526-
checkClosed();
527-
return PreparedStatement.super.executeLargeUpdate();
546+
return executeUpdate();
528547
}
529548

530549
private static String encodeObject(Object x) throws SQLException {

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

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public class StatementImpl implements Statement, JdbcV2Wrapper {
3838
private volatile String lastQueryId;
3939
private String schema;
4040
private int maxRows;
41+
protected boolean isPoolable = false; // Statement is not poolable by default
4142
public StatementImpl(ConnectionImpl connection) throws SQLException {
4243
this.connection = connection;
4344
this.queryTimeout = 0;
@@ -382,7 +383,7 @@ public boolean execute(String sql, QuerySettings settings) throws SQLException {
382383
//USE Database
383384
List<String> tokens = JdbcUtils.tokenizeSQL(sql);
384385
this.schema = tokens.get(1).replace("\"", "");
385-
LOG.info("Changed statement schema " + schema);
386+
LOG.debug("Changed statement schema {}", schema);
386387
return false;
387388
} else {
388389
executeUpdate(sql, settings);
@@ -468,12 +469,16 @@ public void clearBatch() throws SQLException {
468469

469470
@Override
470471
public int[] executeBatch() throws SQLException {
472+
return executeBatchImpl().stream().mapToInt(i -> i).toArray();
473+
}
474+
475+
private List<Integer> executeBatchImpl() throws SQLException {
471476
checkClosed();
472477
List<Integer> results = new ArrayList<>();
473478
for (String sql : batch) {
474479
results.add(executeUpdate(sql));
475480
}
476-
return results.stream().mapToInt(i -> i).toArray();
481+
return results;
477482
}
478483

479484
@Override
@@ -483,11 +488,13 @@ public Connection getConnection() throws SQLException {
483488

484489
@Override
485490
public boolean getMoreResults(int current) throws SQLException {
491+
// TODO: implement query batches. When multiple selects in the batch.
486492
return false;
487493
}
488494

489495
@Override
490496
public ResultSet getGeneratedKeys() throws SQLException {
497+
// TODO: return empty result set or throw exception
491498
return null;
492499
}
493500

@@ -523,7 +530,7 @@ public boolean execute(String sql, String[] columnNames) throws SQLException {
523530

524531
@Override
525532
public int getResultSetHoldability() throws SQLException {
526-
return 0;
533+
return ResultSet.HOLD_CURSORS_OVER_COMMIT; // we do not have transactions and result must be closed by app.
527534
}
528535

529536
@Override
@@ -534,11 +541,12 @@ public boolean isClosed() throws SQLException {
534541
@Override
535542
public void setPoolable(boolean poolable) throws SQLException {
536543
checkClosed();
544+
this.isPoolable = poolable;
537545
}
538546

539547
@Override
540548
public boolean isPoolable() throws SQLException {
541-
return false;
549+
return isPoolable;
542550
}
543551

544552
@Override
@@ -554,7 +562,7 @@ public boolean isCloseOnCompletion() throws SQLException {
554562
@Override
555563
public long getLargeUpdateCount() throws SQLException {
556564
checkClosed();
557-
return Statement.super.getLargeUpdateCount();
565+
return getUpdateCount();
558566
}
559567

560568
@Override
@@ -566,37 +574,32 @@ public void setLargeMaxRows(long max) throws SQLException {
566574
@Override
567575
public long getLargeMaxRows() throws SQLException {
568576
checkClosed();
569-
return Statement.super.getLargeMaxRows();
577+
return getMaxRows();
570578
}
571579

572580
@Override
573581
public long[] executeLargeBatch() throws SQLException {
574-
checkClosed();
575-
return Statement.super.executeLargeBatch();
582+
return executeBatchImpl().stream().mapToLong(Integer::longValue).toArray();
576583
}
577584

578585
@Override
579586
public long executeLargeUpdate(String sql) throws SQLException {
580-
checkClosed();
581-
return Statement.super.executeLargeUpdate(sql);
587+
return executeUpdate(sql);
582588
}
583589

584590
@Override
585591
public long executeLargeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
586-
checkClosed();
587-
return Statement.super.executeLargeUpdate(sql, autoGeneratedKeys);
592+
return executeUpdate(sql, autoGeneratedKeys);
588593
}
589594

590595
@Override
591596
public long executeLargeUpdate(String sql, int[] columnIndexes) throws SQLException {
592-
checkClosed();
593-
return Statement.super.executeLargeUpdate(sql, columnIndexes);
597+
return executeUpdate(sql, columnIndexes);
594598
}
595599

596600
@Override
597601
public long executeLargeUpdate(String sql, String[] columnNames) throws SQLException {
598-
checkClosed();
599-
return Statement.super.executeLargeUpdate(sql, columnNames);
602+
return executeUpdate(sql, columnNames);
600603
}
601604

602605
@Override

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -564,15 +564,15 @@ void testClearParameters() throws Exception {
564564
stmt.execute("CREATE TABLE IF NOT EXISTS `test_issue_2299` (`id` Nullable(String), `name` Nullable(String), `age` Int32) ENGINE Memory;");
565565
}
566566

567-
Assert.assertEquals(ps.parameters.length, 3);
567+
Assert.assertEquals(ps.getParametersCount(), 3);
568568

569569
ps.setString(1, "testId");
570570
ps.setString(2, "testName");
571571
ps.setInt(3, 18);
572572
ps.execute();
573573

574574
ps.clearParameters();
575-
Assert.assertEquals(ps.parameters.length, 3);
575+
Assert.assertEquals(ps.getParametersCount(), 3);
576576

577577
ps.setString(1, "testId2");
578578
ps.setString(2, "testName2");

0 commit comments

Comments
 (0)