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 7e71d9423 fix(view): copy inputs when creating v1 versions (#2274)
7e71d9423 is described below

commit 7e71d94239c79913c856c3830b8bcaf14851c029
Author: Minh Vu <[email protected]>
AuthorDate: Fri Oct 23 18:36:55 2026 +0200

    fix(view): copy inputs when creating v1 versions (#2274)
    
    * fix(view): copy v1 view version constructor inputs
    
    Copy the supplied representations and default namespace so caller mutations
    cannot change an already validated view version.
    
    Signed-off-by: Minh Vu <[email protected]>
    
    * test(view): match representation slice type in copy assertion
    
    ---------
    
    Signed-off-by: Minh Vu <[email protected]>
---
 view/metadata.go              |  6 ++++--
 view/metadata_builder_test.go | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/view/metadata.go b/view/metadata.go
index 872694271..2c0af1c1a 100644
--- a/view/metadata.go
+++ b/view/metadata.go
@@ -159,6 +159,8 @@ func WithTimestampMS(timestampMS int64) VersionOpt {
 }
 
 // NewVersion creates a Version instance from the provided parameters.
+// It copies the representations and namespace so later changes to the inputs
+// cannot modify the returned version.
 // If building updates using the MetadataBuilder, and one desires to use the 
last
 // added schema ID, one should use the LastAddedID constant as the provided 
schemaID
 //
@@ -188,10 +190,10 @@ func NewVersion(id int64, schemaID int, representations 
[]Representation, defaul
        version := &Version{
                VersionID:        id,
                SchemaID:         schemaID,
-               Representations:  representations,
+               Representations:  slices.Clone(representations),
                Summary:          VersionSummary{viewEngineProperty: 
defaultViewEngine},
                TimestampMS:      time.Now().UnixMilli(),
-               DefaultNamespace: defaultNS,
+               DefaultNamespace: slices.Clone(defaultNS),
        }
 
        for _, opt := range opts {
diff --git a/view/metadata_builder_test.go b/view/metadata_builder_test.go
index 753bed0df..b9c1d9066 100644
--- a/view/metadata_builder_test.go
+++ b/view/metadata_builder_test.go
@@ -246,6 +246,45 @@ func TestNewVersion_RepresentationValidation(t *testing.T) 
{
        }
 }
 
+func TestNewVersionCopiesInputSlices(t *testing.T) {
+       representations := Representations{
+               NewRepresentation("SELECT 1", "spark"),
+               NewRepresentation("SELECT 2", "trino"),
+       }
+       defaultNS := table.Identifier{"analytics", "reporting"}
+
+       version, err := NewVersion(1, 0, representations, defaultNS)
+       require.NoError(t, err)
+
+       // These mutations would otherwise change an already validated version,
+       // including making the representation dialects duplicate.
+       representations[0].Sql = "SELECT changed"
+       representations[1].Dialect = "spark"
+       defaultNS[0] = "other"
+       defaultNS[1] = "schema"
+
+       assert.Equal(t, []Representation{
+               NewRepresentation("SELECT 1", "spark"),
+               NewRepresentation("SELECT 2", "trino"),
+       }, version.Representations)
+       assert.Equal(t, table.Identifier{"analytics", "reporting"}, 
version.DefaultNamespace)
+
+       // Neither side should share the backing storage with the other.
+       version.Representations[0].Sql = "SELECT from version"
+       version.DefaultNamespace[0] = "version"
+       assert.Equal(t, "SELECT changed", representations[0].Sql)
+       assert.Equal(t, "other", defaultNS[0])
+}
+
+func TestNewVersionFromSQLCopiesNamespace(t *testing.T) {
+       defaultNS := table.Identifier{"analytics"}
+       version, err := NewVersionFromSQL(1, 0, "SELECT 1", defaultNS)
+       require.NoError(t, err)
+
+       defaultNS[0] = "other"
+       assert.Equal(t, table.Identifier{"analytics"}, version.DefaultNamespace)
+}
+
 func TestAddVersion_InvalidRepresentation_Validation(t *testing.T) {
        invalidVersion := &Version{
                VersionID: 1,

Reply via email to