Search in sources :

Example 11 with MapType

use of io.trino.spi.type.MapType in project trino by trinodb.

the class AvroDecoderTestUtil method checkArrayValues.

public static void checkArrayValues(Block block, Type type, Object value) {
    assertNotNull(type, "Type is null");
    assertTrue(type instanceof ArrayType, "Unexpected type");
    assertNotNull(block, "Block is null");
    assertNotNull(value, "Value is null");
    List<?> list = (List<?>) value;
    assertEquals(block.getPositionCount(), list.size());
    Type elementType = ((ArrayType) type).getElementType();
    if (elementType instanceof ArrayType) {
        for (int index = 0; index < block.getPositionCount(); index++) {
            if (block.isNull(index)) {
                assertNull(list.get(index));
                continue;
            }
            Block arrayBlock = block.getObject(index, Block.class);
            checkArrayValues(arrayBlock, elementType, list.get(index));
        }
    } else if (elementType instanceof MapType) {
        for (int index = 0; index < block.getPositionCount(); index++) {
            if (block.isNull(index)) {
                assertNull(list.get(index));
                continue;
            }
            Block mapBlock = block.getObject(index, Block.class);
            checkMapValues(mapBlock, elementType, list.get(index));
        }
    } else if (elementType instanceof RowType) {
        for (int index = 0; index < block.getPositionCount(); index++) {
            if (block.isNull(index)) {
                assertNull(list.get(index));
                continue;
            }
            Block rowBlock = block.getObject(index, Block.class);
            checkRowValues(rowBlock, elementType, list.get(index));
        }
    } else {
        for (int index = 0; index < block.getPositionCount(); index++) {
            checkPrimitiveValue(getObjectValue(elementType, block, index), list.get(index));
        }
    }
}
Also used : ArrayType(io.trino.spi.type.ArrayType) RowType(io.trino.spi.type.RowType) MapType(io.trino.spi.type.MapType) Type(io.trino.spi.type.Type) ArrayType(io.trino.spi.type.ArrayType) VarcharType(io.trino.spi.type.VarcharType) Block(io.trino.spi.block.Block) RowType(io.trino.spi.type.RowType) List(java.util.List) MapType(io.trino.spi.type.MapType)

Example 12 with MapType

use of io.trino.spi.type.MapType in project trino by trinodb.

the class TestDeltaLakeSchemaSupport method testSerializeSchemaAsJson.

@Test
public void testSerializeSchemaAsJson() throws Exception {
    DeltaLakeColumnHandle arrayColumn = new DeltaLakeColumnHandle("arr", new ArrayType(new ArrayType(INTEGER)), REGULAR);
    DeltaLakeColumnHandle structColumn = new DeltaLakeColumnHandle("str", RowType.from(ImmutableList.of(new RowType.Field(Optional.of("s1"), VarcharType.createUnboundedVarcharType()), new RowType.Field(Optional.of("s2"), RowType.from(ImmutableList.of(new RowType.Field(Optional.of("i1"), INTEGER), new RowType.Field(Optional.of("d2"), DecimalType.createDecimalType(38, 0))))))), REGULAR);
    TypeOperators typeOperators = new TypeOperators();
    DeltaLakeColumnHandle mapColumn = new DeltaLakeColumnHandle("m", new MapType(INTEGER, new MapType(INTEGER, INTEGER, typeOperators), typeOperators), REGULAR);
    URL expected = getResource("io/trino/plugin/deltalake/transactionlog/schema/nested_schema.json");
    ObjectMapper objectMapper = new ObjectMapper();
    String jsonEncoding = serializeSchemaAsJson(ImmutableList.of(arrayColumn, structColumn, mapColumn));
    assertEquals(objectMapper.readTree(jsonEncoding), objectMapper.readTree(expected));
}
Also used : ArrayType(io.trino.spi.type.ArrayType) RowType(io.trino.spi.type.RowType) DeltaLakeColumnHandle(io.trino.plugin.deltalake.DeltaLakeColumnHandle) MapType(io.trino.spi.type.MapType) URL(java.net.URL) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) TypeOperators(io.trino.spi.type.TypeOperators) Test(org.testng.annotations.Test)

