use of io.trino.spi.type.RowType in project trino by trinodb.
the class ExpressionConverter method toIcebergExpression.
private static Expression toIcebergExpression(String columnName, Type type, Domain domain) {
if (domain.isAll()) {
return alwaysTrue();
}
if (domain.getValues().isNone()) {
return domain.isNullAllowed() ? isNull(columnName) : alwaysFalse();
}
if (domain.getValues().isAll()) {
return domain.isNullAllowed() ? alwaysTrue() : not(isNull(columnName));
}
// Skip structural types. TODO (https://github.com/trinodb/trino/issues/8759) Evaluate Apache Iceberg's support for predicate on structural types
if (type instanceof ArrayType || type instanceof MapType || type instanceof RowType) {
// Fail fast. Ignoring expression could lead to data loss in case of deletions.
throw new UnsupportedOperationException("Unsupported type for expression: " + type);
}
if (type.isOrderable()) {
List<Range> orderedRanges = domain.getValues().getRanges().getOrderedRanges();
List<Object> icebergValues = new ArrayList<>();
List<Expression> rangeExpressions = new ArrayList<>();
for (Range range : orderedRanges) {
if (range.isSingleValue()) {
icebergValues.add(getIcebergLiteralValue(type, range.getLowBoundedValue()));
} else {
rangeExpressions.add(toIcebergExpression(columnName, range));
}
}
Expression ranges = or(rangeExpressions);
Expression values = icebergValues.isEmpty() ? alwaysFalse() : in(columnName, icebergValues);
Expression nullExpression = domain.isNullAllowed() ? isNull(columnName) : alwaysFalse();
return or(nullExpression, or(values, ranges));
}
throw new VerifyException(format("Unsupported type %s with domain values %s", type, domain));
}
use of io.trino.spi.type.RowType in project trino by trinodb.
the class RaptorStorageManager method getColumnInfoFromOrcColumnTypes.
private List<ColumnInfo> getColumnInfoFromOrcColumnTypes(List<String> orcColumnNames, ColumnMetadata<OrcType> orcColumnTypes) {
Type rowType = getType(orcColumnTypes, ROOT_COLUMN);
if (orcColumnNames.size() != rowType.getTypeParameters().size()) {
throw new TrinoException(RAPTOR_ERROR, "Column names and types do not match");
}
ImmutableList.Builder<ColumnInfo> list = ImmutableList.builder();
for (int i = 0; i < orcColumnNames.size(); i++) {
list.add(new ColumnInfo(Long.parseLong(orcColumnNames.get(i)), rowType.getTypeParameters().get(i)));
}
return list.build();
}
use of io.trino.spi.type.RowType in project trino by trinodb.
the class JsonToRowCast method specialize.
@Override
protected ScalarFunctionImplementation specialize(BoundSignature boundSignature) {
RowType rowType = (RowType) boundSignature.getReturnType();
checkCondition(canCastFromJson(rowType), INVALID_CAST_ARGUMENT, "Cannot cast JSON to %s", rowType);
BlockBuilderAppender fieldAppender = createBlockBuilderAppender(rowType);
MethodHandle methodHandle = METHOD_HANDLE.bindTo(rowType).bindTo(fieldAppender);
return new ChoicesScalarFunctionImplementation(boundSignature, NULLABLE_RETURN, ImmutableList.of(NEVER_NULL), methodHandle);
}
use of io.trino.spi.type.RowType in project trino by trinodb.
the class TestArrayOfRowsUnnester method testArrayOfRowsUnnester.
/**
* Test operations of ArrayOfRowUnnester incrementally on the input.
* Output final blocks after the whole input has been processed.
* <p>
* 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.trino.spi.type.RowType in project trino by trinodb.
the class TestArrayOfRowsUnnester method testTrimmedBlocks.
@Test
public void testTrimmedBlocks() {
int fieldCount = 3;
int[] unnestedLengths = { 1, 2, 1 };
Slice[][][] elements = column(array(toSlices("0.0.0", "0.0.1", "0.0.2")), array(toSlices("1.0.0", "1.0.1", "1.0.2"), toSlices("1.1.0", "1.1.1", "1.1.2")), array(toSlices("2.0.0", "2.0.1", "2.0.2")));
RowType rowType = RowType.anonymous(Collections.nCopies(fieldCount, VARCHAR));
Block arrayOfRowBlock = createArrayBlockOfRowBlocks(elements, rowType);
// Remove the first element from the arrayBlock for testing
int startElement = 1;
Slice[][][] truncatedSlices = Arrays.copyOfRange(elements, startElement, elements.length - startElement + 1);
int[] truncatedUnnestedLengths = Arrays.copyOfRange(unnestedLengths, startElement, elements.length - startElement + 1);
Block truncatedBlock = arrayOfRowBlock.getRegion(startElement, truncatedSlices.length);
Unnester arrayOfRowsUnnester = new ArrayOfRowsUnnester(rowType);
arrayOfRowsUnnester.resetInput(truncatedBlock);
arrayOfRowsUnnester.startNewOutput(new PageBuilderStatus(), 20);
// Process all input entries in the truncated block
for (int i = 0; i < truncatedBlock.getPositionCount(); i++) {
arrayOfRowsUnnester.processCurrentAndAdvance(truncatedUnnestedLengths[i]);
}
Block[] output = arrayOfRowsUnnester.buildOutputBlocksAndFlush();
assertEquals(Arrays.asList(truncatedSlices).stream().mapToInt(slice -> slice.length).sum(), output[0].getPositionCount());
for (int i = 0; i < fieldCount; i++) {
Slice[] expectedOutput = computeExpectedUnnestedOutput(getFieldElements(truncatedSlices, i), truncatedUnnestedLengths, 0, truncatedSlices.length);
assertBlock(output[i], expectedOutput);
}
}
Aggregations