Skip to content

Commit 4acc1b3

Browse files
authored
Merge pull request #774 from zhicwu/enhance-jdbc
Treat Nothing as NULL
2 parents 754cb32 + 54cd54c commit 4acc1b3

File tree

3 files changed

+112
-21
lines changed

3 files changed

+112
-21
lines changed

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

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.math.BigInteger;
55

66
import com.clickhouse.client.ClickHouseValue;
7+
import com.clickhouse.client.ClickHouseValues;
78

89
/**
910
* Wrapper class of Nothing.
@@ -26,27 +27,27 @@ public BigInteger asBigInteger() {
2627

2728
@Override
2829
public byte asByte() {
29-
throw new IllegalStateException("Empty value cannot be converted to byte");
30+
return (byte) 0;
3031
}
3132

3233
@Override
3334
public double asDouble() {
34-
throw new IllegalStateException("Empty value cannot be converted to double");
35+
return 0D;
3536
}
3637

3738
@Override
3839
public float asFloat() {
39-
throw new IllegalStateException("Empty value cannot be converted to float");
40+
return 0F;
4041
}
4142

4243
@Override
4344
public int asInteger() {
44-
throw new IllegalStateException("Empty value cannot be converted to int");
45+
return 0;
4546
}
4647

4748
@Override
4849
public long asLong() {
49-
throw new IllegalStateException("Empty value cannot be converted to long");
50+
return 0L;
5051
}
5152

5253
@Override
@@ -56,7 +57,7 @@ public Object asObject() {
5657

5758
@Override
5859
public short asShort() {
59-
throw new IllegalStateException("Empty value cannot be converted to short");
60+
return (short) 0;
6061
}
6162

6263
@Override
@@ -76,7 +77,7 @@ public ClickHouseValue resetToNullOrEmpty() {
7677

7778
@Override
7879
public String toSqlExpression() {
79-
return toString();
80+
return ClickHouseValues.NULL_EXPR;
8081
}
8182

8283
@Override

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

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public static ClickHouseResponse of(ClickHouseConfig config, ClickHouseInputStre
6060
protected final List<ClickHouseColumn> columns;
6161
protected final ClickHouseResponseSummary summary;
6262

63-
private boolean isClosed;
63+
private boolean closed;
6464

6565
protected ClickHouseStreamResponse(ClickHouseConfig config, ClickHouseInputStream input,
6666
Map<String, Object> settings, List<ClickHouseColumn> columns, ClickHouseResponseSummary summary)
@@ -91,30 +91,28 @@ protected ClickHouseStreamResponse(ClickHouseConfig config, ClickHouseInputStrea
9191
}
9292
}
9393
this.summary = summary != null ? summary : ClickHouseResponseSummary.EMPTY;
94-
this.isClosed = hasError;
94+
this.closed = hasError;
9595
}
9696

9797
@Override
9898
public boolean isClosed() {
99-
return isClosed;
99+
return closed;
100100
}
101101

102102
@Override
103103
public void close() {
104-
if (input != null) {
104+
try {
105+
log.debug("%d bytes skipped before closing input stream", input.skip(Long.MAX_VALUE));
106+
} catch (Exception e) {
107+
// ignore
108+
log.debug("Failed to skip reading input stream due to: %s", e.getMessage());
109+
} finally {
105110
try {
106-
log.debug("%d bytes skipped before closing input stream", input.skip(Long.MAX_VALUE));
111+
input.close();
107112
} catch (Exception e) {
108-
// ignore
109-
log.debug("Failed to skip reading input stream due to: %s", e.getMessage());
110-
} finally {
111-
try {
112-
input.close();
113-
} catch (Exception e) {
114-
log.warn("Failed to close input stream", e);
115-
}
116-
isClosed = true;
113+
log.warn("Failed to close input stream", e);
117114
}
115+
closed = true;
118116
}
119117
}
120118

clickhouse-client/src/test/java/com/clickhouse/client/data/ClickhouseLZ4InputStreamTest.java

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,104 @@
11
package com.clickhouse.client.data;
22

33
import org.testng.Assert;
4+
import org.testng.annotations.DataProvider;
45
import org.testng.annotations.Test;
56
import java.io.ByteArrayInputStream;
67
import java.io.ByteArrayOutputStream;
8+
import java.io.EOFException;
79
import java.io.IOException;
10+
import java.io.InputStream;
11+
import java.nio.charset.StandardCharsets;
812

913
public class ClickhouseLZ4InputStreamTest {
14+
private InputStream generateInputStream(String prefix, int samples, StringBuilder builder) throws IOException {
15+
builder.setLength(0);
16+
17+
byte[] result = null;
18+
try (ByteArrayOutputStream out = new ByteArrayOutputStream();
19+
ClickHouseLZ4OutputStream lz4Out = new ClickHouseLZ4OutputStream(out, 1024 * 1024)) {
20+
for (int i = 0; i < samples; i++) {
21+
String s = prefix + i;
22+
lz4Out.write(s.getBytes(StandardCharsets.UTF_8));
23+
builder.append(s);
24+
}
25+
lz4Out.flush();
26+
result = out.toByteArray();
27+
// Assert.assertTrue(result.length < builder.length() / 2);
28+
}
29+
30+
return new ByteArrayInputStream(result);
31+
}
32+
33+
@DataProvider(name = "prefixes")
34+
private Object[][] getPrefixes() {
35+
return new Object[][] { { "test" }, { "萌萌哒" },
36+
{ "1😂2萌🥘" } };
37+
};
38+
39+
@Test(dataProvider = "prefixes", groups = { "unit" })
40+
public void testReadByte(String prefix) throws IOException {
41+
StringBuilder builder = new StringBuilder();
42+
boolean readAll = false;
43+
try (InputStream in = generateInputStream(prefix, 10000, builder);
44+
ClickHouseLZ4InputStream lz4In = new ClickHouseLZ4InputStream(in);
45+
ByteArrayOutputStream out = new ByteArrayOutputStream();) {
46+
try {
47+
while (true) {
48+
out.write(0xFF & lz4In.readByte());
49+
}
50+
} catch (EOFException e) {
51+
readAll = true;
52+
}
53+
54+
out.flush();
55+
56+
Assert.assertEquals(new String(out.toByteArray(), StandardCharsets.UTF_8), builder.toString());
57+
}
58+
Assert.assertTrue(readAll, "All bytes should have read without any issue");
59+
}
60+
61+
@Test(dataProvider = "prefixes", groups = { "unit" })
62+
public void testRead(String prefix) throws IOException {
63+
StringBuilder builder = new StringBuilder();
64+
boolean readAll = false;
65+
try (InputStream in = generateInputStream(prefix, 10000, builder);
66+
ClickHouseLZ4InputStream lz4In = new ClickHouseLZ4InputStream(in);
67+
ByteArrayOutputStream out = new ByteArrayOutputStream();) {
68+
int result = 0;
69+
while ((result = lz4In.read()) != -1) {
70+
out.write(result);
71+
}
72+
out.flush();
73+
readAll = true;
74+
75+
Assert.assertEquals(new String(out.toByteArray(), StandardCharsets.UTF_8), builder.toString());
76+
}
77+
Assert.assertTrue(readAll, "All bytes should have read without any issue");
78+
}
79+
80+
@Test(dataProvider = "prefixes", groups = { "unit" })
81+
public void testReadBytes(String prefix) throws IOException {
82+
StringBuilder builder = new StringBuilder();
83+
boolean readAll = false;
84+
for (int i = 1; i < 1025; i++) {
85+
byte[] bytes = new byte[i];
86+
try (InputStream in = generateInputStream(prefix, 10000, builder);
87+
ClickHouseLZ4InputStream lz4In = new ClickHouseLZ4InputStream(in);
88+
ByteArrayOutputStream out = new ByteArrayOutputStream();) {
89+
int result = 0;
90+
while ((result = lz4In.read(bytes)) != -1) {
91+
out.write(bytes, 0, result);
92+
}
93+
out.flush();
94+
readAll = true;
95+
96+
Assert.assertEquals(new String(out.toByteArray(), StandardCharsets.UTF_8), builder.toString());
97+
}
98+
Assert.assertTrue(readAll, "All bytes should have read without any issue");
99+
}
100+
}
101+
10102
@Test(groups = { "unit" })
11103
public void testLZ4Stream() throws IOException {
12104
StringBuilder sb = new StringBuilder();

0 commit comments

Comments
 (0)