Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,7 @@ private SparkSQLProperties() {}
// Controls whether to report available column statistics to Spark for query optimization.
public static final String REPORT_COLUMN_STATS = "spark.sql.iceberg.report-column-stats";
public static final boolean REPORT_COLUMN_STATS_DEFAULT = true;

// Prefix for custom snapshot properties
public static final String SNAPSHOT_PROPERTY_PREFIX = "spark.sql.iceberg.snapshot-property.";
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,14 @@
import org.apache.iceberg.relocated.com.google.common.annotations.VisibleForTesting;
import org.apache.iceberg.relocated.com.google.common.base.Preconditions;
import org.apache.iceberg.relocated.com.google.common.collect.Maps;
import org.apache.iceberg.util.PropertyUtil;
import org.apache.spark.sql.RuntimeConfig;
import org.apache.spark.sql.SparkSession;
import org.apache.spark.sql.connector.write.RowLevelOperation.Command;
import org.apache.spark.sql.internal.SQLConf;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import scala.collection.JavaConverters;

/**
* A class for common Iceberg configs for Spark writes.
Expand Down Expand Up @@ -252,6 +254,13 @@ public long targetDeleteFileSize() {
public Map<String, String> extraSnapshotMetadata() {
Map<String, String> extraSnapshotMetadata = Maps.newHashMap();

// Add session configuration properties with SNAPSHOT_PROPERTY_PREFIX if necessary
extraSnapshotMetadata.putAll(
PropertyUtil.propertiesWithPrefix(
JavaConverters.mapAsJavaMap(sessionConf.getAll()),
SparkSQLProperties.SNAPSHOT_PROPERTY_PREFIX));

// Add write options, overriding session configuration if necessary
writeOptions.forEach(
(key, value) -> {
if (key.startsWith(SnapshotSummary.EXTRA_METADATA_PREFIX)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,37 @@ public void testSparkConfOverride() {
}
}

@TestTemplate
public void testExtraSnapshotMetadataReflectsSessionConfig() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we add a E2E test which verifies that when this is set the snapshot created actually persists the given property as snapshot property ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the comment (and sorry for the late reply). Added a E2E test testExtraSnapshotMetadataPersistedOnWrite for this purpose.

withSQLConf(
ImmutableMap.of("spark.sql.iceberg.snapshot-property.test-key", "session-value"),
() -> {
Table table = validationCatalog.loadTable(tableIdent);
SparkWriteConf writeConf = new SparkWriteConf(spark, table, ImmutableMap.of());

Map<String, String> metadata = writeConf.extraSnapshotMetadata();

assertThat(metadata).containsEntry("test-key", "session-value");
});
}

@TestTemplate
public void testExtraSnapshotMetadataWriteOptionsOverrideSessionConfig() {
withSQLConf(
ImmutableMap.of("spark.sql.iceberg.snapshot-property.test-key", "session-value"),
() -> {
Table table = validationCatalog.loadTable(tableIdent);
Map<String, String> writeOptions =
ImmutableMap.of("snapshot-property.test-key", "write-option-value");
SparkWriteConf writeConf = new SparkWriteConf(spark, table, writeOptions);

Map<String, String> metadata = writeConf.extraSnapshotMetadata();

// Assert that writeOptions take precedence over session config
assertThat(metadata).containsEntry("test-key", "write-option-value");
});
}

@TestTemplate
public void testDataPropsDefaultsAsDeleteProps() {
List<List<Map<String, String>>> propertiesSuites =
Expand Down