Search in sources :

Example 1 with ColumnWithStructSubfield

use of com.facebook.presto.hive.ColumnEncryptionInformation.ColumnWithStructSubfield in project presto by prestodb.

the class TestColumnEncryptionInformation method testColumnWithStructSubfieldWithSubfield.

@Test
public void testColumnWithStructSubfieldWithSubfield() {
    ColumnWithStructSubfield column = ColumnWithStructSubfield.valueOf("a.b.c.d");
    assertEquals(column.getColumnName(), "a");
    assertTrue(column.getSubfieldPath().isPresent());
    assertEquals(column.getSubfieldPath().get(), "b.c.d");
    assertTrue(column.getChildField().isPresent());
    assertEquals(column.getChildField().get(), ColumnWithStructSubfield.valueOf("b.c.d"));
}
Also used : ColumnWithStructSubfield(com.facebook.presto.hive.ColumnEncryptionInformation.ColumnWithStructSubfield) Test(org.testng.annotations.Test)

Example 2 with ColumnWithStructSubfield

use of com.facebook.presto.hive.ColumnEncryptionInformation.ColumnWithStructSubfield in project presto by prestodb.

the class TestColumnEncryptionInformation method testColumnWithStructSubfieldWithNoSubfield.

@Test
public void testColumnWithStructSubfieldWithNoSubfield() {
    ColumnWithStructSubfield column = ColumnWithStructSubfield.valueOf("a");
    assertEquals(column.getColumnName(), "a");
    assertFalse(column.getSubfieldPath().isPresent());
    assertFalse(column.getChildField().isPresent());
}
Also used : ColumnWithStructSubfield(com.facebook.presto.hive.ColumnEncryptionInformation.ColumnWithStructSubfield) Test(org.testng.annotations.Test)

Example 3 with ColumnWithStructSubfield

use of com.facebook.presto.hive.ColumnEncryptionInformation.ColumnWithStructSubfield in project presto by prestodb.

the class AbstractDwrfEncryptionInformationSource method getFieldToKeyReference.

private static Optional<Map<String, String>> getFieldToKeyReference(DwrfTableEncryptionProperties encryptionProperties, Optional<Set<HiveColumnHandle>> requestedColumns) {
    Optional<ColumnEncryptionInformation> columnEncryptionInformation = encryptionProperties.getColumnEncryptionInformation();
    Optional<String> encryptTable = encryptionProperties.getEncryptTable();
    Map<String, String> fieldToKeyReference;
    if (encryptTable.isPresent()) {
        if (!requestedColumns.isPresent() || !requestedColumns.get().isEmpty()) {
            fieldToKeyReference = ImmutableMap.of(DwrfEncryptionMetadata.TABLE_IDENTIFIER, encryptTable.get());
        } else {
            fieldToKeyReference = ImmutableMap.of();
        }
    } else if (columnEncryptionInformation.isPresent()) {
        Map<ColumnWithStructSubfield, String> allFieldsToKeyReference = columnEncryptionInformation.get().getColumnToKeyReference();
        Optional<Set<String>> requestedColumnNames = requestedColumns.map(columns -> columns.stream().map(HiveColumnHandle::getName).collect(toImmutableSet()));
        fieldToKeyReference = allFieldsToKeyReference.entrySet().stream().filter(entry -> requestedColumnNames.map(columns -> columns.contains(entry.getKey().getColumnName())).orElse(true)).collect(toImmutableMap(entry -> entry.getKey().toString(), Map.Entry::getValue));
    } else {
        throw new PrestoException(GENERIC_INTERNAL_ERROR, "Neither of encryptColumn or encryptTable present. We should never hit this");
    }
    return Optional.of(fieldToKeyReference);
}
Also used : OrcSerde(com.facebook.hive.orc.OrcSerde) Table(com.facebook.presto.hive.metastore.Table) ImmutableMap(com.google.common.collect.ImmutableMap) GENERIC_INTERNAL_ERROR(com.facebook.presto.spi.StandardErrorCode.GENERIC_INTERNAL_ERROR) Set(java.util.Set) PrestoException(com.facebook.presto.spi.PrestoException) Partition(com.facebook.presto.hive.metastore.Partition) ConnectorSession(com.facebook.presto.spi.ConnectorSession) ColumnWithStructSubfield(com.facebook.presto.hive.ColumnEncryptionInformation.ColumnWithStructSubfield) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) Map(java.util.Map) DwrfTableEncryptionProperties.fromHiveTableProperties(com.facebook.presto.hive.DwrfTableEncryptionProperties.fromHiveTableProperties) Optional(java.util.Optional) ImmutableSet.toImmutableSet(com.google.common.collect.ImmutableSet.toImmutableSet) Optional(java.util.Optional) PrestoException(com.facebook.presto.spi.PrestoException) ImmutableMap(com.google.common.collect.ImmutableMap) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) Map(java.util.Map)

