use of io.trino.spi.block.PageBuilderStatus in project trino by trinodb.
the class UnnestOperator method getOutput.
@Override
public Page getOutput() {
if (currentPage == null) {
return null;
}
PageBuilderStatus pageBuilderStatus = new PageBuilderStatus(MAX_BYTES_PER_PAGE);
prepareForNewOutput(pageBuilderStatus);
int outputRowCount = 0;
while (currentPosition < currentPage.getPositionCount()) {
outputRowCount += processCurrentPosition();
currentPosition++;
if (outputRowCount >= MAX_ROWS_PER_BLOCK || pageBuilderStatus.isFull()) {
break;
}
}
Block[] outputBlocks = buildOutputBlocks();
if (currentPosition == currentPage.getPositionCount()) {
currentPage = null;
currentPosition = 0;
}
return new Page(outputBlocks);
}
use of io.trino.spi.block.PageBuilderStatus in project trino by trinodb.
the class TestUnnestBlockBuilder method testCapacityIncrease.
@Test
public void testCapacityIncrease() {
Slice[] values = new Slice[100];
for (int i = 0; i < values.length; i++) {
values[i] = utf8Slice("a");
}
UnnestBlockBuilder unnestBlockBuilder = new UnnestBlockBuilder(VARCHAR);
Block valuesBlock = createSimpleBlock(values);
unnestBlockBuilder.resetInputBlock(valuesBlock);
unnestBlockBuilder.startNewOutput(new PageBuilderStatus(), 20);
unnestBlockBuilder.appendRange(0, values.length);
assertBlock(unnestBlockBuilder.buildOutputAndFlush(), values);
unnestBlockBuilder.clearCurrentOutput();
}
use of io.trino.spi.block.PageBuilderStatus in project trino by trinodb.
the class TestUnnestBlockBuilder method testEmptyOutput.
@Test
public void testEmptyOutput() {
Slice[] values = toSlices(new String[] { "a", "b" });
UnnestBlockBuilder unnestBlockBuilder = new UnnestBlockBuilder(VARCHAR);
Block valuesBlock = createSimpleBlock(values);
unnestBlockBuilder.resetInputBlock(valuesBlock);
unnestBlockBuilder.startNewOutput(new PageBuilderStatus(), 10);
// Nothing added to the output
Block block = unnestBlockBuilder.buildOutputAndFlush();
assertTrue(block instanceof DictionaryBlock);
assertBlock(block, new Slice[] {});
}
use of io.trino.spi.block.PageBuilderStatus in project trino by trinodb.
the class TestArrayUnnester method testTrimmedBlocks.
@Test
public void testTrimmedBlocks() {
int[] unnestedLengths = { 2, 1, 2, 3, 1 };
Slice[][][] elements = column(array(toSlices("0.0.0"), toSlices("0.1.0")), array(toSlices("1.0.0")), array(toSlices("2.0.0"), toSlices("2.1.0")), array(toSlices("3.0.0"), toSlices("3.1.0"), toSlices("3.2.0")), array(toSlices("4.0.0")));
Slice[][] slices = getFieldElements(elements, 0);
Block arrayBlock = createArrayBlock(slices);
// Remove the first element from the arrayBlock for testing
int startElement = 1;
Slice[][] truncatedSlices = Arrays.copyOfRange(slices, startElement, slices.length - startElement + 1);
int[] truncatedUnnestedLengths = Arrays.copyOfRange(unnestedLengths, startElement, slices.length - startElement + 1);
Block truncatedBlock = arrayBlock.getRegion(startElement, truncatedSlices.length);
assertBlock(truncatedBlock, truncatedSlices);
Unnester arrayUnnester = new ArrayUnnester(VARCHAR);
arrayUnnester.resetInput(truncatedBlock);
arrayUnnester.startNewOutput(new PageBuilderStatus(), 20);
// Process all input entries in the truncated block
for (int i = 0; i < truncatedBlock.getPositionCount(); i++) {
arrayUnnester.processCurrentAndAdvance(truncatedUnnestedLengths[i]);
}
Block[] output = arrayUnnester.buildOutputBlocksAndFlush();
assertEquals(Arrays.asList(truncatedSlices).stream().mapToInt(slice -> slice.length).sum(), output[0].getPositionCount());
Slice[] expectedOutput = computeExpectedUnnestedOutput(truncatedSlices, truncatedUnnestedLengths, 0, truncatedSlices.length);
assertBlock(output[0], expectedOutput);
}
use of io.trino.spi.block.PageBuilderStatus in project trino by trinodb.
the class TestMapUnnester method testMapUnnester.
private static Block[] testMapUnnester(int[] requiredOutputCounts, int[] unnestedLengths, Slice[][][] elements) {
validateTestInput(requiredOutputCounts, unnestedLengths, elements, 2);
int positionCount = unnestedLengths.length;
for (int index = 0; index < positionCount; index++) {
if (elements[index] != null) {
for (int i = 0; i < elements[index].length; i++) {
assertTrue(elements[index][i] != null, "entry cannot be null");
assertEquals(elements[index][i].length, 2);
}
}
}
// Check for null elements in individual input fields
boolean[] nullsPresent = new boolean[2];
nullsPresent[0] = nullExists(elements[0]);
nullsPresent[1] = nullExists(elements[1]);
assertFalse(nullsPresent[0]);
// Create the unnester and input block
Unnester mapUnnester = new MapUnnester(VARCHAR, VARCHAR);
Block mapBlock = createBlockBuilderWithValues(elements).build();
Block[] blocks = null;
// Verify output being produced after processing every position. (quadratic)
for (int inputTestCount = 1; inputTestCount <= elements.length; inputTestCount++) {
// Reset input and prepare for new output
PageBuilderStatus status = new PageBuilderStatus();
mapUnnester.resetInput(mapBlock);
assertEquals(mapUnnester.getInputEntryCount(), elements.length);
mapUnnester.startNewOutput(status, 10);
boolean misAligned = false;
// Process inputTestCount positions
for (int i = 0; i < inputTestCount; i++) {
mapUnnester.processCurrentAndAdvance(requiredOutputCounts[i]);
int elementsSize = (elements[i] != null ? elements[i].length : 0);
// Check for misalignment, caused by required output count being greater than unnested length
if ((requiredOutputCounts[i] > elementsSize)) {
misAligned = true;
}
}
// Build output
blocks = mapUnnester.buildOutputBlocksAndFlush();
assertEquals(blocks.length, 2);
// Verify output blocks for individual fields
for (int field = 0; field < blocks.length; field++) {
assertTrue((blocks[field] instanceof DictionaryBlock) || (!nullsPresent[field] && misAligned));
assertFalse((blocks[field] instanceof DictionaryBlock) && (!nullsPresent[field] && misAligned));
Slice[][] fieldElements = getFieldElements(elements, field);
Slice[] expectedOutput = computeExpectedUnnestedOutput(fieldElements, requiredOutputCounts, 0, inputTestCount);
assertBlock(blocks[field], expectedOutput);
}
}
return blocks;
}
Aggregations