|
6 | 6 | import com.clickhouse.client.ClickHouseServerForTest; |
7 | 7 | import com.clickhouse.client.api.Client; |
8 | 8 | import com.clickhouse.client.api.ClientException; |
9 | | -import com.clickhouse.client.api.DataTypeUtils; |
10 | 9 | import com.clickhouse.client.api.command.CommandSettings; |
11 | 10 | import com.clickhouse.client.api.data_formats.ClickHouseBinaryFormatReader; |
12 | 11 | import com.clickhouse.client.api.data_formats.internal.BinaryStreamReader; |
13 | | -import com.clickhouse.client.api.data_formats.internal.SerializerUtils; |
14 | 12 | import com.clickhouse.client.api.enums.Protocol; |
15 | 13 | import com.clickhouse.client.api.insert.InsertSettings; |
16 | 14 | import com.clickhouse.client.api.metadata.TableSchema; |
|
34 | 32 | import java.lang.reflect.Method; |
35 | 33 | import java.math.BigDecimal; |
36 | 34 | import java.math.RoundingMode; |
37 | | -import java.sql.Connection; |
38 | 35 | import java.time.Instant; |
39 | 36 | import java.time.LocalDate; |
40 | 37 | import java.time.LocalDateTime; |
41 | | -import java.time.LocalTime; |
42 | 38 | import java.time.Period; |
43 | 39 | import java.time.ZoneId; |
44 | 40 | import java.time.ZoneOffset; |
45 | | -import java.time.ZonedDateTime; |
46 | | -import java.time.temporal.ChronoField; |
47 | 41 | import java.time.temporal.ChronoUnit; |
48 | | -import java.time.temporal.TemporalAccessor; |
49 | | -import java.time.temporal.TemporalField; |
50 | 42 | import java.util.ArrayList; |
51 | 43 | import java.util.Arrays; |
52 | 44 | import java.util.Collections; |
@@ -1145,6 +1137,147 @@ public void testDates() throws Exception { |
1145 | 1137 | } |
1146 | 1138 | } |
1147 | 1139 |
|
| 1140 | + @Test(groups = {"integration"}, dataProvider = "testNestedArrays_dp") |
| 1141 | + public void testNestedArrays(String columnDef, String insertValues, String[] expectedStrValues, |
| 1142 | + String[] expectedListValues) throws Exception { |
| 1143 | + final String table = "test_nested_arrays"; |
| 1144 | + client.execute("DROP TABLE IF EXISTS " + table).get(); |
| 1145 | + client.execute(tableDefinition(table, "rowId Int32", columnDef)).get(); |
| 1146 | + |
| 1147 | + client.execute("INSERT INTO " + table + " VALUES " + insertValues).get().close(); |
| 1148 | + |
| 1149 | + List<GenericRecord> records = client.queryAll("SELECT * FROM " + table + " ORDER BY rowId"); |
| 1150 | + Assert.assertEquals(records.size(), expectedStrValues.length); |
| 1151 | + |
| 1152 | + for (GenericRecord record : records) { |
| 1153 | + int rowId = record.getInteger("rowId"); |
| 1154 | + |
| 1155 | + // Check getString() - includes quotes for string values |
| 1156 | + String actualValue = record.getString("arr"); |
| 1157 | + Assert.assertEquals(actualValue, expectedStrValues[rowId - 1], |
| 1158 | + "getString() mismatch at row " + rowId + " for " + columnDef); |
| 1159 | + |
| 1160 | + // Check getObject() - should return an ArrayValue |
| 1161 | + Object objValue = record.getObject("arr"); |
| 1162 | + Assert.assertNotNull(objValue, "getObject() returned null at row " + rowId); |
| 1163 | + Assert.assertTrue(objValue instanceof BinaryStreamReader.ArrayValue, |
| 1164 | + "getObject() should return ArrayValue at row " + rowId + ", got: " + objValue.getClass().getName()); |
| 1165 | + BinaryStreamReader.ArrayValue arrayValue = (BinaryStreamReader.ArrayValue) objValue; |
| 1166 | + Assert.assertEquals(arrayValue.asList().toString(), expectedListValues[rowId - 1], |
| 1167 | + "getObject().asList() mismatch at row " + rowId + " for " + columnDef); |
| 1168 | + |
| 1169 | + // Check getList() - should return a List representation (no quotes for strings) |
| 1170 | + List<?> listValue = record.getList("arr"); |
| 1171 | + Assert.assertNotNull(listValue, "getList() returned null at row " + rowId); |
| 1172 | + Assert.assertEquals(listValue.toString(), expectedListValues[rowId - 1], |
| 1173 | + "getList() mismatch at row " + rowId + " for " + columnDef); |
| 1174 | + } |
| 1175 | + } |
| 1176 | + |
| 1177 | + @DataProvider |
| 1178 | + public Object[][] testNestedArrays_dp() { |
| 1179 | + return new Object[][] { |
| 1180 | + // 2D arrays of integers - Array(Array(Int32)) |
| 1181 | + { |
| 1182 | + "arr Array(Array(Int32))", |
| 1183 | + "(1, [[1, 2], [3, 4]]), (2, [[5, 6, 7]]), (3, [[]]), (4, [[8], [], [9, 10]]), " + |
| 1184 | + "(5, [[11]]), (6, [[12, 13], [14, 15]]), (7, [[100, 200]]), (8, [[16]]), (9, [[17, 18]]), (10, [[19, 20, 21]])", |
| 1185 | + new String[] { |
| 1186 | + "[[1, 2], [3, 4]]", "[[5, 6, 7]]", "[[]]", "[[8], [], [9, 10]]", |
| 1187 | + "[[11]]", "[[12, 13], [14, 15]]", "[[100, 200]]", "[[16]]", "[[17, 18]]", "[[19, 20, 21]]" |
| 1188 | + }, |
| 1189 | + new String[] { |
| 1190 | + "[[1, 2], [3, 4]]", "[[5, 6, 7]]", "[[]]", "[[8], [], [9, 10]]", |
| 1191 | + "[[11]]", "[[12, 13], [14, 15]]", "[[100, 200]]", "[[16]]", "[[17, 18]]", "[[19, 20, 21]]" |
| 1192 | + } |
| 1193 | + }, |
| 1194 | + // 2D arrays of strings - Array(Array(String)) |
| 1195 | + { |
| 1196 | + "arr Array(Array(String))", |
| 1197 | + "(1, [['a', 'b'], ['c', 'd']]), (2, [['hello', 'world']]), (3, [[]]), (4, [['x'], [], ['y', 'z']]), " + |
| 1198 | + "(5, [['test']]), (6, [['foo', 'bar']]), (7, [['single']]), (8, [['alpha', 'beta']]), (9, [['one']]), (10, [['end']])", |
| 1199 | + new String[] { // getString() format - with quotes |
| 1200 | + "[['a', 'b'], ['c', 'd']]", "[['hello', 'world']]", "[[]]", "[['x'], [], ['y', 'z']]", |
| 1201 | + "[['test']]", "[['foo', 'bar']]", "[['single']]", "[['alpha', 'beta']]", "[['one']]", "[['end']]" |
| 1202 | + }, |
| 1203 | + new String[] { // getList() format - no quotes |
| 1204 | + "[[a, b], [c, d]]", "[[hello, world]]", "[[]]", "[[x], [], [y, z]]", |
| 1205 | + "[[test]]", "[[foo, bar]]", "[[single]]", "[[alpha, beta]]", "[[one]]", "[[end]]" |
| 1206 | + } |
| 1207 | + }, |
| 1208 | + // 3D arrays of integers - Array(Array(Array(Int32))) |
| 1209 | + { |
| 1210 | + "arr Array(Array(Array(Int32)))", |
| 1211 | + "(1, [[[1, 2], [3]]]), (2, [[[4], [5, 6]], [[7]]]), (3, [[[]]]), (4, [[[8, 9]]]), " + |
| 1212 | + "(5, [[[10], [11, 12]]]), (6, [[[13]]]), (7, [[[14, 15], [16]]]), (8, [[[17]]]), (9, [[[18, 19]]]), (10, [[[]]])", |
| 1213 | + new String[] { |
| 1214 | + "[[[1, 2], [3]]]", "[[[4], [5, 6]], [[7]]]", "[[[]]]", "[[[8, 9]]]", |
| 1215 | + "[[[10], [11, 12]]]", "[[[13]]]", "[[[14, 15], [16]]]", "[[[17]]]", "[[[18, 19]]]", "[[[]]]" |
| 1216 | + }, |
| 1217 | + new String[] { |
| 1218 | + "[[[1, 2], [3]]]", "[[[4], [5, 6]], [[7]]]", "[[[]]]", "[[[8, 9]]]", |
| 1219 | + "[[[10], [11, 12]]]", "[[[13]]]", "[[[14, 15], [16]]]", "[[[17]]]", "[[[18, 19]]]", "[[[]]]" |
| 1220 | + } |
| 1221 | + }, |
| 1222 | + // 2D arrays of floats - Array(Array(Float64)) |
| 1223 | + { |
| 1224 | + "arr Array(Array(Float64))", |
| 1225 | + "(1, [[1.1, 2.2], [3.3]]), (2, [[4.4]]), (3, [[5.5, 6.6, 7.7]]), (4, [[]]), " + |
| 1226 | + "(5, [[8.8]]), (6, [[9.9, 10.1]]), (7, [[11.2]]), (8, [[12.3, 13.4]]), (9, [[14.5]]), (10, [[15.6, 16.7]])", |
| 1227 | + new String[] { |
| 1228 | + "[[1.1, 2.2], [3.3]]", "[[4.4]]", "[[5.5, 6.6, 7.7]]", "[[]]", |
| 1229 | + "[[8.8]]", "[[9.9, 10.1]]", "[[11.2]]", "[[12.3, 13.4]]", "[[14.5]]", "[[15.6, 16.7]]" |
| 1230 | + }, |
| 1231 | + new String[] { |
| 1232 | + "[[1.1, 2.2], [3.3]]", "[[4.4]]", "[[5.5, 6.6, 7.7]]", "[[]]", |
| 1233 | + "[[8.8]]", "[[9.9, 10.1]]", "[[11.2]]", "[[12.3, 13.4]]", "[[14.5]]", "[[15.6, 16.7]]" |
| 1234 | + } |
| 1235 | + }, |
| 1236 | + // 3D arrays of strings - Array(Array(Array(String))) |
| 1237 | + { |
| 1238 | + "arr Array(Array(Array(String)))", |
| 1239 | + "(1, [[['a', 'b']]]), (2, [[['c'], ['d', 'e']]]), (3, [[[]]]), (4, [[['f']]]), " + |
| 1240 | + "(5, [[['g', 'h']]]), (6, [[['i']]]), (7, [[['a', 'b'], ['c']], [['d', 'e', 'f']]]), (8, [[[]]]), (9, [[['m']]]), (10, [[['n', 'o']]])", |
| 1241 | + new String[] { // getString() format - with quotes |
| 1242 | + "[[['a', 'b']]]", "[[['c'], ['d', 'e']]]", "[[[]]]", "[[['f']]]", |
| 1243 | + "[[['g', 'h']]]", "[[['i']]]", "[[['a', 'b'], ['c']], [['d', 'e', 'f']]]", "[[[]]]", "[[['m']]]", "[[['n', 'o']]]" |
| 1244 | + }, |
| 1245 | + new String[] { // getList() format - no quotes |
| 1246 | + "[[[a, b]]]", "[[[c], [d, e]]]", "[[[]]]", "[[[f]]]", |
| 1247 | + "[[[g, h]]]", "[[[i]]]", "[[[a, b], [c]], [[d, e, f]]]", "[[[]]]", "[[[m]]]", "[[[n, o]]]" |
| 1248 | + } |
| 1249 | + }, |
| 1250 | + // 2D arrays of nullable integers - Array(Array(Nullable(Int32))) |
| 1251 | + { |
| 1252 | + "arr Array(Array(Nullable(Int32)))", |
| 1253 | + "(1, [[1, NULL, 2]]), (2, [[NULL]]), (3, [[3, 4, NULL]]), (4, [[]]), " + |
| 1254 | + "(5, [[NULL, NULL]]), (6, [[5]]), (7, [[6, NULL]]), (8, [[NULL, 7]]), (9, [[8, 9]]), (10, [[NULL]])", |
| 1255 | + new String[] { |
| 1256 | + "[[1, NULL, 2]]", "[[NULL]]", "[[3, 4, NULL]]", "[[]]", |
| 1257 | + "[[NULL, NULL]]", "[[5]]", "[[6, NULL]]", "[[NULL, 7]]", "[[8, 9]]", "[[NULL]]" |
| 1258 | + }, |
| 1259 | + new String[] { |
| 1260 | + "[[1, null, 2]]", "[[null]]", "[[3, 4, null]]", "[[]]", |
| 1261 | + "[[null, null]]", "[[5]]", "[[6, null]]", "[[null, 7]]", "[[8, 9]]", "[[null]]" |
| 1262 | + } |
| 1263 | + }, |
| 1264 | + // 4D arrays of integers - Array(Array(Array(Array(Int32)))) |
| 1265 | + { |
| 1266 | + "arr Array(Array(Array(Array(Int32))))", |
| 1267 | + "(1, [[[[1, 2]]]]), (2, [[[[3], [4, 5]]]]), (3, [[[[]]]]), (4, [[[[6]]]]), " + |
| 1268 | + "(5, [[[[7, 8]]]]), (6, [[[[9]]]]), (7, [[[[10, 11]]]]), (8, [[[[]]]]), (9, [[[[12]]]]), (10, [[[[13, 14]]]])", |
| 1269 | + new String[] { |
| 1270 | + "[[[[1, 2]]]]", "[[[[3], [4, 5]]]]", "[[[[]]]]", "[[[[6]]]]", |
| 1271 | + "[[[[7, 8]]]]", "[[[[9]]]]", "[[[[10, 11]]]]", "[[[[]]]]", "[[[[12]]]]", "[[[[13, 14]]]]" |
| 1272 | + }, |
| 1273 | + new String[] { |
| 1274 | + "[[[[1, 2]]]]", "[[[[3], [4, 5]]]]", "[[[[]]]]", "[[[[6]]]]", |
| 1275 | + "[[[[7, 8]]]]", "[[[[9]]]]", "[[[[10, 11]]]]", "[[[[]]]]", "[[[[12]]]]", "[[[[13, 14]]]]" |
| 1276 | + } |
| 1277 | + } |
| 1278 | + }; |
| 1279 | + } |
| 1280 | + |
1148 | 1281 | public static String tableDefinition(String table, String... columns) { |
1149 | 1282 | StringBuilder sb = new StringBuilder(); |
1150 | 1283 | sb.append("CREATE TABLE " + table + " ( "); |
|
0 commit comments