Example 4 with ColumnWithStructSubfield

use of com.facebook.presto.hive.ColumnEncryptionInformation.ColumnWithStructSubfield in project presto by prestodb.

the class HiveMetadata method getTableEncryptionPropertiesFromTableProperties.

protected Optional<TableEncryptionProperties> getTableEncryptionPropertiesFromTableProperties(ConnectorTableMetadata tableMetadata, HiveStorageFormat hiveStorageFormat, List<String> partitionedBy) {
    ColumnEncryptionInformation columnEncryptionInformation = getEncryptColumns(tableMetadata.getProperties());
    String tableEncryptionReference = getEncryptTable(tableMetadata.getProperties());
    if (tableEncryptionReference == null && (columnEncryptionInformation == null || !columnEncryptionInformation.hasEntries())) {
        return Optional.empty();
    }
    if (tableEncryptionReference != null && columnEncryptionInformation.hasEntries()) {
        throw new PrestoException(INVALID_TABLE_PROPERTY, format("Only one of %s or %s should be specified", ENCRYPT_TABLE, ENCRYPT_COLUMNS));
    }
    if (hiveStorageFormat != DWRF) {
        throw new PrestoException(NOT_SUPPORTED, "Only DWRF file format supports encryption at this time");
    }
    if (tableEncryptionReference != null) {
        return Optional.of(getDwrfTableEncryptionProperties(Optional.of(tableEncryptionReference), Optional.empty(), tableMetadata));
    }
    partitionedBy.forEach(partitionColumn -> {
        if (columnEncryptionInformation.getColumnToKeyReference().containsKey(ColumnWithStructSubfield.valueOf(partitionColumn))) {
            throw new PrestoException(INVALID_TABLE_PROPERTY, format("Partition column (%s) cannot be used as an encryption column", partitionColumn));
        }
    });
    Map<String, ColumnMetadata> columnMetadata = tableMetadata.getColumns().stream().collect(toImmutableMap(ColumnMetadata::getName, identity()));
    // Sorting to ensure that we can find cases of multiple referenceKeys within the same struct chain. Example - a.b and a.b.c
    // By sorting we ensure that we have already seen a.b and can find that when we visit a.b.c
    List<ColumnWithStructSubfield> sortedColumns = new ArrayList<>(columnEncryptionInformation.getColumnToKeyReference().keySet());
    sortedColumns.sort(Comparator.comparing(ColumnWithStructSubfield::toString));
    Set<String> seenColumns = new HashSet<>();
    for (ColumnWithStructSubfield columnWithSubfield : sortedColumns) {
        ColumnMetadata column = columnMetadata.get(columnWithSubfield.getColumnName());
        if (column == null) {
            throw new PrestoException(INVALID_TABLE_PROPERTY, format("In %s unable to find column %s", ENCRYPT_COLUMNS, columnWithSubfield.getColumnName()));
        }
        if (seenColumns.contains(columnWithSubfield.toString())) {
            throw new PrestoException(INVALID_TABLE_PROPERTY, format("The same column/subfield cannot have 2 encryption keys"));
        }
        if (columnWithSubfield.getSubfieldPath().isPresent()) {
            Iterable<String> subfieldPathFragments = Splitter.on(".").split(columnWithSubfield.getSubfieldPath().get());
            Type columnType = column.getType();
            String parentPath = columnWithSubfield.getColumnName();
            for (String pathFragment : subfieldPathFragments) {
                if (!(columnType instanceof RowType)) {
                    throw new PrestoException(INVALID_TABLE_PROPERTY, format("In %s subfields declared in %s, but %s has type %s", ENCRYPT_COLUMNS, columnWithSubfield.toString(), column.getName(), column.getType().getDisplayName()));
                }
                if (seenColumns.contains(parentPath)) {
                    throw new PrestoException(INVALID_TABLE_PROPERTY, format("For (%s) found a keyReference at a higher level field (%s)", columnWithSubfield.toString(), parentPath));
                }
                RowType row = (RowType) columnType;
                columnType = row.getFields().stream().filter(f -> f.getName().orElse("").equals(pathFragment)).findAny().map(RowType.Field::getType).orElseThrow(() -> new PrestoException(INVALID_TABLE_PROPERTY, format("In %s subfields declared in %s, but %s has type %s", ENCRYPT_COLUMNS, columnWithSubfield.toString(), column.getName(), column.getType().getDisplayName())));
                parentPath = format("%s.%s", parentPath, pathFragment);
            }
        }
        seenColumns.add(columnWithSubfield.toString());
    }
    return Optional.of(getDwrfTableEncryptionProperties(Optional.empty(), Optional.of(columnEncryptionInformation), tableMetadata));
}
Also used : ColumnMetadata(com.facebook.presto.spi.ColumnMetadata) ColumnWithStructSubfield(com.facebook.presto.hive.ColumnEncryptionInformation.ColumnWithStructSubfield) ArrayList(java.util.ArrayList) RowType(com.facebook.presto.common.type.RowType) PrestoException(com.facebook.presto.spi.PrestoException) VarcharType.createUnboundedVarcharType(com.facebook.presto.common.type.VarcharType.createUnboundedVarcharType) TableStatisticType(com.facebook.presto.spi.statistics.TableStatisticType) RowType(com.facebook.presto.common.type.RowType) MapType(com.facebook.presto.common.type.MapType) HiveWriteUtils.isWritableType(com.facebook.presto.hive.HiveWriteUtils.isWritableType) Type(com.facebook.presto.common.type.Type) Varchars.isVarcharType(com.facebook.presto.common.type.Varchars.isVarcharType) TypeUtils.isNumericType(com.facebook.presto.common.type.TypeUtils.isNumericType) Chars.isCharType(com.facebook.presto.common.type.Chars.isCharType) ArrayType(com.facebook.presto.common.type.ArrayType) ColumnStatisticType(com.facebook.presto.spi.statistics.ColumnStatisticType) HiveType.toHiveType(com.facebook.presto.hive.HiveType.toHiveType) HiveSessionProperties.isUsePageFileForHiveUnsupportedType(com.facebook.presto.hive.HiveSessionProperties.isUsePageFileForHiveUnsupportedType) PrestoTableType(com.facebook.presto.hive.metastore.PrestoTableType) HashSet(java.util.HashSet)

