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/10/23 16:37:01 UTC
(iceberg-go) branch main updated: fix(view): copy inputs when creating v1 versions (#2274)
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 <vu...@gmail.com>
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 <vu...@gmail.com>
* test(view): match representation slice type in copy assertion
---------
Signed-off-by: Minh Vu <vu...@gmail.com>
---
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,