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"));
}
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());
}
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);
}
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));
}
Aggregations