Skip to content

Commit b16f9c0

Browse files
committed
Merge branch 'main' into jdbc_v2_row_binary_writer
2 parents 7435503 + a245c1f commit b16f9c0

File tree

26 files changed

+273
-50
lines changed

26 files changed

+273
-50
lines changed

CHANGELOG.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,24 @@
1+
## 0.8.4
2+
3+
### Examples
4+
- [jdbc-v2] - JPA example added. (https://github.com/ClickHouse/clickhouse-java/pull/2301)
5+
6+
### Bug Fixes
7+
- [jdbc-v2] Added implementation of `ResultSetMetaData.getColumnClassName()` to return information
8+
about class name of the value stored in a result. (https://github.com/ClickHouse/clickhouse-java/issues/2112)
9+
- [client-v2] Fixed NPE when `Client.queryAll` used with `INSERT` statement because internally `columns` variable
10+
was accessed and was null. (https://github.com/ClickHouse/clickhouse-java/issues/2150)
11+
- [jdbc-v2] Fixed NPE when `ssl=true` was passed via an connection URL. (https://github.com/ClickHouse/clickhouse-java/issues/2206)
12+
- [jdbc-v2] Fixed sending correct driver version. Problem occurs because context classloader had no access to
13+
a resource file with versions. (https://github.com/ClickHouse/clickhouse-java/issues/2245)
14+
- [jdbc-v2] Fixed incorrect flag for Array values when reading result set. (https://github.com/ClickHouse/clickhouse-java/issues/2266)
15+
- [jdbc-v2] Fixed parsing parameters in PreparedStatement for cases when '?' is within quotes or similar. (https://github.com/ClickHouse/clickhouse-java/issues/2290)
16+
- [jdbc-v2] Added implementation for `com.clickhouse.jdbc.PreparedStatementImpl#getMetaData`.
17+
Complete metadata is returned only after statement execution. Partial metadata is returned before execution
18+
of the statement. (https://github.com/ClickHouse/clickhouse-java/issues/2292)
19+
- [jdbc-v2] Fixed `clearParameters` in `PreparedStatementImpl` to correctly reset parameters array. (https://github.com/ClickHouse/clickhouse-java/issues/2299)
20+
- [jdbc-v2] Fixed logging. (https://github.com/ClickHouse/clickhouse-java/pull/2303)
21+
122
## 0.8.3
223

324
### Improvements

clickhouse-data/src/main/java/com/clickhouse/data/ClickHouseColumn.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,21 @@ public final class ClickHouseColumn implements Serializable {
106106
private Map<Class<?>, Integer> mapKeyToVariantOrdNumMap;
107107
private Map<Class<?>, Integer> mapValueToVariantOrdNumMap;
108108

109+
public enum DefaultValue {
110+
DEFAULT("Default"),
111+
MATERIALIZED("MATERIALIZED"),
112+
EPHEMERAL("EPHEMERAL"),
113+
ALIAS("ALIAS");
114+
115+
public final String defaultValue;
116+
117+
DefaultValue(String defaultValue) {
118+
this.defaultValue = defaultValue;
119+
}
120+
}
121+
122+
private DefaultValue defaultValue;
123+
private String defaultExpression;
109124

110125
private static ClickHouseColumn update(ClickHouseColumn column) {
111126
column.enumConstants = ClickHouseEnum.EMPTY;
@@ -853,6 +868,14 @@ public void setHasDefault(boolean hasDefault) {
853868
this.hasDefault = hasDefault;
854869
}
855870

871+
public void setDefaultValue(DefaultValue defaultValue) { this.defaultValue = defaultValue; }
872+
873+
public DefaultValue getDefaultValue() { return defaultValue; }
874+
875+
public void setDefaultExpression(String defaultExpression) { this.defaultExpression = defaultExpression; }
876+
877+
public String getDefaultExpression() { return defaultExpression; }
878+
856879
public boolean isLowCardinality() {
857880
return !lowCardinalityDisabled && lowCardinality;
858881
}

client-v2/src/main/java/com/clickhouse/client/api/Client.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,6 +1340,9 @@ public CompletableFuture<InsertResponse> insert(String tableName, List<?> data,
13401340
.getOrDefault(tableName, Collections.emptyMap());
13411341
List<POJOSerializer> serializersForTable = new ArrayList<>();
13421342
for (ClickHouseColumn column : tableSchema.getColumns()) {
1343+
if (column.hasDefault() && column.getDefaultValue() != ClickHouseColumn.DefaultValue.DEFAULT ) {
1344+
continue;
1345+
}
13431346
POJOSerializer serializer = classSerializers.get(column.getColumnName());
13441347
if (serializer == null) {
13451348
throw new IllegalArgumentException("No serializer found for column '" + column.getColumnName() + "'. Did you forget to register it?");

client-v2/src/main/java/com/clickhouse/client/api/data_formats/RowBinaryFormatWriter.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,9 @@ public void commitRow() throws IOException {
8282
List<ClickHouseColumn> columnList = tableSchema.getColumns();
8383
for (int i = 0; i < row.length; i++) {
8484
ClickHouseColumn column = columnList.get(i);
85-
85+
// here we skip if we have a default value that is MATERIALIZED or ALIAS or ...
86+
if (column.hasDefault() && column.getDefaultValue() != ClickHouseColumn.DefaultValue.DEFAULT)
87+
continue;
8688
if (RowBinaryFormatSerializer.writeValuePreamble(out, defaultSupport, column, row[i])) {
8789
SerializerUtils.serializeData(out, row[i], column);
8890
}

client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/AbstractBinaryFormatReader.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ protected AbstractBinaryFormatReader(InputStream inputStream, QuerySettings quer
9999
* @throws IOException
100100
*/
101101
public boolean readToPOJO(Map<String, POJOSetter> deserializers, Object obj ) throws IOException {
102+
if (columns == null || columns.length == 0) {
103+
return false;
104+
}
105+
102106
boolean firstColumn = true;
103107

104108
for (ClickHouseColumn column : columns) {
@@ -135,6 +139,10 @@ public boolean readToPOJO(Map<String, POJOSetter> deserializers, Object obj ) th
135139
* @throws IOException
136140
*/
137141
public boolean readRecord(Map<String, Object> record) throws IOException {
142+
if (columns == null || columns.length == 0) {
143+
return false;
144+
}
145+
138146
boolean firstColumn = true;
139147
for (ClickHouseColumn column : columns) {
140148
try {
@@ -157,6 +165,10 @@ public boolean readRecord(Map<String, Object> record) throws IOException {
157165
}
158166

159167
protected boolean readRecord(Object[] record) throws IOException {
168+
if (columns == null || columns.length == 0) {
169+
return false;
170+
}
171+
160172
boolean firstColumn = true;
161173
for (int i = 0; i < columns.length; i++) {
162174
try {

client-v2/src/main/java/com/clickhouse/client/api/internal/TableSchemaParser.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,13 @@ public static TableSchema readTSKV(InputStream content, String table, String sql
2525
p.load(new StringReader(line.replaceAll("\t", "\n")));
2626
ClickHouseColumn column = ClickHouseColumn.of(p.getProperty("name"), p.getProperty("type"));
2727
String defaultType = p.getProperty("default_type");
28+
String defaultExpression = p.getProperty("default_expression");
2829
column.setHasDefault(defaultType != null && !defaultType.isEmpty());
30+
if ( column.hasDefault() ) {
31+
column.setDefaultValue(ClickHouseColumn.DefaultValue.valueOf(defaultType));
32+
if ( defaultExpression != null && !defaultExpression.isEmpty() )
33+
column.setDefaultExpression(defaultExpression);
34+
}
2935
columns.add(column);
3036
}
3137
}

client-v2/src/test/java/com/clickhouse/client/insert/InsertTests.java

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,54 @@ public void testAdvancedWriter() throws Exception {
554554
}
555555
}
556556

557+
@Test
558+
public void testWriterWithMaterialize() throws Exception {
559+
String tableName = "table_name_with_materialize";
560+
String tableCreate = "CREATE TABLE \"" + tableName + "\" " +
561+
" (name String, " +
562+
" v1 Float32, " +
563+
" v2 Float32, " +
564+
" attrs Nullable(String), " +
565+
" corrected_time DateTime('UTC') DEFAULT now()," +
566+
" special_attr Nullable(Int8) DEFAULT -1," +
567+
" name_lower String MATERIALIZED lower(name)," +
568+
" name_lower_alias String ALIAS lower(name)," +
569+
" unhexed String EPHEMERAL," +
570+
" hexed FixedString(4) DEFAULT unhex(unhexed)" +
571+
" ) Engine = MergeTree ORDER by (name)";
572+
573+
initTable(tableName, tableCreate);
574+
575+
ZonedDateTime correctedTime = Instant.now().atZone(ZoneId.of("UTC"));
576+
Object[][] rows = new Object[][] {
577+
{"foo1", 0.3f, 0.6f, "a=1,b=2,c=5", correctedTime, 10, "Z��"},
578+
{"foo2", 0.6f, 0.1f, "a=1,b=2,c=5", correctedTime, null, "Z��"},
579+
{"foo3", 0.7f, 0.4f, "a=1,b=2,c=5", null, null, "Z��"},
580+
{"foo4", 0.8f, 0.5f, null, null, null, "Z��"},
581+
};
582+
583+
TableSchema schema = client.getTableSchema(tableName);
584+
585+
ClickHouseFormat format = ClickHouseFormat.RowBinaryWithDefaults;
586+
try (InsertResponse response = client.insert(tableName, out -> {
587+
RowBinaryFormatWriter w = new RowBinaryFormatWriter(out, schema, format);
588+
for (Object[] row : rows) {
589+
for (int i = 0; i < row.length; i++) {
590+
w.setValue(i + 1, row[i]);
591+
}
592+
w.commitRow();
593+
}
594+
}, format, new InsertSettings()).get()) {
595+
System.out.println("Rows written: " + response.getWrittenRows());
596+
}
597+
598+
List<GenericRecord> records = client.queryAll("SELECT * FROM \"" + tableName + "\"" );
599+
600+
for (GenericRecord record : records) {
601+
System.out.println("> " + record.getString(1) + ", " + record.getFloat(2) + ", " + record.getFloat(3));
602+
}
603+
}
604+
557605
@Test
558606
public void testCollectionInsert() throws Exception {
559607
String tableName = "very_long_table_name_with_uuid_" + UUID.randomUUID().toString().replace('-', '_');
@@ -705,6 +753,33 @@ public void testPOJOWithDynamicType() throws Exception {
705753
}
706754
}
707755

756+
@Test(groups = { "integration" }, enabled = true)
757+
public void insertSimplePOJOsWithMaterializeColumn() throws Exception {
758+
String tableName = "simple_pojo_table_with_materialize_column";
759+
String createSQL = SimplePOJO.generateTableCreateSQL(tableName);
760+
String uuid = UUID.randomUUID().toString();
761+
762+
initTable(tableName, createSQL);
763+
764+
client.register(SimplePOJO.class, client.getTableSchema(tableName));
765+
List<Object> simplePOJOs = new ArrayList<>();
766+
767+
for (int i = 0; i < 1000; i++) {
768+
simplePOJOs.add(new SimplePOJO());
769+
}
770+
settings.setQueryId(uuid);
771+
InsertResponse response = client.insert(tableName, simplePOJOs, settings).get(EXECUTE_CMD_TIMEOUT, TimeUnit.SECONDS);
772+
773+
OperationMetrics metrics = response.getMetrics();
774+
assertEquals(simplePOJOs.size(), metrics.getMetric(ServerMetrics.NUM_ROWS_WRITTEN).getLong());
775+
assertEquals(simplePOJOs.size(), response.getWrittenRows());
776+
assertTrue(metrics.getMetric(ClientMetrics.OP_DURATION).getLong() > 0);
777+
assertTrue(metrics.getMetric(ClientMetrics.OP_SERIALIZATION).getLong() > 0);
778+
assertEquals(metrics.getQueryId(), uuid);
779+
assertEquals(response.getQueryId(), uuid);
780+
}
781+
782+
708783
protected void initTable(String tableName, String createTableSQL) throws Exception {
709784
initTable(tableName, createTableSQL, new CommandSettings());
710785
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.clickhouse.client.insert;
2+
3+
import com.clickhouse.client.ClientTests;
4+
import lombok.Getter;
5+
import lombok.Setter;
6+
import org.apache.commons.lang3.RandomStringUtils;
7+
import org.slf4j.Logger;
8+
import org.slf4j.LoggerFactory;
9+
10+
import java.util.Random;
11+
12+
@Getter
13+
@Setter
14+
public class SimplePOJO {
15+
16+
private static final Logger LOGGER = LoggerFactory.getLogger(SimplePOJO.class);
17+
private int int32;
18+
private String str;
19+
private String hexed;
20+
21+
public SimplePOJO() {
22+
long seed = System.currentTimeMillis();
23+
final Random random = new Random(seed);
24+
this.int32 = random.nextInt();
25+
this.str = RandomStringUtils.randomAlphabetic(1, 256);
26+
this.hexed = RandomStringUtils.randomAlphanumeric(4);
27+
}
28+
29+
public static String generateTableCreateSQL(String tableName) {
30+
return "CREATE TABLE " + tableName + " (" +
31+
"int32 Int32, " +
32+
"str String, " +
33+
"int64 Int64 MATERIALIZED abs(toInt64(int32)), " +
34+
"str_lower String ALIAS lower(str), " +
35+
"unhexed String EPHEMERAL, " +
36+
"hexed FixedString(4) DEFAULT unhex(unhexed), " +
37+
") ENGINE = MergeTree ORDER BY ()";
38+
}
39+
40+
}
41+

client-v2/src/test/java/com/clickhouse/client/query/QueryTests.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,14 @@ public void testQueryAllTableNames() {
344344
Assert.assertTrue(tableNames.containsAll(expectedTableNames));
345345
}
346346

347+
@Test(groups = {"integration"})
348+
public void testQueryAllInsertSelect() {
349+
client.queryAll("CREATE TABLE IF NOT EXISTS nums (number Int16) ENGINE = MergeTree() ORDER BY number;");
350+
String sql = "INSERT INTO nums SELECT * FROM system.numbers LIMIT 100";
351+
List<GenericRecord> records = client.queryAll(sql);
352+
Assert.assertTrue(records.isEmpty());
353+
}
354+
347355
@Test(groups = {"integration"})
348356
public void testQueryJSONEachRow() throws ExecutionException, InterruptedException {
349357
Map<String, Object> datasetRecord = prepareSimpleDataSet();

examples/client-v2/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
5555
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
5656

57-
<clickhouse-java.version>0.8.3-SNAPSHOT</clickhouse-java.version>
57+
<clickhouse-java.version>0.8.4-SNAPSHOT</clickhouse-java.version>
5858

5959
<compiler-plugin.version>3.8.1</compiler-plugin.version>
6060

0 commit comments

Comments
 (0)