You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iceberg.apache.org by ze...@apache.org on 2026/06/08 20:00:28 UTC

(iceberg-go) branch main updated: fix(table): preserve table props when building partition location provider (#1155) (#1162)

This is an automated email from the ASF dual-hosted git repository.

zeroshade pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg-go.git


The following commit(s) were added to refs/heads/main by this push:
     new 38e98b00 fix(table): preserve table props when building partition location provider (#1155) (#1162)
38e98b00 is described below

commit 38e98b009f19c784c4ae8a0a762d6c424560f171
Author: Tanmay Rauth <t_...@apple.com>
AuthorDate: Tue Jun 9 01:30:22 2026 +0530

    fix(table): preserve table props when building partition location provider (#1155) (#1162)
    
    writerFactory.partitionLocProvider was passing only WriteDataPathKey to
    LoadLocationProvider, dropping write.object-storage.enabled and other
    table props. As a result, partitioned writes always fell back to the
    simple Hadoop-style layout, ignoring the object-storage entropy prefix.
    
    Store the table props on the factory and copy them when constructing
    partition props, overlaying only the partition-specific data path.
    
    Fixes: #1155
---
 table/rolling_data_writer.go      |  9 +++++--
 table/rolling_data_writer_test.go | 52 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+), 2 deletions(-)

diff --git a/table/rolling_data_writer.go b/table/rolling_data_writer.go
index a5d09e97..a8fe795e 100644
--- a/table/rolling_data_writer.go
+++ b/table/rolling_data_writer.go
@@ -21,6 +21,7 @@ import (
 	"context"
 	"fmt"
 	"iter"
+	"maps"
 	"net/url"
 	"strings"
 	"sync"
@@ -45,6 +46,7 @@ type writerFactory struct {
 	targetFileSize int64
 
 	locProvider      LocationProvider
+	tableProps       iceberg.Properties
 	fileSchema       *iceberg.Schema
 	arrowSchema      *arrow.Schema
 	writeProps       any
@@ -152,6 +154,7 @@ func newWriterFactory(rootLocation string, args recordWritingArgs, meta *Metadat
 		taskSchema:     taskSchema,
 		targetFileSize: targetFileSize,
 		locProvider:    locProvider,
+		tableProps:     meta.props,
 		fileSchema:     fileSchema,
 		arrowSchema:    arrowSchema,
 		writeProps:     format.GetWriteProperties(meta.props),
@@ -219,8 +222,10 @@ func (w *writerFactory) partitionLocProvider(partitionPath string) (LocationProv
 	}
 
 	partitionDataPath := w.rootURL.JoinPath("data", partitionPath).String()
-	loc, err := LoadLocationProvider(w.rootLocation,
-		iceberg.Properties{WriteDataPathKey: partitionDataPath})
+	partitionProps := make(iceberg.Properties, len(w.tableProps)+1)
+	maps.Copy(partitionProps, w.tableProps)
+	partitionProps[WriteDataPathKey] = partitionDataPath
+	loc, err := LoadLocationProvider(w.rootLocation, partitionProps)
 	if err != nil {
 		return nil, err
 	}
diff --git a/table/rolling_data_writer_test.go b/table/rolling_data_writer_test.go
index 27a97f04..a3f06b68 100644
--- a/table/rolling_data_writer_test.go
+++ b/table/rolling_data_writer_test.go
@@ -400,3 +400,55 @@ func (s *RollingDataWriterTestSuite) TestBytesWrittenReflectsCompressedSize() {
 	s.Require().NoError(err)
 	s.Equal(int64(100), df.Count())
 }
+
+// TestPartitionLocProviderPreservesObjectStorageProps reproduces #1155: when
+// write.object-storage.enabled is true on a partitioned table, partition data
+// file paths must include entropy hash dirs from objectStoreLocationProvider.
+// Previously partitionLocProvider rebuilt props with only WriteDataPathKey, so
+// LoadLocationProvider fell back to simpleLocationProvider for partitions.
+func (s *RollingDataWriterTestSuite) TestPartitionLocProviderPreservesObjectStorageProps() {
+	arrSchema := arrow.NewSchema([]arrow.Field{
+		{Name: "id", Type: arrow.PrimitiveTypes.Int32, Nullable: true},
+		{Name: "name", Type: arrow.BinaryTypes.String, Nullable: true},
+	}, nil)
+
+	icebergSchema, err := ArrowSchemaToIcebergWithFreshIDs(arrSchema, false)
+	s.Require().NoError(err)
+
+	spec := iceberg.NewPartitionSpec()
+	loc := "table_location"
+	meta, err := NewMetadata(icebergSchema, &spec, UnsortedSortOrder, loc, iceberg.Properties{
+		ObjectStoreEnabledKey: "true",
+	})
+	s.Require().NoError(err)
+	metaBuilder, err := MetadataBuilderFromBase(meta, "")
+	s.Require().NoError(err)
+
+	writeUUID := uuid.New()
+	args := recordWritingArgs{
+		sc:        arrSchema,
+		fs:        iceio.LocalFS{},
+		writeUUID: &writeUUID,
+		counter: func(yield func(int) bool) {
+			for i := 0; ; i++ {
+				if !yield(i) {
+					break
+				}
+			}
+		},
+	}
+	factory, err := newWriterFactory(loc, args, metaBuilder, icebergSchema, 1024*1024)
+	s.Require().NoError(err)
+	defer factory.closeAll()
+
+	provider, err := factory.partitionLocProvider("dt=2026-06-04")
+	s.Require().NoError(err)
+	_, ok := provider.(*objectStoreLocationProvider)
+	s.True(ok, "expected objectStoreLocationProvider for partitioned writes when write.object-storage.enabled=true")
+
+	// Hashed prefix should appear before the file name for object storage layout.
+	dataLoc := provider.NewDataLocation("a")
+	s.Contains(dataLoc, "table_location/data/dt=2026-06-04/")
+	s.NotEqual("table_location/data/dt=2026-06-04/a", dataLoc,
+		"object storage layout should inject an entropy hash prefix between partition dir and file")
+}