Skip to content

Commit e31fee4

Browse files
authored
Merge pull request #855 from zhicwu/prepare-patch
Prepare patch6
2 parents 254c97c + 09cd66e commit e31fee4

22 files changed

+206
-88
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ Note: in general, the new driver(v0.3.2) is a few times faster with less memory
112112
<groupId>com.clickhouse</groupId>
113113
<!-- or clickhouse-grpc-client if you prefer gRPC -->
114114
<artifactId>clickhouse-http-client</artifactId>
115-
<version>0.3.2-patch5</version>
115+
<version>0.3.2-patch6</version>
116116
</dependency>
117117
```
118118

@@ -148,7 +148,7 @@ try (ClickHouseClient client = ClickHouseClient.newInstance(preferredProtocol);
148148
<!-- will stop using ru.yandex.clickhouse starting from 0.4.0 -->
149149
<groupId>com.clickhouse</groupId>
150150
<artifactId>clickhouse-jdbc</artifactId>
151-
<version>0.3.2-patch5</version>
151+
<version>0.3.2-patch6</version>
152152
<!-- below is only needed when all you want is a shaded jar -->
153153
<classifier>http</classifier>
154154
<exclusions>

clickhouse-client/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Async Java client for ClickHouse. `clickhouse-client` is an abstract module, so
99
<dependency>
1010
<groupId>com.clickhouse</groupId>
1111
<artifactId>clickhouse-http-client</artifactId>
12-
<version>0.3.2-patch5</version>
12+
<version>0.3.2-patch6</version>
1313
</dependency>
1414
```
1515

clickhouse-client/src/main/java/com/clickhouse/client/data/ClickHouseOffsetDateTimeValue.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,8 @@ public ClickHouseOffsetDateTimeValue update(String value) {
356356
if (value == null) {
357357
resetToNullOrEmpty();
358358
} else {
359-
set(OffsetDateTime.parse(value, ClickHouseValues.DATETIME_FORMATTER));
359+
set(LocalDateTime.parse(value, ClickHouseValues.DATETIME_FORMATTER).atZone(tz.toZoneId())
360+
.toOffsetDateTime());
360361
}
361362
return this;
362363
}

