From 1798a07d9af7a82052c99135bda845cb28ad8452 Mon Sep 17 00:00:00 2001 From: okayhooni Date: Thu, 14 Dec 2023 20:09:41 +0900 Subject: [PATCH 1/3] iceberg.query-partition-pruning-required option was added --- .../trino/plugin/iceberg/IcebergConfig.java | 21 +++++++++++++++++++ .../trino/plugin/iceberg/IcebergMetadata.java | 14 +++++++++---- .../iceberg/IcebergSessionProperties.java | 11 ++++++++++ 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergConfig.java b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergConfig.java index 67e4b9675c2a..e302a3a576ee 100644 --- a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergConfig.java +++ b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergConfig.java @@ -21,6 +21,7 @@ import io.airlift.units.Duration; import io.trino.plugin.hive.HiveCompressionCodec; import jakarta.validation.constraints.AssertFalse; +import jakarta.validation.constraints.AssertTrue; import jakarta.validation.constraints.DecimalMax; import jakarta.validation.constraints.DecimalMin; import jakarta.validation.constraints.Max; @@ -78,6 +79,7 @@ public class IcebergConfig private Optional materializedViewsStorageSchema = Optional.empty(); private boolean sortedWritingEnabled = true; private boolean queryPartitionFilterRequired; + private boolean queryPartitionPruningRequired; public CatalogType getCatalogType() { @@ -413,6 +415,25 @@ public boolean isQueryPartitionFilterRequired() return queryPartitionFilterRequired; } + @Config("iceberg.query-partition-pruning-required") + @ConfigDescription("Require a partition pruning on at least one partition column in the query plan. This can be enabled only with iceberg.query-partition-filter-required=true") + public IcebergConfig setQueryPartitionFilterPruningRequired(boolean queryPartitionPruningRequired) + { + this.queryPartitionPruningRequired = queryPartitionPruningRequired; + return this; + } + + public boolean isQueryPartitionPruningRequired() + { + return queryPartitionPruningRequired; + } + + @AssertTrue(message = "iceberg.query-partition-pruning-required may only be enabled when iceberg.query-partition-filter-required is set to true") + public boolean isQueryPartitionPruningEnabledWhenPartitionFilterIsEnabled() + { + return !queryPartitionPruningRequired || queryPartitionFilterRequired; + } + @AssertFalse(message = "iceberg.materialized-views.storage-schema may only be set when iceberg.materialized-views.hide-storage-table is set to false") public boolean isStorageSchemaSetWhenHidingIsEnabled() { diff --git a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergMetadata.java b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergMetadata.java index 9595bb202cde..d1b98f4f0d0c 100644 --- a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergMetadata.java +++ b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergMetadata.java @@ -225,6 +225,7 @@ import static io.trino.plugin.iceberg.IcebergSessionProperties.isMergeManifestsOnWrite; import static io.trino.plugin.iceberg.IcebergSessionProperties.isProjectionPushdownEnabled; import static io.trino.plugin.iceberg.IcebergSessionProperties.isQueryPartitionFilterRequired; +import static io.trino.plugin.iceberg.IcebergSessionProperties.isQueryPartitionPruningRequired; import static io.trino.plugin.iceberg.IcebergSessionProperties.isStatisticsEnabled; import static io.trino.plugin.iceberg.IcebergTableName.isDataTable; import static io.trino.plugin.iceberg.IcebergTableName.isMaterializedViewStorage; @@ -730,9 +731,11 @@ public void validateScan(ConnectorSession session, ConnectorTableHandle handle) return; } Set columnsWithPredicates = new HashSet<>(); - table.getConstraintColumns().stream() - .map(IcebergColumnHandle::getId) - .forEach(columnsWithPredicates::add); + if (!isQueryPartitionPruningRequired(session)) { + table.getConstraintColumns().stream() + .map(IcebergColumnHandle::getId) + .forEach(columnsWithPredicates::add); + } table.getUnenforcedPredicate().getDomains().ifPresent(domain -> domain.keySet().stream() .map(IcebergColumnHandle::getId) .forEach(columnsWithPredicates::add)); @@ -746,9 +749,12 @@ public void validateScan(ConnectorSession session, ConnectorTableHandle handle) .map(PartitionField::sourceId) .map(id -> schema.idToName().get(id)) .collect(joining(", ")); + + String requiredOption = isQueryPartitionPruningRequired(session) ? "Pruning" : "Filter"; + throw new TrinoException( QUERY_REJECTED, - format("Filter required for %s on at least one of the partition columns: %s", table.getSchemaTableName(), partitionColumnNames)); + format("%s required for %s on at least one of the partition columns: %s", requiredOption, table.getSchemaTableName(), partitionColumnNames)); } } } diff --git a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergSessionProperties.java b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergSessionProperties.java index 613eea702275..5aec65e61068 100644 --- a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergSessionProperties.java +++ b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergSessionProperties.java @@ -93,6 +93,7 @@ public final class IcebergSessionProperties private static final String MERGE_MANIFESTS_ON_WRITE = "merge_manifests_on_write"; private static final String SORTED_WRITING_ENABLED = "sorted_writing_enabled"; private static final String QUERY_PARTITION_FILTER_REQUIRED = "query_partition_filter_required"; + private static final String QUERY_PARTITION_PRUNING_REQUIRED = "query_partition_pruning_required"; private final List> sessionProperties; @@ -327,6 +328,11 @@ public IcebergSessionProperties( "Require filter on partition column", icebergConfig.isQueryPartitionFilterRequired(), false)) + .add(booleanProperty( + QUERY_PARTITION_PRUNING_REQUIRED, + "Require pruning on partition column", + icebergConfig.isQueryPartitionPruningRequired(), + false)) .build(); } @@ -537,4 +543,9 @@ public static boolean isQueryPartitionFilterRequired(ConnectorSession session) { return session.getProperty(QUERY_PARTITION_FILTER_REQUIRED, Boolean.class); } + + public static boolean isQueryPartitionPruningRequired(ConnectorSession session) + { + return session.getProperty(QUERY_PARTITION_PRUNING_REQUIRED, Boolean.class); + } } From 2fe1b44fc4b260cb7448988366011706f05d8835 Mon Sep 17 00:00:00 2001 From: okayhooni Date: Thu, 14 Dec 2023 21:32:39 +0900 Subject: [PATCH 2/3] fix typo and add docs --- docs/src/main/sphinx/connector/iceberg.md | 6 ++++++ .../main/java/io/trino/plugin/iceberg/IcebergConfig.java | 2 +- .../java/io/trino/plugin/iceberg/TestIcebergConfig.java | 7 +++++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/docs/src/main/sphinx/connector/iceberg.md b/docs/src/main/sphinx/connector/iceberg.md index 869be0bbafd9..24b1356232de 100644 --- a/docs/src/main/sphinx/connector/iceberg.md +++ b/docs/src/main/sphinx/connector/iceberg.md @@ -171,6 +171,12 @@ implementation is used: `query_partition_filter_required` catalog session property for temporary, catalog specific use. - `false` +* - `iceberg.query-partition-pruning-required` + - Set to `true` to force a query to use a partition pruning in the query plan. + This can be enabled only with `iceberg.query-partition-filter-required=true`. + You can use the`query_partition_pruning_required` catalog session property, + for temporary catalog specific use. + - `false` ::: ## Type mapping diff --git a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergConfig.java b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergConfig.java index e302a3a576ee..75bb5924e808 100644 --- a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergConfig.java +++ b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergConfig.java @@ -417,7 +417,7 @@ public boolean isQueryPartitionFilterRequired() @Config("iceberg.query-partition-pruning-required") @ConfigDescription("Require a partition pruning on at least one partition column in the query plan. This can be enabled only with iceberg.query-partition-filter-required=true") - public IcebergConfig setQueryPartitionFilterPruningRequired(boolean queryPartitionPruningRequired) + public IcebergConfig setQueryPartitionPruningRequired(boolean queryPartitionPruningRequired) { this.queryPartitionPruningRequired = queryPartitionPruningRequired; return this; diff --git a/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/TestIcebergConfig.java b/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/TestIcebergConfig.java index 4ca2417beba4..b5c896c43c97 100644 --- a/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/TestIcebergConfig.java +++ b/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/TestIcebergConfig.java @@ -66,7 +66,8 @@ public void testDefaults() .setMaterializedViewsStorageSchema(null) .setRegisterTableProcedureEnabled(false) .setSortedWritingEnabled(true) - .setQueryPartitionFilterRequired(false)); + .setQueryPartitionFilterRequired(false) + .setQueryPartitionPruningRequired(false)); } @Test @@ -97,6 +98,7 @@ public void testExplicitPropertyMappings() .put("iceberg.register-table-procedure.enabled", "true") .put("iceberg.sorted-writing-enabled", "false") .put("iceberg.query-partition-filter-required", "true") + .put("iceberg.query-partition-pruning-required", "true") .buildOrThrow(); IcebergConfig expected = new IcebergConfig() @@ -123,7 +125,8 @@ public void testExplicitPropertyMappings() .setMaterializedViewsStorageSchema("mv_storage_schema") .setRegisterTableProcedureEnabled(true) .setSortedWritingEnabled(false) - .setQueryPartitionFilterRequired(true); + .setQueryPartitionFilterRequired(true) + .setQueryPartitionPruningRequired(true); assertFullMapping(properties, expected); } From 90c77f3a2ad132b396c3298ed427cdd10af7a992 Mon Sep 17 00:00:00 2001 From: okayhooni Date: Sat, 16 Dec 2023 04:28:24 +0900 Subject: [PATCH 3/3] implement table level and catalog level mandatory filtering partition fields option --- docs/src/main/sphinx/connector/iceberg.md | 4 + .../trino/plugin/iceberg/IcebergConfig.java | 14 +++ .../trino/plugin/iceberg/IcebergMetadata.java | 90 +++++++++++++------ .../iceberg/IcebergSessionProperties.java | 11 +++ .../plugin/iceberg/TestIcebergConfig.java | 3 + 5 files changed, 96 insertions(+), 26 deletions(-) diff --git a/docs/src/main/sphinx/connector/iceberg.md b/docs/src/main/sphinx/connector/iceberg.md index 24b1356232de..700e3086b73f 100644 --- a/docs/src/main/sphinx/connector/iceberg.md +++ b/docs/src/main/sphinx/connector/iceberg.md @@ -171,6 +171,10 @@ implementation is used: `query_partition_filter_required` catalog session property for temporary, catalog specific use. - `false` +* - `iceberg.query-partition-filter-required-common-fields` + - Comma-separated list of field names to must be used in the filter of queries, + if those fields are the partition fields of each table. + - `null` * - `iceberg.query-partition-pruning-required` - Set to `true` to force a query to use a partition pruning in the query plan. This can be enabled only with `iceberg.query-partition-filter-required=true`. diff --git a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergConfig.java b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergConfig.java index 75bb5924e808..0aadc7905a35 100644 --- a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergConfig.java +++ b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergConfig.java @@ -80,6 +80,7 @@ public class IcebergConfig private boolean sortedWritingEnabled = true; private boolean queryPartitionFilterRequired; private boolean queryPartitionPruningRequired; + private Optional queryPartitionFilterRequiredCommonFields = Optional.empty(); public CatalogType getCatalogType() { @@ -415,6 +416,19 @@ public boolean isQueryPartitionFilterRequired() return queryPartitionFilterRequired; } + public Optional getQueryPartitionFilterRequiredCommonFields() + { + return queryPartitionFilterRequiredCommonFields; + } + + @Config("iceberg.query-partition-filter-required-common-fields") + @ConfigDescription("Require filter predicates on all the partition fields declared in this configuration") + public IcebergConfig setQueryPartitionFilterRequiredCommonFields(String queryPartitionFilterRequiredCommonFields) + { + this.queryPartitionFilterRequiredCommonFields = Optional.ofNullable(queryPartitionFilterRequiredCommonFields); + return this; + } + @Config("iceberg.query-partition-pruning-required") @ConfigDescription("Require a partition pruning on at least one partition column in the query plan. This can be enabled only with iceberg.query-partition-filter-required=true") public IcebergConfig setQueryPartitionPruningRequired(boolean queryPartitionPruningRequired) diff --git a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergMetadata.java b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergMetadata.java index d1b98f4f0d0c..40e5f64cc4cd 100644 --- a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergMetadata.java +++ b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergMetadata.java @@ -186,6 +186,7 @@ import java.util.function.UnaryOperator; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Stream; import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.common.base.Preconditions.checkArgument; @@ -219,6 +220,7 @@ import static io.trino.plugin.iceberg.IcebergMetadataColumn.isMetadataColumnId; import static io.trino.plugin.iceberg.IcebergSessionProperties.getExpireSnapshotMinRetention; import static io.trino.plugin.iceberg.IcebergSessionProperties.getHiveCatalogName; +import static io.trino.plugin.iceberg.IcebergSessionProperties.getQueryPartitionFilterRequiredCommonFields; import static io.trino.plugin.iceberg.IcebergSessionProperties.getRemoveOrphanFilesMinRetention; import static io.trino.plugin.iceberg.IcebergSessionProperties.isCollectExtendedStatisticsOnWrite; import static io.trino.plugin.iceberg.IcebergSessionProperties.isExtendedStatisticsEnabled; @@ -313,6 +315,7 @@ public class IcebergMetadata public static final String ORC_BLOOM_FILTER_COLUMNS_KEY = "orc.bloom.filter.columns"; public static final String ORC_BLOOM_FILTER_FPP_KEY = "orc.bloom.filter.fpp"; + public static final String QUERY_PARTITION_FILTER_REQUIRED_FIELDS_CONFIG_KEY = "trino.query-partition-filter-required.fields"; public static final String NUMBER_OF_DISTINCT_VALUES_NAME = "NUMBER_OF_DISTINCT_VALUES"; private static final FunctionName NUMBER_OF_DISTINCT_VALUES_FUNCTION = new FunctionName(IcebergThetaSketchForStats.NAME); @@ -723,40 +726,75 @@ public ColumnMetadata getColumnMetadata(ConnectorSession session, ConnectorTable public void validateScan(ConnectorSession session, ConnectorTableHandle handle) { IcebergTableHandle table = (IcebergTableHandle) handle; - if (isQueryPartitionFilterRequired(session) && table.getEnforcedPredicate().isAll() && !table.getForAnalyze().orElseThrow()) { - Schema schema = SchemaParser.fromJson(table.getTableSchemaJson()); - Optional partitionSpec = table.getPartitionSpecJson() - .map(partitionSpecJson -> PartitionSpecParser.fromJson(schema, partitionSpecJson)); - if (partitionSpec.isEmpty() || partitionSpec.get().isUnpartitioned()) { - return; - } - Set columnsWithPredicates = new HashSet<>(); - if (!isQueryPartitionPruningRequired(session)) { - table.getConstraintColumns().stream() - .map(IcebergColumnHandle::getId) - .forEach(columnsWithPredicates::add); - } - table.getUnenforcedPredicate().getDomains().ifPresent(domain -> domain.keySet().stream() + if (!isQueryPartitionFilterRequired(session) || table.getForAnalyze().orElse(false)) { + return; + } + + Schema schema = SchemaParser.fromJson(table.getTableSchemaJson()); + Optional partitionSpec = table.getPartitionSpecJson() + .map(partitionSpecJson -> PartitionSpecParser.fromJson(schema, partitionSpecJson)); + if (partitionSpec.isEmpty() || partitionSpec.get().isUnpartitioned()) { + return; + } + + Supplier> tableAllPartitionColumnIdStreamSupplier = () -> partitionSpec.get().fields().stream() + .filter(field -> !field.transform().isVoid()) + .map(PartitionField::sourceId); + + Set partitionColumns = tableAllPartitionColumnIdStreamSupplier.get() + .collect(toImmutableSet()); + + Set mandatoryFilterPartitionColumnNames = new HashSet<>(); + if (table.getStorageProperties().containsKey(QUERY_PARTITION_FILTER_REQUIRED_FIELDS_CONFIG_KEY)) { + Splitter.on(",").splitToStream(table.getStorageProperties().get(QUERY_PARTITION_FILTER_REQUIRED_FIELDS_CONFIG_KEY)) + .map(String::trim) + .forEach(mandatoryFilterPartitionColumnNames::add); + } + if (getQueryPartitionFilterRequiredCommonFields(session).isPresent()) { + Splitter.on(",").splitToStream(getQueryPartitionFilterRequiredCommonFields(session).get()) + .map(String::trim) + .forEach(mandatoryFilterPartitionColumnNames::add); + } + + Set mandatoryPartitionColumns = tableAllPartitionColumnIdStreamSupplier.get() + .filter(id -> mandatoryFilterPartitionColumnNames.contains(schema.idToName().get(id))) + .collect(toImmutableSet()); + + Set columnsWithPredicates = new HashSet<>(); + if (!isQueryPartitionPruningRequired(session)) { + table.getConstraintColumns().stream() .map(IcebergColumnHandle::getId) - .forEach(columnsWithPredicates::add)); - Set partitionColumns = partitionSpec.get().fields().stream() - .filter(field -> !field.transform().isVoid()) - .map(PartitionField::sourceId) - .collect(toImmutableSet()); - if (Collections.disjoint(columnsWithPredicates, partitionColumns)) { - String partitionColumnNames = partitionSpec.get().fields().stream() - .filter(field -> !field.transform().isVoid()) - .map(PartitionField::sourceId) + .forEach(columnsWithPredicates::add); + } + table.getEnforcedPredicate().getDomains().ifPresent(domain -> domain.keySet().stream() + .map(IcebergColumnHandle::getId) + .forEach(columnsWithPredicates::add)); + table.getUnenforcedPredicate().getDomains().ifPresent(domain -> domain.keySet().stream() + .map(IcebergColumnHandle::getId) + .forEach(columnsWithPredicates::add)); + + String requiredOption = isQueryPartitionPruningRequired(session) ? "Pruning" : "Filter"; + if (!mandatoryPartitionColumns.isEmpty()) { + if (!difference(mandatoryPartitionColumns, columnsWithPredicates).isEmpty()) { + String partitionColumnNames = tableAllPartitionColumnIdStreamSupplier.get() .map(id -> schema.idToName().get(id)) + .filter(mandatoryFilterPartitionColumnNames::contains) .collect(joining(", ")); - String requiredOption = isQueryPartitionPruningRequired(session) ? "Pruning" : "Filter"; - throw new TrinoException( QUERY_REJECTED, - format("%s required for %s on at least one of the partition columns: %s", requiredOption, table.getSchemaTableName(), partitionColumnNames)); + format("%s required for %s on all the mandatory partition columns: %s", requiredOption, table.getSchemaTableName(), partitionColumnNames)); } } + else if (Collections.disjoint(partitionColumns, columnsWithPredicates)) { + String partitionColumnNames = tableAllPartitionColumnIdStreamSupplier.get() + .map(id -> schema.idToName().get(id)) + .collect(joining(", ")); + + throw new TrinoException( + QUERY_REJECTED, + format("%s required for %s on at least one of the partition columns: %s", requiredOption, table.getSchemaTableName(), partitionColumnNames)); + } } @Override diff --git a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergSessionProperties.java b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergSessionProperties.java index 5aec65e61068..01b766d5f9c2 100644 --- a/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergSessionProperties.java +++ b/plugin/trino-iceberg/src/main/java/io/trino/plugin/iceberg/IcebergSessionProperties.java @@ -93,6 +93,7 @@ public final class IcebergSessionProperties private static final String MERGE_MANIFESTS_ON_WRITE = "merge_manifests_on_write"; private static final String SORTED_WRITING_ENABLED = "sorted_writing_enabled"; private static final String QUERY_PARTITION_FILTER_REQUIRED = "query_partition_filter_required"; + private static final String QUERY_PARTITION_FILTER_REQUIRED_COMMON_FIELDS = "query-partition-filter-required-common-fields"; private static final String QUERY_PARTITION_PRUNING_REQUIRED = "query_partition_pruning_required"; private final List> sessionProperties; @@ -328,6 +329,11 @@ public IcebergSessionProperties( "Require filter on partition column", icebergConfig.isQueryPartitionFilterRequired(), false)) + .add(stringProperty( + QUERY_PARTITION_FILTER_REQUIRED_COMMON_FIELDS, + "Require filter predicates on all the partition fields declared in this configuration", + icebergConfig.getQueryPartitionFilterRequiredCommonFields().orElse(null), + false)) .add(booleanProperty( QUERY_PARTITION_PRUNING_REQUIRED, "Require pruning on partition column", @@ -544,6 +550,11 @@ public static boolean isQueryPartitionFilterRequired(ConnectorSession session) return session.getProperty(QUERY_PARTITION_FILTER_REQUIRED, Boolean.class); } + public static Optional getQueryPartitionFilterRequiredCommonFields(ConnectorSession session) + { + return Optional.ofNullable(session.getProperty(QUERY_PARTITION_FILTER_REQUIRED_COMMON_FIELDS, String.class)); + } + public static boolean isQueryPartitionPruningRequired(ConnectorSession session) { return session.getProperty(QUERY_PARTITION_PRUNING_REQUIRED, Boolean.class); diff --git a/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/TestIcebergConfig.java b/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/TestIcebergConfig.java index b5c896c43c97..0ffe029023ae 100644 --- a/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/TestIcebergConfig.java +++ b/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/TestIcebergConfig.java @@ -67,6 +67,7 @@ public void testDefaults() .setRegisterTableProcedureEnabled(false) .setSortedWritingEnabled(true) .setQueryPartitionFilterRequired(false) + .setQueryPartitionFilterRequiredCommonFields(null) .setQueryPartitionPruningRequired(false)); } @@ -98,6 +99,7 @@ public void testExplicitPropertyMappings() .put("iceberg.register-table-procedure.enabled", "true") .put("iceberg.sorted-writing-enabled", "false") .put("iceberg.query-partition-filter-required", "true") + .put("iceberg.query-partition-filter-required-common-fields", "log_ts,timestamp") .put("iceberg.query-partition-pruning-required", "true") .buildOrThrow(); @@ -126,6 +128,7 @@ public void testExplicitPropertyMappings() .setRegisterTableProcedureEnabled(true) .setSortedWritingEnabled(false) .setQueryPartitionFilterRequired(true) + .setQueryPartitionFilterRequiredCommonFields("log_ts,timestamp") .setQueryPartitionPruningRequired(true); assertFullMapping(properties, expected);