-
Couldn't load subscription status.
- Fork 1.9k
[Kernel] Introduce IcebergCompatV3 #4595
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 27 commits
1f6001f
3283154
074b131
053c23c
7e10891
a343b1b
0233915
afd5b86
0a01a32
029044f
2dad169
8a858e8
f9cb9ca
35427a4
b366ec6
74f1e05
6e76076
a681913
158d04b
27e79fa
4688720
0514737
36d5736
b6bc89c
84299dd
a80d79a
f03342c
2a93f08
6966bfe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -37,6 +37,7 @@ | |
| import io.delta.kernel.internal.data.TransactionStateRow; | ||
| import io.delta.kernel.internal.fs.Path; | ||
| import io.delta.kernel.internal.icebergcompat.IcebergCompatV2MetadataValidatorAndUpdater; | ||
| import io.delta.kernel.internal.icebergcompat.IcebergCompatV3MetadataValidatorAndUpdater; | ||
| import io.delta.kernel.statistics.DataFileStatistics; | ||
| import io.delta.kernel.types.StructType; | ||
| import io.delta.kernel.utils.*; | ||
|
|
@@ -164,14 +165,15 @@ static CloseableIterator<FilteredColumnarBatch> transformLogicalData( | |
| // - generating the default value columns | ||
| // - generating the generated columns | ||
|
|
||
| boolean isIcebergCompatV2Enabled = isIcebergCompatV2Enabled(transactionState); | ||
| boolean isIcebergCompatEnabled = | ||
| isIcebergCompatV2Enabled(transactionState) || isIcebergCompatV3Enabled(transactionState); | ||
| blockIfColumnMappingEnabled(transactionState); | ||
|
|
||
| // TODO: set the correct schema once writing into column mapping enabled table is supported. | ||
| String tablePath = getTablePath(transactionState); | ||
| return dataIter.map( | ||
| filteredBatch -> { | ||
| if (isIcebergCompatV2Enabled) { | ||
| if (isIcebergCompatEnabled) { | ||
| // don't remove the partition columns for iceberg compat v2 enabled tables | ||
| return filteredBatch; | ||
| } | ||
|
|
@@ -245,13 +247,18 @@ static CloseableIterator<Row> generateAppendActions( | |
| "DataWriteContext is not created by the `Transaction.getWriteContext()`"); | ||
|
|
||
| boolean isIcebergCompatV2Enabled = isIcebergCompatV2Enabled(transactionState); | ||
| boolean isIcebergCompatV3Enabled = isIcebergCompatV3Enabled(transactionState); | ||
KaiqiJinWow marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| URI tableRoot = new Path(getTablePath(transactionState)).toUri(); | ||
| StructType physicalSchema = TransactionStateRow.getPhysicalSchema(transactionState); | ||
| return fileStatusIter.map( | ||
| dataFileStatus -> { | ||
| if (isIcebergCompatV2Enabled) { | ||
| IcebergCompatV2MetadataValidatorAndUpdater.validateDataFileStatus(dataFileStatus); | ||
| } else if (isIcebergCompatV3Enabled) { | ||
| IcebergCompatV3MetadataValidatorAndUpdater.validateDataFileStatus(dataFileStatus); | ||
| } | ||
|
Comment on lines
256
to
260
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you can use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would push back this as |
||
|
|
||
| AddFile addFileRow = | ||
| AddFile.convertDataFileStatus( | ||
| physicalSchema, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,122 @@ | ||
| /* | ||
| * Copyright (2023) The Delta Lake Project Authors. | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| package io.delta.kernel.internal.icebergcompat; | ||
|
|
||
| import static io.delta.kernel.internal.tablefeatures.TableFeatures.*; | ||
| import static java.util.stream.Collectors.toList; | ||
|
|
||
| import io.delta.kernel.exceptions.KernelException; | ||
| import io.delta.kernel.internal.TableConfig; | ||
| import io.delta.kernel.internal.actions.Metadata; | ||
| import io.delta.kernel.internal.actions.Protocol; | ||
| import io.delta.kernel.internal.tablefeatures.TableFeature; | ||
| import io.delta.kernel.utils.DataFileStatus; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
| import java.util.Optional; | ||
| import java.util.stream.Stream; | ||
|
|
||
| /** Utility methods for validation and compatibility checks for Iceberg V3. */ | ||
| public class IcebergCompatV3MetadataValidatorAndUpdater | ||
KaiqiJinWow marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| extends IcebergCompatMetadataValidatorAndUpdater { | ||
|
|
||
| /** | ||
| * Validates that any change to property {@link TableConfig#ICEBERG_COMPAT_V3_ENABLED} is valid. | ||
| * Currently, the changes we support are | ||
| * | ||
| * <ul> | ||
| * <li>No change in enablement (true to true or false to false) | ||
| * <li>Enabling but only on a new table (false to true) | ||
| * </ul> | ||
| * | ||
| * The changes that we do not support and for which we throw an {@link KernelException} are | ||
| * | ||
| * <ul> | ||
| * <li>Disabling on an existing table (true to false) | ||
| * <li>Enabling on an existing table (false to true) | ||
| * </ul> | ||
| */ | ||
| public static void validateIcebergCompatV3Change( | ||
| Map<String, String> oldConfig, Map<String, String> newConfig, boolean isNewTable) { | ||
| blockConfigChangeOnExistingTable( | ||
| TableConfig.ICEBERG_COMPAT_V3_ENABLED, oldConfig, newConfig, isNewTable); | ||
| } | ||
|
|
||
| /** | ||
| * Validate and update the given Iceberg V3 metadata. | ||
| * | ||
| * @param newMetadata Metadata after the current updates | ||
| * @param newProtocol Protocol after the current updates | ||
| * @return The updated metadata if the metadata is valid and updated, otherwise empty. | ||
| * @throws UnsupportedOperationException if the metadata is not compatible with Iceberg V3 | ||
| * requirements | ||
| */ | ||
| public static Optional<Metadata> validateAndUpdateIcebergCompatV3Metadata( | ||
| boolean isCreatingNewTable, Metadata newMetadata, Protocol newProtocol) { | ||
| return INSTANCE.validateAndUpdateMetadata( | ||
| new IcebergCompatInputContext( | ||
| INSTANCE.compatFeatureName(), isCreatingNewTable, newMetadata, newProtocol)); | ||
| } | ||
|
|
||
| /** | ||
| * Validate the given {@link DataFileStatus} that is being added as a {@code add} action to Delta | ||
| * Log. Currently, it checks that the statistics are not empty. | ||
| * | ||
| * @param dataFileStatus The {@link DataFileStatus} to validate. | ||
| */ | ||
| public static void validateDataFileStatus(DataFileStatus dataFileStatus) { | ||
KaiqiJinWow marked this conversation as resolved.
Show resolved
Hide resolved
KaiqiJinWow marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| validateDataFileStatus(dataFileStatus, INSTANCE.compatFeatureName()); | ||
| } | ||
|
|
||
| /// ////////////////////////////////////////////////////////////////////////////// | ||
| /// Define the compatibility and update checks for icebergCompatV3 /// | ||
| /// ////////////////////////////////////////////////////////////////////////////// | ||
|
|
||
| private static final IcebergCompatV3MetadataValidatorAndUpdater INSTANCE = | ||
| new IcebergCompatV3MetadataValidatorAndUpdater(); | ||
|
|
||
| @Override | ||
| String compatFeatureName() { | ||
| return "icebergCompatV3"; | ||
| } | ||
|
|
||
| @Override | ||
| TableConfig<Boolean> requiredDeltaTableProperty() { | ||
| return TableConfig.ICEBERG_COMPAT_V3_ENABLED; | ||
| } | ||
|
|
||
| @Override | ||
| List<IcebergCompatRequiredTablePropertyEnforcer> requiredDeltaTableProperties() { | ||
| return Stream.of(COLUMN_MAPPING_REQUIREMENT, ROW_TRACKING_ENABLED).collect(toList()); | ||
| } | ||
|
|
||
| @Override | ||
| List<TableFeature> requiredDependencyTableFeatures() { | ||
| return Stream.of(ICEBERG_COMPAT_V3_W_FEATURE, COLUMN_MAPPING_RW_FEATURE, ROW_TRACKING_W_FEATURE) | ||
KaiqiJinWow marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| .collect(toList()); | ||
| } | ||
|
|
||
| @Override | ||
| List<IcebergCompatCheck> icebergCompatChecks() { | ||
| return Stream.of( | ||
| V3_CHECK_HAS_SUPPORTED_TYPES, | ||
| CHECK_ONLY_ICEBERG_COMPAT_V3_ENABLED, | ||
| CHECK_HAS_ALLOWED_PARTITION_TYPES, | ||
| CHECK_HAS_NO_PARTITION_EVOLUTION, | ||
| CHECK_HAS_SUPPORTED_TYPE_WIDENING) | ||
| .collect(toList()); | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.