clickhouse-client/src/main/java/com/clickhouse/client/data/ClickHouseRowBinaryProcessor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ private void buildMappingsForDataTypes() {
286286
buildMappings(deserializers, serializers,
287287
(r, f, c, i) -> ClickHouseDateValue.of(r,
288288
BinaryStreamUtils.readDate32(i, f.getTimeZoneForDate())),
289-
(v, f, c, o) -> BinaryStreamUtils.writeDate(o, v.asDate(), f.getTimeZoneForDate()),
289+
(v, f, c, o) -> BinaryStreamUtils.writeDate32(o, v.asDate(), f.getTimeZoneForDate()),
290290
ClickHouseDataType.Date32);
291291
buildMappings(deserializers, serializers, (r, f, c, i) -> c.getTimeZone() == null
292292
? ClickHouseDateTimeValue.of(r,

clickhouse-client/src/main/java/com/clickhouse/client/data/array/ClickHouseByteArrayValue.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ public ClickHouseByteArrayValue update(String value) {
414414
byte[] arr = new byte[list.size()];
415415
int index = 0;
416416
for (String v : list) {
417-
arr[index++] = Byte.parseByte(v);
417+
arr[index++] = v == null ? (byte) 0 : Byte.parseByte(v);
418418
}
419419
set(arr);
420420
}

clickhouse-client/src/main/java/com/clickhouse/client/data/array/ClickHouseDoubleArrayValue.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ public ClickHouseDoubleArrayValue update(String value) {
410410
double[] arr = new double[list.size()];
411411
int index = 0;
412412
for (String v : list) {
413-
arr[index++] = Double.parseDouble(v);
413+
arr[index++] = v == null ? 0D : Double.parseDouble(v);
414414
}
415415
set(arr);
416416
}

clickhouse-client/src/main/java/com/clickhouse/client/data/array/ClickHouseFloatArrayValue.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ public ClickHouseFloatArrayValue update(String value) {
410410
float[] arr = new float[list.size()];
411411
int index = 0;
412412
for (String v : list) {
413-
arr[index++] = Float.parseFloat(v);
413+
arr[index++] = v == null ? 0F : Float.parseFloat(v);
414414
}
415415
set(arr);
416416
}

clickhouse-client/src/main/java/com/clickhouse/client/data/array/ClickHouseIntArrayValue.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ public ClickHouseIntArrayValue update(String value) {
410410
int[] arr = new int[list.size()];
411411
int index = 0;
412412
for (String v : list) {
413-
arr[index++] = Integer.parseInt(v);
413+
arr[index++] = v == null ? 0 : Integer.parseInt(v);
414414
}
415415
set(arr);
416416
}

clickhouse-client/src/main/java/com/clickhouse/client/data/array/ClickHouseLongArrayValue.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ public ClickHouseLongArrayValue update(String value) {
410410
long[] arr = new long[list.size()];
411411
int index = 0;
412412
for (String v : list) {
413-
arr[index++] = Long.parseLong(v);
413+
arr[index++] = v == null ? 0L : Long.parseLong(v);
414414
}
415415
set(arr);
416416
}

clickhouse-client/src/main/java/com/clickhouse/client/data/array/ClickHouseShortArrayValue.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ public ClickHouseShortArrayValue update(String value) {
410410
short[] arr = new short[list.size()];
411411
int index = 0;
412412
for (String v : list) {
413-
arr[index++] = Short.parseShort(v);
413+
arr[index++] = v == null ? (short) 0 : Short.parseShort(v);
414414
}
415415
set(arr);
416416
}

clickhouse-client/src/test/java/com/clickhouse/client/ClickHouseUtilsTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,11 @@ public void testReadValueArray() {
375375
args.lastIndexOf(']') + 1);
376376
Assert.assertEquals(list, Arrays.asList("1", "2", "3"));
377377

378+
args = "[1, null , 3,, Null]";
379+
list.clear();
380+
Assert.assertEquals(ClickHouseUtils.readValueArray(args, 0, args.length(), list::add), args.length());
381+
Assert.assertEquals(list, Arrays.asList("1", null, "3", null, null));
382+
378383
args = "['1\\'2', '2,3' , '3\n4\r5']";
379384
list.clear();
380385
Assert.assertEquals(ClickHouseUtils.readValueArray(args, 0, args.length(), list::add), args.length());

clickhouse-jdbc/README.md

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Keep in mind that `clickhouse-jdbc` is synchronous, and in general it has more o
1111
<!-- will stop using ru.yandex.clickhouse starting from 0.4.0 -->
1212
<groupId>com.clickhouse</groupId>
1313
<artifactId>clickhouse-jdbc</artifactId>
14-
<version>0.3.2-patch5</version>
14+
<version>0.3.2-patch6</version>
1515
</dependency>
1616
```
1717

@@ -48,6 +48,10 @@ Note: please refer to [JDBC specific configuration](https://github.com/ClickHous
4848

4949
```java
5050
String url = "jdbc:ch://my-server/system"; // use http protocol and port 8123 by default
51+
// String url = "jdbc:ch://my-server:8443/system"; // if you prefer https
52+
Properties properties = new Properties();
53+
// properties.setProperty("ssl", "true");
54+
// properties.setProperty("sslmode", "NONE"); // NONE to trust all servers; STRICT for trusted only
5155
ClickHouseDataSource dataSource = new ClickHouseDataSource(url, new Properties());
5256
try (Connection conn = dataSource.getConnection("default", "password");
5357
Statement stmt = conn.createStatement()) {
@@ -69,7 +73,7 @@ Tips:
6973
2. Use [input function](https://clickhouse.com/docs/en/sql-reference/table-functions/input/) whenever possible
7074

7175
```java
72-
// create table mytable(id String, ts DateTime64(3), desc Nullable(String)) engine=Memory
76+
// create table mytable(id String, timestamp DateTime64(3), description Nullable(String)) engine=Memory
7377

7478
// 1. recommended as it performs the best
7579
try (PreparedStatement ps = conn.prepareStatement(
@@ -78,27 +82,28 @@ try (PreparedStatement ps = conn.prepareStatement(
7882
ps.setString(1, "test"); // col1
7983
ps.setObject(2, LocalDateTime.now()); // col2, setTimestamp is slow and not recommended
8084
ps.setInt(3, 123); // col3
81-
ps.addBatch(); // parameters will be write into stream in binary format
85+
ps.addBatch(); // parameters will be write into buffered stream immediately in binary format
8286
...
8387
ps.executeBatch(); // stream everything on-hand into ClickHouse
8488
}
8589

8690
// 2. easier to use but slower compare to input function
8791
try (PreparedStatement ps = conn.prepareStatement("insert into mytable(* except (desc))")) {
88-
// the driver will issue query "select * except (desc) from mytable where 0" for type inferring
89-
// since desc column is excluded, we know there are only two parameters: col1 and col2
90-
ps.setString(1, "test"); // col1
91-
ps.setObject(2, LocalDateTime.now()); // col2
92-
ps.addBatch(); // parameters will be write into stream in binary format
92+
// the driver will issue query "select * except (description) from mytable where 0" for type inferring
93+
// since description column is excluded, we know there are only two parameters: col1 and col2
94+
ps.setString(1, "test"); // id
95+
ps.setObject(2, LocalDateTime.now()); // timestamp
96+
ps.addBatch(); // parameters will be write into buffered stream immediately in binary format
9397
...
9498
ps.executeBatch(); // stream everything on-hand into ClickHouse
9599
}
96100

97101
// 3. not recommended as it's based on a large SQL
98-
try (PreparedStatement ps = conn.prepareStatement("insert into mytable values(?,?,?)")) {
99-
ps.setString(1, "test"); // col1
100-
ps.setObject(2, LocalDateTime.now()); // col2
101-
ps.setString(3, null); // col3
102+
// Note: "insert into mytable values(?,?,?)" is treated as "insert into mytable"
103+
try (PreparedStatement ps = conn.prepareStatement("insert into mytable values(trim(?),?,?)")) {
104+
ps.setString(1, "test"); // id
105+
ps.setObject(2, LocalDateTime.now()); // timestamp
106+
ps.setString(3, null); // description
102107
ps.addBatch(); // append parameters to the query
103108
...
104109
ps.executeBatch(); // issue the composed query: insert into mytable values(...)(...)...(...)

clickhouse-jdbc/src/main/java/com/clickhouse/jdbc/internal/AbstractPreparedStatement.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import java.sql.SQLException;
66

77
import com.clickhouse.client.ClickHouseRequest;
8+
import com.clickhouse.client.ClickHouseUtils;
89
import com.clickhouse.jdbc.SqlExceptionUtils;
910

1011
public abstract class AbstractPreparedStatement extends ClickHouseStatementImpl implements PreparedStatement {
@@ -15,6 +16,25 @@ protected AbstractPreparedStatement(ClickHouseConnectionImpl connection, ClickHo
1516

1617
protected abstract long[] executeAny(boolean asBatch) throws SQLException;
1718

19+
protected abstract int getMaxParameterIndex();
20+
21+
protected int toArrayIndex(int parameterIndex) throws SQLException {
22+
int max = getMaxParameterIndex();
23+
if (max < 1) {
24+
String name = getConnection().getJdbcConfig().useNamedParameter() ? "named parameter"
25+
: "JDBC style '?' placeholder";
26+
throw SqlExceptionUtils.clientError(ClickHouseUtils
27+
.format("Can't set parameter at index %d due to no %s found in the query",
28+
parameterIndex, name));
29+
} else if (parameterIndex < 1 || parameterIndex > max) {
30+
throw SqlExceptionUtils.clientError(ClickHouseUtils
31+
.format("Parameter index must between 1 and %d but we got %d", max,
32+
parameterIndex));
33+
}
34+
35+
return parameterIndex - 1;
36+
}
37+
1838
@Override
1939
public final void addBatch(String sql) throws SQLException {
2040
ensureOpen();

clickhouse-jdbc/src/main/java/com/clickhouse/jdbc/internal/ClickHouseConnectionImpl.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,10 +594,35 @@ public PreparedStatement prepareStatement(String sql, int resultSetType, int res
594594
throw SqlExceptionUtils
595595
.clientError(
596596
"External table, input function, and query parameter cannot be used together in PreparedStatement.");
597+
} else if (parsedStmt.getStatementType() == StatementType.INSERT &&
598+
!parsedStmt.containsKeyword("SELECT") && parsedStmt.hasValues() &&
599+
(!parsedStmt.hasFormat() || clientRequest.getFormat().name().equals(parsedStmt.getFormat()))) {
600+
String query = parsedStmt.getSQL();
601+
int startIndex = parsedStmt.getPositions().get(ClickHouseSqlStatement.KEYWORD_VALUES_START);
602+
int endIndex = parsedStmt.getPositions().get(ClickHouseSqlStatement.KEYWORD_VALUES_END);
603+
boolean useStream = true;
604+
for (int i = startIndex + 1; i < endIndex; i++) {
605+
char ch = query.charAt(i);
606+
if (ch != '?' && ch != ',' && !Character.isWhitespace(ch)) {
607+
useStream = false;
608+
break;
609+
}
610+
}
611+
612+
if (useStream) {
613+
ps = new InputBasedPreparedStatement(this,
614+
clientRequest.write().query(query.substring(0, parsedStmt.getStartPosition("VALUES")),
615+
newQueryId()),
616+
getTableColumns(parsedStmt.getDatabase(), parsedStmt.getTable(),
617+
parsedStmt.getContentBetweenKeywords(
618+
ClickHouseSqlStatement.KEYWORD_TABLE_COLUMNS_START,
619+
ClickHouseSqlStatement.KEYWORD_TABLE_COLUMNS_END)),
620+
resultSetType, resultSetConcurrency, resultSetHoldability);
621+
}
597622
}
598623
} else {
599624
if (parsedStmt.hasTempTable()) {
600-
// non-insert queries using temp table
625+
// queries using external/temporary table
601626
ps = new TableBasedPreparedStatement(this,
602627
clientRequest.write().query(parsedStmt.getSQL(), newQueryId()), parsedStmt,
603628
resultSetType, resultSetConcurrency, resultSetHoldability);

clickhouse-jdbc/src/main/java/com/clickhouse/jdbc/internal/InputBasedPreparedStatement.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -137,13 +137,9 @@ protected long[] executeAny(boolean asBatch) throws SQLException {
137137
return results;
138138
}
139139

140-
protected int toArrayIndex(int parameterIndex) throws SQLException {
141-
if (parameterIndex < 1 || parameterIndex > values.length) {
142-
throw SqlExceptionUtils.clientError(ClickHouseUtils
143-
.format("Parameter index must between 1 and %d but we got %d", values.length, parameterIndex));
144-
}
145-
146-
return parameterIndex - 1;
140+
@Override
141+
protected int getMaxParameterIndex() {
142+
return values.length;
147143
}
148144

149145
@Override

clickhouse-jdbc/src/main/java/com/clickhouse/jdbc/internal/SqlBasedPreparedStatement.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -209,13 +209,9 @@ protected long[] executeAny(boolean asBatch) throws SQLException {
209209
return results;
210210
}
211211

212-
protected int toArrayIndex(int parameterIndex) throws SQLException {
213-
if (parameterIndex < 1 || parameterIndex > templates.length) {
214-
throw SqlExceptionUtils.clientError(ClickHouseUtils
215-
.format("Parameter index must between 1 and %d but we got %d", templates.length, parameterIndex));
216-
}
217-
218-
return parameterIndex - 1;
212+
@Override
213+
protected int getMaxParameterIndex() {
214+
return templates.length;
219215
}
220216

221217
@Override

clickhouse-jdbc/src/main/java/com/clickhouse/jdbc/internal/TableBasedPreparedStatement.java

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -113,21 +113,17 @@ public long[] executeAny(boolean asBatch) throws SQLException {
113113
return results;
114114
}
115115

116+
@Override
117+
protected int getMaxParameterIndex() {
118+
return values.length;
119+
}
120+
116121
protected String getSql() {
117122
// why? because request can be modified so it might not always same as
118123
// parsedStmt.getSQL()
119124
return getRequest().getStatements(false).get(0);
120125
}
121126

122-
protected int toArrayIndex(int parameterIndex) throws SQLException {
123-
if (parameterIndex < 1 || parameterIndex > values.length) {
124-
throw SqlExceptionUtils.clientError(ClickHouseUtils
125-
.format("Parameter index must between 1 and %d but we got %d", values.length, parameterIndex));
126-
}
127-
128-
return parameterIndex - 1;
129-
}
130-
131127
@Override
132128
public ResultSet executeQuery() throws SQLException {
133129
ensureParams();

0 commit comments

Comments
 (0)