@Override public <T> T getObject(int position, Class<T> clazz) { return block.getObject(position, clazz); }
@Override public Block getObject(Block block, int position) { return block.getObject(position, Block.class); }
@Override public Block getObject(Block block, int position) { return block.getObject(position, Block.class); }
@Override public Block getObject(Block block, int position) { return block.getObject(position, Block.class); }
@Override public <T> T getObject(int position, Class<T> clazz) { return dictionary.getObject(getId(position), clazz); }
@Override public <T> T getObject(int position, Class<T> clazz) { checkReadablePosition(position); return value.getObject(0, clazz); }
@Override public <T> T getObject(int position, Class<T> clazz) { assureLoaded(); return block.getObject(position, clazz); }
@Override public void setField(Block block, int position) { Block rowBlock = block.getObject(position, Block.class); // TODO reuse row object and use FieldSetters, like we do at the top level // Ideally, we'd use the same recursive structure starting from the top, but // this requires modeling row types in the same way we model table rows // (multiple blocks vs all fields packed in a single block) List<Object> value = new ArrayList<>(fieldTypes.size()); for (int i = 0; i < fieldTypes.size(); i++) { Object element = getField(fieldTypes.get(i), rowBlock, i); value.add(element); } rowInspector.setStructFieldData(row, field, value); } }
@Override public <T> T getObject(int position, Class<T> clazz) { checkFieldIndex(position); return getRawFieldBlock(position).getObject(rowIndex, clazz); }
@Override public <T> T getObject(int position, Class<T> clazz) { checkReadablePosition(position); return getBlock().getObject(position + start, clazz); }
@Override public long hash(Block block, int position) { Block arrayBlock = block.getObject(position, Block.class); long result = 1; for (int i = 0; i < arrayBlock.getPositionCount(); i++) { Type elementType = fields.get(i).getType(); result = 31 * result + TypeUtils.hashPosition(elementType, arrayBlock, i); } return result; }
@Override public Object getObjectValue(ConnectorSession session, Block block, int position) { if (block.isNull(position)) { return null; } Block singleMapBlock = block.getObject(position, Block.class); if (!(singleMapBlock instanceof SingleMapBlock)) { throw new UnsupportedOperationException("Map is encoded with legacy block representation"); } Map<Object, Object> map = new HashMap<>(); for (int i = 0; i < singleMapBlock.getPositionCount(); i += 2) { map.put(keyType.getObjectValue(session, singleMapBlock, i), valueType.getObjectValue(session, singleMapBlock, i + 1)); } return Collections.unmodifiableMap(map); }
@Override public void setField(Block block, int position) { Block arrayBlock = block.getObject(position, Block.class); List<Object> list = new ArrayList<>(arrayBlock.getPositionCount()); for (int i = 0; i < arrayBlock.getPositionCount(); i++) { Object element = getField(elementType, arrayBlock, i); list.add(element); } rowInspector.setStructFieldData(row, field, list); } }
@Override public void setField(Block block, int position) { Block mapBlock = block.getObject(position, Block.class); Map<Object, Object> map = new HashMap<>(mapBlock.getPositionCount() * 2); for (int i = 0; i < mapBlock.getPositionCount(); i += 2) { Object key = getField(keyType, mapBlock, i); Object value = getField(valueType, mapBlock, i + 1); map.put(key, value); } rowInspector.setStructFieldData(row, field, map); } }
@Override public boolean equalTo(Block leftBlock, int leftPosition, Block rightBlock, int rightPosition) { Block leftRow = leftBlock.getObject(leftPosition, Block.class); Block rightRow = rightBlock.getObject(rightPosition, Block.class); for (int i = 0; i < leftRow.getPositionCount(); i++) { checkElementNotNull(leftRow.isNull(i)); checkElementNotNull(rightRow.isNull(i)); Type fieldType = fields.get(i).getType(); if (!fieldType.equalTo(leftRow, i, rightRow, i)) { return false; } } return true; }
private static boolean equals(Block block1, Block block2) { boolean retval = block1.getPositionCount() == block2.getPositionCount(); for (int i = 0; i < block1.getPositionCount() && retval; ++i) { if (block1 instanceof ArrayBlock && block2 instanceof ArrayBlock) { retval = equals(block1.getObject(i, Block.class), block2.getObject(i, Block.class)); } else { retval = block1.compareTo(i, 0, block1.getSliceLength(i), block2, i, 0, block2.getSliceLength(i)) == 0; } } return retval; }
@Override public boolean equalTo(Block leftBlock, int leftPosition, Block rightBlock, int rightPosition) { Block leftArray = leftBlock.getObject(leftPosition, Block.class); Block rightArray = rightBlock.getObject(rightPosition, Block.class); if (leftArray.getPositionCount() != rightArray.getPositionCount()) { return false; } for (int i = 0; i < leftArray.getPositionCount(); i++) { checkElementNotNull(leftArray.isNull(i), ARRAY_NULL_ELEMENT_MSG); checkElementNotNull(rightArray.isNull(i), ARRAY_NULL_ELEMENT_MSG); if (!elementType.equalTo(leftArray, i, rightArray, i)) { return false; } } return true; }
@Override public Object getObjectValue(ConnectorSession session, Block block, int position) { if (block.isNull(position)) { return null; } if (block instanceof AbstractArrayBlock) { return ((AbstractArrayBlock) block).apply((valuesBlock, start, length) -> arrayBlockToObjectValues(session, valuesBlock, start, length), position); } else { Block arrayBlock = block.getObject(position, Block.class); return arrayBlockToObjectValues(session, arrayBlock, 0, arrayBlock.getPositionCount()); } }
private static Block copyBlockViaWriteStructure(Block block, Supplier<BlockBuilder> newBlockBuilder) { BlockBuilder blockBuilder = newBlockBuilder.get(); for (int i = 0; i < block.getPositionCount(); i++) { if (block.isNull(i)) { blockBuilder.appendNull(); } else { blockBuilder.appendStructure(block.getObject(i, Block.class)); } } return blockBuilder.build(); }