Example 13 with MapType

use of io.trino.spi.type.MapType in project trino by trinodb.

the class MapFilterFunction method generateFilter.

private static MethodHandle generateFilter(MapType mapType) {
    CallSiteBinder binder = new CallSiteBinder();
    Type keyType = mapType.getKeyType();
    Type valueType = mapType.getValueType();
    Class<?> keyJavaType = Primitives.wrap(keyType.getJavaType());
    Class<?> valueJavaType = Primitives.wrap(valueType.getJavaType());
    ClassDefinition definition = new ClassDefinition(a(PUBLIC, FINAL), makeClassName("MapFilter"), type(Object.class));
    definition.declareDefaultConstructor(a(PRIVATE));
    Parameter state = arg("state", Object.class);
    Parameter block = arg("block", Block.class);
    Parameter function = arg("function", BinaryFunctionInterface.class);
    MethodDefinition method = definition.declareMethod(a(PUBLIC, STATIC), "filter", type(Block.class), ImmutableList.of(state, block, function));
    BytecodeBlock body = method.getBody();
    Scope scope = method.getScope();
    Variable positionCount = scope.declareVariable(int.class, "positionCount");
    Variable position = scope.declareVariable(int.class, "position");
    Variable pageBuilder = scope.declareVariable(PageBuilder.class, "pageBuilder");
    Variable mapBlockBuilder = scope.declareVariable(BlockBuilder.class, "mapBlockBuilder");
    Variable singleMapBlockWriter = scope.declareVariable(BlockBuilder.class, "singleMapBlockWriter");
    Variable keyElement = scope.declareVariable(keyJavaType, "keyElement");
    Variable valueElement = scope.declareVariable(valueJavaType, "valueElement");
    Variable keep = scope.declareVariable(Boolean.class, "keep");
    // invoke block.getPositionCount()
    body.append(positionCount.set(block.invoke("getPositionCount", int.class)));
    // prepare the single map block builder
    body.append(pageBuilder.set(state.cast(PageBuilder.class)));
    body.append(new IfStatement().condition(pageBuilder.invoke("isFull", boolean.class)).ifTrue(pageBuilder.invoke("reset", void.class)));
    body.append(mapBlockBuilder.set(pageBuilder.invoke("getBlockBuilder", BlockBuilder.class, constantInt(0))));
    body.append(singleMapBlockWriter.set(mapBlockBuilder.invoke("beginBlockEntry", BlockBuilder.class)));
    SqlTypeBytecodeExpression keySqlType = constantType(binder, keyType);
    BytecodeNode loadKeyElement;
    if (!keyType.equals(UNKNOWN)) {
        // key element must be non-null
        loadKeyElement = new BytecodeBlock().append(keyElement.set(keySqlType.getValue(block, position).cast(keyJavaType)));
    } else {
        loadKeyElement = new BytecodeBlock().append(keyElement.set(constantNull(keyJavaType)));
    }
    SqlTypeBytecodeExpression valueSqlType = constantType(binder, valueType);
    BytecodeNode loadValueElement;
    if (!valueType.equals(UNKNOWN)) {
        loadValueElement = new IfStatement().condition(block.invoke("isNull", boolean.class, add(position, constantInt(1)))).ifTrue(valueElement.set(constantNull(valueJavaType))).ifFalse(valueElement.set(valueSqlType.getValue(block, add(position, constantInt(1))).cast(valueJavaType)));
    } else {
        loadValueElement = new BytecodeBlock().append(valueElement.set(constantNull(valueJavaType)));
    }
    body.append(new ForLoop().initialize(position.set(constantInt(0))).condition(lessThan(position, positionCount)).update(incrementVariable(position, (byte) 2)).body(new BytecodeBlock().append(loadKeyElement).append(loadValueElement).append(keep.set(function.invoke("apply", Object.class, keyElement.cast(Object.class), valueElement.cast(Object.class)).cast(Boolean.class))).append(new IfStatement("if (keep != null && keep) ...").condition(and(notEqual(keep, constantNull(Boolean.class)), keep.cast(boolean.class))).ifTrue(new BytecodeBlock().append(keySqlType.invoke("appendTo", void.class, block, position, singleMapBlockWriter)).append(valueSqlType.invoke("appendTo", void.class, block, add(position, constantInt(1)), singleMapBlockWriter))))));
    body.append(mapBlockBuilder.invoke("closeEntry", BlockBuilder.class).pop());
    body.append(pageBuilder.invoke("declarePosition", void.class));
    body.append(constantType(binder, mapType).invoke("getObject", Object.class, mapBlockBuilder.cast(Block.class), subtract(mapBlockBuilder.invoke("getPositionCount", int.class), constantInt(1))).ret());
    Class<?> generatedClass = defineClass(definition, Object.class, binder.getBindings(), MapFilterFunction.class.getClassLoader());
    return methodHandle(generatedClass, "filter", Object.class, Block.class, BinaryFunctionInterface.class);
}
Also used : Signature.typeVariable(io.trino.metadata.Signature.typeVariable) Variable(io.airlift.bytecode.Variable) VariableInstruction.incrementVariable(io.airlift.bytecode.instruction.VariableInstruction.incrementVariable) ForLoop(io.airlift.bytecode.control.ForLoop) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) ClassDefinition(io.airlift.bytecode.ClassDefinition) IfStatement(io.airlift.bytecode.control.IfStatement) SqlTypeBytecodeExpression.constantType(io.trino.sql.gen.SqlTypeBytecodeExpression.constantType) TypeSignature.mapType(io.trino.spi.type.TypeSignature.mapType) Type(io.trino.spi.type.Type) TypeSignature.functionType(io.trino.spi.type.TypeSignature.functionType) MapType(io.trino.spi.type.MapType) Scope(io.airlift.bytecode.Scope) MethodDefinition(io.airlift.bytecode.MethodDefinition) CallSiteBinder(io.trino.sql.gen.CallSiteBinder) Parameter(io.airlift.bytecode.Parameter) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) Block(io.trino.spi.block.Block) BytecodeNode(io.airlift.bytecode.BytecodeNode) SqlTypeBytecodeExpression(io.trino.sql.gen.SqlTypeBytecodeExpression)