Aggregations

ColumnWithStructSubfield (com.facebook.presto.hive.ColumnEncryptionInformation.ColumnWithStructSubfield)4 PrestoException (com.facebook.presto.spi.PrestoException)2 Test (org.testng.annotations.Test)2 OrcSerde (com.facebook.hive.orc.OrcSerde)1 ArrayType (com.facebook.presto.common.type.ArrayType)1 Chars.isCharType (com.facebook.presto.common.type.Chars.isCharType)1 MapType (com.facebook.presto.common.type.MapType)1 RowType (com.facebook.presto.common.type.RowType)1 Type (com.facebook.presto.common.type.Type)1 TypeUtils.isNumericType (com.facebook.presto.common.type.TypeUtils.isNumericType)1 VarcharType.createUnboundedVarcharType (com.facebook.presto.common.type.VarcharType.createUnboundedVarcharType)1 Varchars.isVarcharType (com.facebook.presto.common.type.Varchars.isVarcharType)1 DwrfTableEncryptionProperties.fromHiveTableProperties (com.facebook.presto.hive.DwrfTableEncryptionProperties.fromHiveTableProperties)1 HiveSessionProperties.isUsePageFileForHiveUnsupportedType (com.facebook.presto.hive.HiveSessionProperties.isUsePageFileForHiveUnsupportedType)1 HiveType.toHiveType (com.facebook.presto.hive.HiveType.toHiveType)1 HiveWriteUtils.isWritableType (com.facebook.presto.hive.HiveWriteUtils.isWritableType)1 Partition (com.facebook.presto.hive.metastore.Partition)1 PrestoTableType (com.facebook.presto.hive.metastore.PrestoTableType)1 Table (com.facebook.presto.hive.metastore.Table)1 ColumnMetadata (com.facebook.presto.spi.ColumnMetadata)1