Skip to content

Commit a21fbd1

Browse files
committed
GH-586: Implement a separate unit test for FixedSizeBinaryWriter
1 parent d1036a1 commit a21fbd1

File tree

1 file changed

+218
-22
lines changed

1 file changed

+218
-22
lines changed

vector/src/test/java/org/apache/arrow/vector/TestMapVector.java

Lines changed: 218 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@
1616
*/
1717
package org.apache.arrow.vector;
1818

19+
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
1920
import static org.junit.jupiter.api.Assertions.assertEquals;
2021
import static org.junit.jupiter.api.Assertions.assertFalse;
2122
import static org.junit.jupiter.api.Assertions.assertNull;
2223
import static org.junit.jupiter.api.Assertions.assertSame;
24+
import static org.junit.jupiter.api.Assertions.assertThrows;
2325
import static org.junit.jupiter.api.Assertions.assertTrue;
2426

2527
import java.nio.ByteBuffer;
@@ -41,6 +43,7 @@
4143
import org.apache.arrow.vector.complex.writer.BaseWriter.MapWriter;
4244
import org.apache.arrow.vector.complex.writer.FieldWriter;
4345
import org.apache.arrow.vector.holder.UuidHolder;
46+
import org.apache.arrow.vector.holders.FixedSizeBinaryHolder;
4447
import org.apache.arrow.vector.types.Types.MinorType;
4548
import org.apache.arrow.vector.types.pojo.ArrowType;
4649
import org.apache.arrow.vector.types.pojo.Field;
@@ -168,7 +171,6 @@ public void testCopyFrom() throws Exception {
168171
// {1 -> 11, 2 -> 22, 3 -> 33}
169172
// null
170173
// {2 -> null}
171-
// {3 -> null}
172174
writer.setPosition(0); // optional
173175
writer.startMap();
174176
writer.startEntry();
@@ -192,22 +194,14 @@ public void testCopyFrom() throws Exception {
192194
writer.endEntry();
193195
writer.endMap();
194196

195-
writer.setPosition(3);
196-
writer.startMap();
197-
writer.startEntry();
198-
writer.key().bigInt().writeBigInt(3);
199-
writer.value().fixedSizeBinary().writeNull();
200-
writer.endEntry();
201-
writer.endMap();
202-
203-
writer.setValueCount(4);
197+
writer.setValueCount(3);
204198

205199
// copy values from input to output
206200
outVector.allocateNew();
207-
for (int i = 0; i < 4; i++) {
201+
for (int i = 0; i < 3; i++) {
208202
outVector.copyFrom(i, i, inVector);
209203
}
210-
outVector.setValueCount(4);
204+
outVector.setValueCount(3);
211205

212206
// assert the output vector is correct
213207
FieldReader reader = outVector.getReader();
@@ -216,8 +210,6 @@ public void testCopyFrom() throws Exception {
216210
assertFalse(reader.isSet(), "should be null");
217211
reader.setPosition(2);
218212
assertTrue(reader.isSet(), "shouldn't be null");
219-
reader.setPosition(3);
220-
assertTrue(reader.isSet(), "shouldn't be null");
221213

222214
/* index 0 */
223215
Object result = outVector.getObject(0);
@@ -244,14 +236,6 @@ public void testCopyFrom() throws Exception {
244236
resultStruct = (Map<?, ?>) resultSet.get(0);
245237
assertEquals(2L, getResultKey(resultStruct));
246238
assertFalse(resultStruct.containsKey(MapVector.VALUE_NAME));
247-
248-
/* index 3 */
249-
result = outVector.getObject(3);
250-
resultSet = (ArrayList<?>) result;
251-
assertEquals(1, resultSet.size());
252-
resultStruct = (Map<?, ?>) resultSet.get(0);
253-
assertEquals(3L, getResultKey(resultStruct));
254-
assertFalse(resultStruct.containsKey(MapVector.VALUE_NAME));
255239
}
256240
}
257241

@@ -1378,4 +1362,216 @@ public void testCopyFromForExtensionType() throws Exception {
13781362
assertEquals(u2, actualUuid);
13791363
}
13801364
}
1365+
1366+
private FixedSizeBinaryHolder getFixedSizeBinaryHolder(byte[] array) {
1367+
// {1 -> [11, 22], 2 -> [32, 21]}
1368+
FixedSizeBinaryHolder holder = new FixedSizeBinaryHolder();
1369+
holder.byteWidth = array.length;
1370+
holder.buffer = allocator.buffer(array.length);
1371+
for (int i = 0; i < array.length; i++) {
1372+
holder.buffer.setByte(i, array[i]);
1373+
}
1374+
1375+
return holder;
1376+
}
1377+
1378+
/**
1379+
* Regression test for GH-586: UnionMapWriter.fixedSizeBinary() should properly delegate to the
1380+
* entry writer for both key and value paths.
1381+
*/
1382+
@Test
1383+
public void testFixedSizeBinaryWriter() {
1384+
try (MapVector mapVector = MapVector.empty("map_vector", allocator, false)) {
1385+
UnionMapWriter writer = mapVector.getWriter();
1386+
writer.allocate();
1387+
1388+
// populate input vector with the following records
1389+
// {1 -> 2, 2 -> 3} - is used to initialize `key` and `value` writers - todo: this needs to be
1390+
// removed (test should work without it)
1391+
// {1 -> [11, 22], 2 -> [32, 21]}
1392+
// null
1393+
// {[11, 22] -> 1, [32, 21] -> 2}
1394+
// {[11, 22] -> null}
1395+
// {null -> [32, 21]} - wrong "for a given entry, the "key" is non-nullable" - todo: it
1396+
// shouldn't work. Should it?
1397+
writer.setPosition(0); // optional
1398+
writer.startMap();
1399+
writer.startEntry();
1400+
writer.key().bigInt().writeBigInt(1);
1401+
writer.value().bigInt().writeBigInt(2);
1402+
writer.endEntry();
1403+
writer.startEntry();
1404+
writer.key().bigInt().writeBigInt(2);
1405+
writer.value().bigInt().writeBigInt(3);
1406+
writer.endEntry();
1407+
writer.endMap();
1408+
1409+
// {1 -> [11, 22], 2 -> [32, 21]}
1410+
FixedSizeBinaryHolder holder1 = getFixedSizeBinaryHolder(new byte[] {11, 22});
1411+
FixedSizeBinaryHolder holder2 = getFixedSizeBinaryHolder(new byte[] {32, 21});
1412+
writer.setPosition(1);
1413+
writer.startMap();
1414+
writer.startEntry();
1415+
writer.key().bigInt().writeBigInt(1);
1416+
writer.value().fixedSizeBinary().write(holder1);
1417+
writer.endEntry();
1418+
holder1.buffer.close();
1419+
writer.startEntry();
1420+
writer.key().bigInt().writeBigInt(2);
1421+
writer.value().fixedSizeBinary().write(holder2);
1422+
writer.endEntry();
1423+
writer.endMap();
1424+
holder2.buffer.close();
1425+
1426+
// {[11, 22] -> 1, [32, 21] -> 2}
1427+
holder1 = getFixedSizeBinaryHolder(new byte[] {11, 22});
1428+
holder2 = getFixedSizeBinaryHolder(new byte[] {32, 21});
1429+
writer.setPosition(3);
1430+
writer.startMap();
1431+
writer.startEntry();
1432+
writer.key().fixedSizeBinary().write(holder1);
1433+
writer.value().bigInt().writeBigInt(1);
1434+
writer.endEntry();
1435+
holder1.buffer.close();
1436+
writer.startEntry();
1437+
writer.key().fixedSizeBinary().write(holder2);
1438+
writer.value().bigInt().writeBigInt(2);
1439+
writer.endEntry();
1440+
writer.endMap();
1441+
holder2.buffer.close();
1442+
1443+
// {[11, 22] -> null}
1444+
holder1 = getFixedSizeBinaryHolder(new byte[] {11, 22});
1445+
writer.setPosition(4);
1446+
writer.startMap();
1447+
writer.startEntry();
1448+
writer.key().fixedSizeBinary().write(holder1);
1449+
writer.endEntry();
1450+
writer.endMap();
1451+
holder1.buffer.close();
1452+
1453+
// {null -> [32, 21]}
1454+
holder2 = getFixedSizeBinaryHolder(new byte[] {32, 21});
1455+
writer.setPosition(5);
1456+
writer.startMap();
1457+
writer.startEntry();
1458+
writer.value().fixedSizeBinary().write(holder2);
1459+
writer.endEntry();
1460+
writer.endMap();
1461+
holder2.buffer.close();
1462+
1463+
writer.setValueCount(6);
1464+
1465+
// assert the output vector is correct
1466+
FieldReader reader = mapVector.getReader();
1467+
assertTrue(reader.isSet(), "shouldn't be null");
1468+
reader.setPosition(1);
1469+
assertTrue(reader.isSet(), "shouldn't be null");
1470+
reader.setPosition(2);
1471+
assertFalse(reader.isSet(), "should be null");
1472+
reader.setPosition(3);
1473+
assertTrue(reader.isSet(), "shouldn't be null");
1474+
reader.setPosition(4);
1475+
assertTrue(reader.isSet(), "shouldn't be null");
1476+
reader.setPosition(5);
1477+
assertTrue(reader.isSet(), "shouldn't be null");
1478+
1479+
/* index 0 */
1480+
Object result = mapVector.getObject(0);
1481+
ArrayList<?> resultSet = (ArrayList<?>) result;
1482+
assertEquals(2, resultSet.size());
1483+
Map<?, ?> resultStruct = (Map<?, ?>) resultSet.get(0);
1484+
assertEquals(1L, getResultKey(resultStruct));
1485+
assertEquals(2L, getResultValue(resultStruct));
1486+
resultStruct = (Map<?, ?>) resultSet.get(1);
1487+
assertEquals(2L, getResultKey(resultStruct));
1488+
assertEquals(3L, getResultValue(resultStruct));
1489+
1490+
/* index 1 */
1491+
result = mapVector.getObject(1);
1492+
resultSet = (ArrayList<?>) result;
1493+
assertEquals(2, resultSet.size());
1494+
resultStruct = (Map<?, ?>) resultSet.get(0);
1495+
assertEquals(1L, getResultKey(resultStruct));
1496+
assertTrue(resultStruct.containsKey(MapVector.VALUE_NAME));
1497+
assertArrayEquals(new byte[] {11, 22}, (byte[]) resultStruct.get(MapVector.VALUE_NAME));
1498+
resultStruct = (Map<?, ?>) resultSet.get(1);
1499+
assertEquals(2L, getResultKey(resultStruct));
1500+
assertTrue(resultStruct.containsKey(MapVector.VALUE_NAME));
1501+
assertArrayEquals(new byte[] {32, 21}, (byte[]) resultStruct.get(MapVector.VALUE_NAME));
1502+
1503+
/* index 2 */
1504+
result = mapVector.getObject(2);
1505+
assertNull(result);
1506+
1507+
/* index 3 */
1508+
result = mapVector.getObject(3);
1509+
resultSet = (ArrayList<?>) result;
1510+
assertEquals(2, resultSet.size());
1511+
resultStruct = (Map<?, ?>) resultSet.get(0);
1512+
assertTrue(resultStruct.containsKey(MapVector.KEY_NAME));
1513+
assertArrayEquals(new byte[] {11, 22}, (byte[]) resultStruct.get(MapVector.KEY_NAME));
1514+
assertEquals(1L, getResultValue(resultStruct));
1515+
resultStruct = (Map<?, ?>) resultSet.get(1);
1516+
assertTrue(resultStruct.containsKey(MapVector.KEY_NAME));
1517+
assertArrayEquals(new byte[] {32, 21}, (byte[]) resultStruct.get(MapVector.KEY_NAME));
1518+
assertEquals(2L, getResultValue(resultStruct));
1519+
1520+
/* index 4 */
1521+
result = mapVector.getObject(4);
1522+
resultSet = (ArrayList<?>) result;
1523+
assertEquals(1, resultSet.size());
1524+
resultStruct = (Map<?, ?>) resultSet.get(0);
1525+
assertTrue(resultStruct.containsKey(MapVector.KEY_NAME));
1526+
assertArrayEquals(new byte[] {11, 22}, (byte[]) resultStruct.get(MapVector.KEY_NAME));
1527+
assertFalse(resultStruct.containsKey(MapVector.VALUE_NAME));
1528+
1529+
/* index 5 */
1530+
result = mapVector.getObject(5);
1531+
resultSet = (ArrayList<?>) result;
1532+
assertEquals(1, resultSet.size());
1533+
resultStruct = (Map<?, ?>) resultSet.get(0);
1534+
assertFalse(resultStruct.containsKey(MapVector.KEY_NAME));
1535+
assertTrue(resultStruct.containsKey(MapVector.VALUE_NAME));
1536+
assertArrayEquals(new byte[] {32, 21}, (byte[]) resultStruct.get(MapVector.VALUE_NAME));
1537+
}
1538+
}
1539+
1540+
@Test
1541+
public void testFixedSizeBinaryWriterInitializationError() {
1542+
try (MapVector mapVector = MapVector.empty("map_vector", allocator, false)) {
1543+
UnionMapWriter writer = mapVector.getWriter();
1544+
writer.allocate();
1545+
1546+
// populate input vector with the following records
1547+
// {[11, 22] -> [32, 21]} - todo: it shouldn't throw. Should it?
1548+
FixedSizeBinaryHolder holder1 = getFixedSizeBinaryHolder(new byte[] {11, 22});
1549+
FixedSizeBinaryHolder holder2 = getFixedSizeBinaryHolder(new byte[] {32, 21});
1550+
1551+
writer.setPosition(0); // optional
1552+
writer.startMap();
1553+
writer.startEntry();
1554+
assertThrows(NullPointerException.class, () -> writer.key().fixedSizeBinary().write(holder1));
1555+
assertThrows(
1556+
NullPointerException.class, () -> writer.value().fixedSizeBinary().write(holder2));
1557+
writer.endEntry();
1558+
holder1.buffer.close();
1559+
holder2.buffer.close();
1560+
writer.endMap();
1561+
1562+
writer.setValueCount(1);
1563+
1564+
// assert the output vector is correct
1565+
FieldReader reader = mapVector.getReader();
1566+
assertTrue(reader.isSet(), "shouldn't be null");
1567+
1568+
/* index 0 */
1569+
Object result = mapVector.getObject(0);
1570+
ArrayList<?> resultSet = (ArrayList<?>) result;
1571+
assertEquals(1, resultSet.size());
1572+
Map<?, ?> resultStruct = (Map<?, ?>) resultSet.get(0);
1573+
assertFalse(resultStruct.containsKey(MapVector.KEY_NAME));
1574+
assertFalse(resultStruct.containsKey(MapVector.VALUE_NAME));
1575+
}
1576+
}
13811577
}

0 commit comments

Comments
 (0)