Example 14 with MapType

use of io.trino.spi.type.MapType in project trino by trinodb.

the class MapFromEntriesFunction method mapFromEntries.

@TypeParameter("K")
@TypeParameter("V")
@SqlType("map(K,V)")
@SqlNullable
public Block mapFromEntries(@OperatorDependency(operator = EQUAL, argumentTypes = { "K", "K" }, convention = @Convention(arguments = { BLOCK_POSITION, BLOCK_POSITION }, result = NULLABLE_RETURN)) BlockPositionEqual keyEqual, @OperatorDependency(operator = HASH_CODE, argumentTypes = "K", convention = @Convention(arguments = BLOCK_POSITION, result = FAIL_ON_NULL)) BlockPositionHashCode keyHashCode, @TypeParameter("map(K,V)") MapType mapType, ConnectorSession session, @SqlType("array(row(K,V))") Block mapEntries) {
    Type keyType = mapType.getKeyType();
    Type valueType = mapType.getValueType();
    RowType mapEntryType = RowType.anonymous(ImmutableList.of(keyType, valueType));
    if (pageBuilder.isFull()) {
        pageBuilder.reset();
    }
    int entryCount = mapEntries.getPositionCount();
    BlockBuilder mapBlockBuilder = pageBuilder.getBlockBuilder(0);
    BlockBuilder resultBuilder = mapBlockBuilder.beginBlockEntry();
    TypedSet uniqueKeys = createEqualityTypedSet(keyType, keyEqual, keyHashCode, entryCount, "map_from_entries");
    for (int i = 0; i < entryCount; i++) {
        if (mapEntries.isNull(i)) {
            mapBlockBuilder.closeEntry();
            pageBuilder.declarePosition();
            throw new TrinoException(INVALID_FUNCTION_ARGUMENT, "map entry cannot be null");
        }
        Block mapEntryBlock = mapEntryType.getObject(mapEntries, i);
        if (mapEntryBlock.isNull(0)) {
            mapBlockBuilder.closeEntry();
            pageBuilder.declarePosition();
            throw new TrinoException(INVALID_FUNCTION_ARGUMENT, "map key cannot be null");
        }
        if (!uniqueKeys.add(mapEntryBlock, 0)) {
            mapBlockBuilder.closeEntry();
            pageBuilder.declarePosition();
            throw new TrinoException(INVALID_FUNCTION_ARGUMENT, format("Duplicate keys (%s) are not allowed", keyType.getObjectValue(session, mapEntryBlock, 0)));
        }
        keyType.appendTo(mapEntryBlock, 0, resultBuilder);
        valueType.appendTo(mapEntryBlock, 1, resultBuilder);
    }
    mapBlockBuilder.closeEntry();
    pageBuilder.declarePosition();
    return mapType.getObject(mapBlockBuilder, mapBlockBuilder.getPositionCount() - 1);
}
Also used : Type(io.trino.spi.type.Type) SqlType(io.trino.spi.function.SqlType) RowType(io.trino.spi.type.RowType) MapType(io.trino.spi.type.MapType) RowType(io.trino.spi.type.RowType) TypedSet(io.trino.operator.aggregation.TypedSet) TypedSet.createEqualityTypedSet(io.trino.operator.aggregation.TypedSet.createEqualityTypedSet) TrinoException(io.trino.spi.TrinoException) Block(io.trino.spi.block.Block) BlockBuilder(io.trino.spi.block.BlockBuilder) SqlNullable(io.trino.spi.function.SqlNullable) TypeParameter(io.trino.spi.function.TypeParameter) SqlType(io.trino.spi.function.SqlType)

