use of io.prestosql.spi.block.PageBuilderStatus in project hetu-core by openlookeng.
the class ArrayCombinationsFunction method combinations.
@TypeParameter("T")
@SqlType("array(array(T))")
public static Block combinations(@TypeParameter("T") Type elementType, @SqlType("array(T)") Block array, @SqlType(INTEGER) long n) {
int arrayLength = array.getPositionCount();
int combinationLength = toIntExact(n);
checkCondition(combinationLength >= 0, INVALID_FUNCTION_ARGUMENT, "combination size must not be negative: %s", combinationLength);
checkCondition(combinationLength <= MAX_COMBINATION_LENGTH, INVALID_FUNCTION_ARGUMENT, "combination size must not exceed %s: %s", MAX_COMBINATION_LENGTH, combinationLength);
ArrayType arrayType = new ArrayType(elementType);
if (combinationLength > arrayLength) {
return arrayType.createBlockBuilder(new PageBuilderStatus().createBlockBuilderStatus(), 0).build();
}
int combinationCount = combinationCount(arrayLength, combinationLength);
checkCondition(combinationCount * (long) combinationLength <= MAX_RESULT_ELEMENTS, INVALID_FUNCTION_ARGUMENT, "combinations exceed max size");
int[] ids = new int[combinationCount * combinationLength];
int idsPosition = 0;
int[] combination = firstCombination(arrayLength, combinationLength);
do {
arraycopy(combination, 0, ids, idsPosition, combinationLength);
idsPosition += combinationLength;
} while (nextCombination(combination, combinationLength));
verify(idsPosition == ids.length, "idsPosition != ids.length, %s and %s respectively", idsPosition, ids.length);
int[] offsets = new int[combinationCount + 1];
setAll(offsets, i -> i * combinationLength);
return ArrayBlock.fromElementBlock(combinationCount, Optional.empty(), offsets, new DictionaryBlock(array, ids));
}
use of io.prestosql.spi.block.PageBuilderStatus in project hetu-core by openlookeng.
the class TestArrayOfRowsUnnester method testArrayOfRowsUnnester.
/**
* Test operations of ArrayOfRowUnnester incrementally on the input.
* Output final blocks after the whole input has been processed.
*
* Input 3d array {@code elements} stores values from a column with type <array<row<varchar, varchar, ... {@code fieldCount} times> >.
* elements[i] corresponds to a position in this column, represents one array of row(....).
* elements[i][j] represents one row(....) object in the array.
* elements[i][j][k] represents value of kth field in row(...) object.
*/
private static Block[] testArrayOfRowsUnnester(int[] requiredOutputCounts, int[] unnestedLengths, Slice[][][] elements, int fieldCount) {
validateTestInput(requiredOutputCounts, unnestedLengths, elements, fieldCount);
int positionCount = requiredOutputCounts.length;
// True if there is a null Row element inside the array at this position
boolean[] containsNullRowElement = new boolean[positionCount];
// Populate containsNullRowElement
for (int i = 0; i < positionCount; i++) {
containsNullRowElement[i] = false;
if (elements[i] != null) {
for (int j = 0; j < elements[i].length; j++) {
if (elements[i][j] == null) {
containsNullRowElement[i] = true;
}
}
}
}
// Check for null elements in individual input fields
boolean[] nullsPresent = new boolean[fieldCount];
for (int field = 0; field < fieldCount; field++) {
nullsPresent[field] = nullExists(elements[field]);
}
// Create the unnester and input block
RowType rowType = RowType.anonymous(Collections.nCopies(fieldCount, VARCHAR));
Unnester arrayofRowsUnnester = new ArrayOfRowsUnnester(rowType);
Block arrayBlockOfRows = createArrayBlockOfRowBlocks(elements, rowType);
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();
arrayofRowsUnnester.resetInput(arrayBlockOfRows);
assertEquals(arrayofRowsUnnester.getInputEntryCount(), elements.length);
arrayofRowsUnnester.startNewOutput(status, 10);
boolean misAligned = false;
// Process inputTestCount positions
for (int i = 0; i < inputTestCount; i++) {
arrayofRowsUnnester.processCurrentAndAdvance(requiredOutputCounts[i]);
int elementsSize = (elements[i] != null ? elements[i].length : 0);
// (2) null Row element
if ((requiredOutputCounts[i] > elementsSize) || containsNullRowElement[i]) {
misAligned = true;
}
}
// Build output block and verify
blocks = arrayofRowsUnnester.buildOutputBlocksAndFlush();
assertEquals(blocks.length, rowType.getFields().size());
// 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;
}
use of io.prestosql.spi.block.PageBuilderStatus in project hetu-core by openlookeng.
the class TestArrayUnnester method testArrayUnnester.
private static Block[] testArrayUnnester(int[] requiredOutputCounts, int[] unnestedLengths, Slice[][][] elements) {
Slice[][] slices = getFieldElements(elements, 0);
validateTestInput(requiredOutputCounts, unnestedLengths, elements, 1);
// Check if there is a null element in the input
boolean nullPresent = nullExists(slices);
// Initialize unnester
Unnester arrayUnnester = new ArrayUnnester(VARCHAR);
Block arrayBlock = createArrayBlock(slices);
Block[] blocks = null;
// Verify output being produced after processing every position. (quadratic)
for (int inputTestCount = 1; inputTestCount <= elements.length; inputTestCount++) {
// Reset input
arrayUnnester.resetInput(arrayBlock);
assertEquals(arrayUnnester.getInputEntryCount(), elements.length);
// Prepare for new output
PageBuilderStatus status = new PageBuilderStatus();
arrayUnnester.startNewOutput(status, 10);
boolean misAligned = false;
// Process inputTestCount positions
for (int i = 0; i < inputTestCount; i++) {
int elementsSize = (elements[i] != null ? elements[i].length : 0);
assertEquals(arrayUnnester.getCurrentUnnestedLength(), elementsSize);
arrayUnnester.processCurrentAndAdvance(requiredOutputCounts[i]);
if (requiredOutputCounts[i] > elementsSize) {
misAligned = true;
}
}
// Verify output
blocks = arrayUnnester.buildOutputBlocksAndFlush();
assertEquals(blocks.length, 1);
assertTrue((blocks[0] instanceof DictionaryBlock) || (!nullPresent && misAligned));
assertFalse((blocks[0] instanceof DictionaryBlock) && (!nullPresent && misAligned));
Slice[] expectedOutput = computeExpectedUnnestedOutput(slices, requiredOutputCounts, 0, inputTestCount);
assertBlock(blocks[0], expectedOutput);
}
return blocks;
}
use of io.prestosql.spi.block.PageBuilderStatus in project hetu-core by openlookeng.
the class TestUnnestBlockBuilder method testAppendRange.
private static void testAppendRange(UnnestBlockBuilder unnestBlockBuilder, Slice[] values) {
unnestBlockBuilder.startNewOutput(new PageBuilderStatus(), 10);
assertTrue(values.length >= 3, "test requires at least 3 elements in values");
int startIndex = 1;
int length = values.length - 2;
unnestBlockBuilder.appendRange(startIndex, length);
Block block = unnestBlockBuilder.buildOutputAndFlush();
assertTrue(block instanceof DictionaryBlock);
assertBlock(block, Arrays.copyOfRange(values, startIndex, startIndex + length));
}
use of io.prestosql.spi.block.PageBuilderStatus in project hetu-core by openlookeng.
the class UnnestOperator method getOutput.
@Override
public Page getOutput() {
if (snapshotState != null) {
Page marker = snapshotState.nextMarker();
if (marker != null) {
return marker;
}
}
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);
}
Aggregations