Skip to content

Commit b567aa9

Browse files
committed
improved queryAll() to use less mem
1 parent fc8d92e commit b567aa9

File tree

7 files changed

+56
-8
lines changed

7 files changed

+56
-8
lines changed

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
import java.util.Collections;
6868
import java.util.HashMap;
6969
import java.util.HashSet;
70+
import java.util.LinkedHashMap;
7071
import java.util.List;
7172
import java.util.Map;
7273
import java.util.Set;
@@ -1404,10 +1405,11 @@ public List<GenericRecord> queryAll(String sqlQuery) {
14041405
query(sqlQuery, settings).get(operationTimeout, TimeUnit.MILLISECONDS)) {
14051406
List<GenericRecord> records = new ArrayList<>();
14061407
if (response.getResultRows() > 0) {
1407-
ClickHouseBinaryFormatReader reader =
1408+
RowBinaryWithNamesAndTypesFormatReader reader =
14081409
new RowBinaryWithNamesAndTypesFormatReader(response.getInputStream(), response.getSettings());
1410+
14091411
Map<String, Object> record;
1410-
while ((record = reader.next()) != null) {
1412+
while (reader.readRecord((record = new LinkedHashMap<>()))) {
14111413
records.add(new MapBackedRecord(record, reader.getSchema()));
14121414
}
14131415
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public NativeFormatReader(InputStream inputStream, QuerySettings settings) {
3333
}
3434

3535
@Override
36-
protected boolean readRecord(Map<String, Object> record) throws IOException {
36+
public boolean readRecord(Map<String, Object> record) throws IOException {
3737
if (currentBlock == null || blockRowIndex >= currentBlock.getnRows()) {
3838
if (!readBlock()) {
3939
return false;

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import java.time.ZoneOffset;
3131
import java.time.ZonedDateTime;
3232
import java.time.temporal.ChronoUnit;
33+
import java.util.ArrayList;
3334
import java.util.Collections;
3435
import java.util.HashMap;
3536
import java.util.List;
@@ -38,6 +39,7 @@
3839
import java.util.TimeZone;
3940
import java.util.UUID;
4041
import java.util.concurrent.ConcurrentHashMap;
42+
import java.util.function.Function;
4143

4244
public abstract class AbstractBinaryFormatReader implements ClickHouseBinaryFormatReader {
4345

@@ -70,7 +72,18 @@ protected AbstractBinaryFormatReader(InputStream inputStream, QuerySettings quer
7072
protected Map<String, Object> nextRecord = new ConcurrentHashMap<>();
7173

7274

73-
protected boolean readRecord(Map<String, Object> record) throws IOException {
75+
/**
76+
* It is still internal method and should be used with care.
77+
* Usually this method is called to read next record into internal object and affects hasNext() method.
78+
* So after calling this one:
79+
* - hasNext(), next() should not be called
80+
* - stream should be read with readRecord() method fully
81+
*
82+
* @param record
83+
* @return
84+
* @throws IOException
85+
*/
86+
public boolean readRecord(Map<String, Object> record) throws IOException {
7487
boolean firstColumn = true;
7588
for (ClickHouseColumn column : getSchema().getColumns()) {
7689
try {

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,4 +346,14 @@ public LocalDateTime getLocalDateTime(String colName) {
346346
public LocalDateTime getLocalDateTime(int index) {
347347
return reader.getLocalDateTime(index);
348348
}
349+
350+
@Override
351+
public Object getObject(String colName) {
352+
return reader.readValue(colName);
353+
}
354+
355+
@Override
356+
public Object getObject(int index) {
357+
return reader.readValue(index);
358+
}
349359
}

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,4 +480,14 @@ public LocalDateTime getLocalDateTime(String colName) {
480480
public LocalDateTime getLocalDateTime(int index) {
481481
return readValue(index);
482482
}
483+
484+
@Override
485+
public Object getObject(String colName) {
486+
return readValue(colName);
487+
}
488+
489+
@Override
490+
public Object getObject(int index) {
491+
return readValue(index);
492+
}
483493
}

client-v2/src/main/java/com/clickhouse/client/api/query/GenericRecord.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
public interface GenericRecord {
2121

22-
2322
/**
2423
* Reads column with name `colName` as a string.
2524
*
@@ -486,4 +485,8 @@ public interface GenericRecord {
486485
LocalDateTime getLocalDateTime(String colName);
487486

488487
LocalDateTime getLocalDateTime(int index);
488+
489+
Object getObject(String colName);
490+
491+
Object getObject(int index);
489492
}

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

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,9 +180,19 @@ public void testReadRecordsNoResult() throws Exception {
180180

181181
@Test(groups = {"integration"})
182182
public void testQueryAll() throws Exception {
183-
prepareDataSet(DATASET_TABLE, DATASET_COLUMNS, DATASET_VALUE_GENERATORS, 10);
184-
GenericRecord hostnameRecord = client.queryAll("SELECT hostname()").stream().findFirst().get();
185-
Assert.assertNotNull(hostnameRecord);
183+
List<Map<String, Object>> dataset = prepareDataSet(DATASET_TABLE, DATASET_COLUMNS, DATASET_VALUE_GENERATORS, 10);
184+
List<GenericRecord> records = client.queryAll("SELECT * FROM " + DATASET_TABLE + " LIMIT " + dataset.size());
185+
Assert.assertFalse(records.isEmpty());
186+
187+
int i = 0;
188+
for (String colDefinition : DATASET_COLUMNS) {
189+
190+
String colName = colDefinition.split(" ")[0];
191+
List<Object> colValues = records.stream().map(r -> r.getObject(colName)).toList();
192+
Assert.assertEquals(colValues.size(), dataset.size());
193+
List<Object> dataValue = dataset.stream().map(d -> d.get(colName)).toList();
194+
Assert.assertEquals(colValues, dataValue, "Failed for column " + colName);
195+
}
186196
}
187197

188198
@Test(groups = {"integration"})

0 commit comments

Comments
 (0)