Example 15 with MapType

use of io.trino.spi.type.MapType in project trino by trinodb.

the class MapToJsonCast method specialize.

@Override
public ScalarFunctionImplementation specialize(BoundSignature boundSignature) {
    MapType mapType = (MapType) boundSignature.getArgumentType(0);
    Type keyType = mapType.getKeyType();
    Type valueType = mapType.getValueType();
    checkCondition(canCastToJson(mapType), INVALID_CAST_ARGUMENT, "Cannot cast %s to JSON", mapType);
    ObjectKeyProvider provider = ObjectKeyProvider.createObjectKeyProvider(keyType);
    JsonGeneratorWriter writer = JsonGeneratorWriter.createJsonGeneratorWriter(valueType, legacyRowToJson);
    MethodHandle methodHandle = METHOD_HANDLE.bindTo(provider).bindTo(writer);
    return new ChoicesScalarFunctionImplementation(boundSignature, FAIL_ON_NULL, ImmutableList.of(NEVER_NULL), methodHandle);
}
Also used : JsonGeneratorWriter(io.trino.util.JsonUtil.JsonGeneratorWriter) Type(io.trino.spi.type.Type) MapType(io.trino.spi.type.MapType) OperatorType(io.trino.spi.function.OperatorType) TypeSignature.mapType(io.trino.spi.type.TypeSignature.mapType) ObjectKeyProvider(io.trino.util.JsonUtil.ObjectKeyProvider) MapType(io.trino.spi.type.MapType) MethodHandle(java.lang.invoke.MethodHandle)

Aggregations

MapType (io.trino.spi.type.MapType)85 Type (io.trino.spi.type.Type)45 ArrayType (io.trino.spi.type.ArrayType)42 RowType (io.trino.spi.type.RowType)38 BlockBuilder (io.trino.spi.block.BlockBuilder)28 VarcharType (io.trino.spi.type.VarcharType)26 Block (io.trino.spi.block.Block)17 DecimalType (io.trino.spi.type.DecimalType)17 Map (java.util.Map)17 Test (org.testng.annotations.Test)17 ImmutableList (com.google.common.collect.ImmutableList)16 List (java.util.List)14 TypeSignature.mapType (io.trino.spi.type.TypeSignature.mapType)13 CharType (io.trino.spi.type.CharType)12 ArrayList (java.util.ArrayList)12 HashMap (java.util.HashMap)11 TypeOperators (io.trino.spi.type.TypeOperators)10 ImmutableMap (com.google.common.collect.ImmutableMap)9 VarbinaryType (io.trino.spi.type.VarbinaryType)8 Collectors.toList (java.util.stream.Collectors.toList)8