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

laskoviymishka 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 96acf3731 build: bump minimum Go version to 1.26 (#2077)
96acf3731 is described below

commit 96acf3731636165ad0f4ae431bb9589e3a360cf2
Author: Matt Topol <[email protected]>
AuthorDate: Wed Sep 30 15:12:42 2026 -0400

    build: bump minimum Go version to 1.26 (#2077)
    
    * fix(puffin): report LZ4 read errors when footer decoder stops early
    
    Since Go 1.27, encoding/json's Decoder.More returns true on non-EOF read
    errors, so a corrupted compressed footer surfaced as "unexpected content
    after footer JSON" instead of the underlying LZ4 checksum error.
    
    * build: bump minimum Go version to 1.26
    
    - go.mod: go 1.26.0
    - CI: test matrix 1.26.8 / 1.27.1; cross-compile and Arrow assertions on
      1.27.1; integration on 1.26
    - golangci-lint v2.14.0 (v2.12.2 is built with go1.26 and panics on the
      Go 1.27 stdlib)
    - apply modernize fixes enabled by go 1.26 (errors.AsType, new(expr),
      reflect iterators) and drop the now-redundant pointer helpers
    - docs: Go 1.26 or later
---
 .github/workflows/go-ci.yml                        |   8 +-
 .github/workflows/go-integration.yml               |   2 +-
 .pre-commit-config.yaml                            |   2 +-
 Makefile                                           |   2 +-
 README.md                                          |   4 +-
 catalog/glue/glue.go                               |   6 +-
 catalog/hive/hive.go                               |   3 +-
 catalog/rest/auth.go                               |   3 +-
 catalog/rest/scan_planning.go                      |   3 +-
 catalog/rest/scan_planning_parity_test.go          |  10 +-
 catalog/rest/scan_planning_retry.go                |   3 +-
 catalog/rest/scan_planning_test.go                 |  11 +-
 catalog/rest/scan_task_decoder_bench_test.go       |   6 +-
 catalog/rest/scan_task_decoder_test.go             |  32 ++--
 catalog/rest/wait_for_plan_test.go                 |   2 +-
 catalog/sql/sql.go                                 |   3 +-
 cmd/iceberg/upgrade_rollback_test.go               |  16 +-
 codec/data_file_test.go                            |   4 +-
 go.mod                                             |   2 +-
 literals.go                                        |   9 +-
 manifest.go                                        |   2 +-
 manifest_test.go                                   |   4 +-
 name_mapping_test.go                               | 210 ++++++++++-----------
 partitions.go                                      |   3 +-
 puffin/puffin_reader.go                            |  15 +-
 table/arrow_utils.go                               |   3 +-
 table/arrow_utils_test.go                          |  46 +++--
 table/dv/deletion_vector_bench_test.go             |   2 +-
 table/dv/deletion_vector_test.go                   |  18 +-
 table/dv_scan_planning_test.go                     |  75 ++++----
 table/dv_scanner_read_test.go                      |  14 +-
 table/incremental_append_scan_test.go              |  12 +-
 table/incremental_changelog_scan_test.go           |  20 +-
 table/inspect_internal_test.go                     |  38 ++--
 table/metadata_builder_internal_test.go            |   8 +-
 table/pos_delete_partitioned_fanout_writer_test.go |   4 -
 table/rebuild_manifest_test.go                     |   6 +-
 table/requirement_test.go                          |  12 +-
 table/scan_metrics_test.go                         |  10 +-
 table/scan_planning.go                             |   2 +-
 table/scanner_empty_manifest_bench_test.go         |   2 +-
 table/scanner_manifest_entries_bench_test.go       |   6 +-
 table/snapshot_producers.go                        |  24 +--
 table/snapshot_producers_test.go                   |   6 +-
 table/snapshots_test.go                            |  22 +--
 table/sorting.go                                   |   3 +-
 table/substrait/substrait.go                       |   3 +-
 table/transaction_internal_test.go                 |  30 ++-
 website/src/install.md                             |   2 +-
 49 files changed, 353 insertions(+), 380 deletions(-)

diff --git a/.github/workflows/go-ci.yml b/.github/workflows/go-ci.yml
index aceeb3f5f..b17433228 100644
--- a/.github/workflows/go-ci.yml
+++ b/.github/workflows/go-ci.yml
@@ -46,7 +46,7 @@ jobs:
       max-parallel: 15
       fail-fast: false
       matrix:
-        go: [ '1.25.9', '1.26.1' ]
+        go: [ '1.26.8', '1.27.1' ]
         os:
           - 'ubuntu-latest'
           - 'macos-latest'
@@ -83,7 +83,7 @@ jobs:
     - name: Run golangci-lint
       uses: 
golangci/golangci-lint-action@ba0d7d2ec06a0ea1cb5fa41b2e4a3ab91d21278a # v9.3.0
       with:
-        version: v2.12.2
+        version: v2.14.0
         args: --timeout=10m
         # The action's own cache key omits the Go version, so all matrix cells
         # collide on one entry; we manage the cache explicitly above instead.
@@ -91,7 +91,7 @@ jobs:
     - name: Run tests with race detector 
       run: make test-race
     - name: Run Arrow ownership assertions
-      if: matrix.os == 'ubuntu-latest' && matrix.go == '1.26.1'
+      if: matrix.os == 'ubuntu-latest' && matrix.go == '1.27.1'
       run: make test-assert
     - name: Save Go module and build cache
       if: github.ref == 'refs/heads/main'
@@ -126,7 +126,7 @@ jobs:
     - name: Install Go
       uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
       with:
-        go-version: '1.26.1'
+        go-version: '1.27.1'
         cache: false
     - name: Restore Go module and build cache
       uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # 
v6.1.0
diff --git a/.github/workflows/go-integration.yml 
b/.github/workflows/go-integration.yml
index 5e77bd377..bf5e15926 100644
--- a/.github/workflows/go-integration.yml
+++ b/.github/workflows/go-integration.yml
@@ -51,7 +51,7 @@ jobs:
       - name: Install Go
         uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # 
v7.0.0
         with:
-          go-version: 1.25
+          go-version: '1.26'
           # Caching managed explicitly below so saves can be gated to main.
           cache: false
 
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 40eaa759f..61b51a7d4 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -17,7 +17,7 @@
 ---
 repos:
   - repo: https://github.com/golangci/golangci-lint
-    rev: v2.12.2
+    rev: v2.14.0
     hooks:
       - id: golangci-lint
         entry: bash -c 'golangci-lint run --fix --timeout 5m'
diff --git a/Makefile b/Makefile
index 741393ac7..2e49d69be 100644
--- a/Makefile
+++ b/Makefile
@@ -15,7 +15,7 @@
 # limitations under the License.
 
 # golangci-lint version (keep in sync with CI and README)
-GOLANGCI_LINT_VERSION := v2.12.2
+GOLANGCI_LINT_VERSION := v2.14.0
 
 .PHONY: test test-assert test-race lint lint-install integration-setup 
integration-setup-spark4 integration-test integration-scanner integration-io 
integration-rest integration-rest-scan-planning integration-spark 
integration-hadoop integration-down integration-logs docs-gen
 
diff --git a/README.md b/README.md
index 23414a28b..01ec83776 100644
--- a/README.md
+++ b/README.md
@@ -25,7 +25,7 @@
 
 ### Prerequisites
 
-* Go 1.25 or later
+* Go 1.26 or later
 
 ### Build
 
@@ -54,7 +54,7 @@ Install the linter first
 
 ```shell
 make lint-install
-# or: go install github.com/golangci/golangci-lint/v2/cmd/[email protected]
+# or: go install github.com/golangci/golangci-lint/v2/cmd/[email protected]
 ```
 
 ### Integration tests
diff --git a/catalog/glue/glue.go b/catalog/glue/glue.go
index d33abd274..db4fe7481 100644
--- a/catalog/glue/glue.go
+++ b/catalog/glue/glue.go
@@ -848,8 +848,7 @@ func (c *Catalog) getRawTable(ctx context.Context, 
database, tableName string) (
                },
        )
        if err != nil {
-               var notFoundErr *types.EntityNotFoundException
-               if errors.As(err, &notFoundErr) {
+               if _, ok := errors.AsType[*types.EntityNotFoundException](err); 
ok {
                        return nil, fmt.Errorf("failed to get table %s.%s: %w", 
database, tableName, catalog.ErrNoSuchTable)
                }
 
@@ -924,8 +923,7 @@ func (c *Catalog) convertGlueToIceberg(ctx context.Context, 
glueTable *types.Tab
 func (c *Catalog) getDatabase(ctx context.Context, databaseName string) 
(*types.Database, error) {
        database, err := c.glueSvc.GetDatabase(ctx, 
&glue.GetDatabaseInput{CatalogId: c.catalogId, Name: aws.String(databaseName)})
        if err != nil {
-               var notFoundErr *types.EntityNotFoundException
-               if errors.As(err, &notFoundErr) {
+               if _, ok := errors.AsType[*types.EntityNotFoundException](err); 
ok {
                        return nil, fmt.Errorf("failed to get namespace %s: 
%w", databaseName, catalog.ErrNoSuchNamespace)
                }
 
diff --git a/catalog/hive/hive.go b/catalog/hive/hive.go
index af4e206fb..8bcf9e77f 100644
--- a/catalog/hive/hive.go
+++ b/catalog/hive/hive.go
@@ -1032,8 +1032,7 @@ func isNoSuchObjectError(err error) bool {
                return false
        }
 
-       var noSuchObjectErr *hive_metastore.NoSuchObjectException
-       if errors.As(err, &noSuchObjectErr) {
+       if _, ok := errors.AsType[*hive_metastore.NoSuchObjectException](err); 
ok {
                return true
        }
 
diff --git a/catalog/rest/auth.go b/catalog/rest/auth.go
index 97a8c7ca8..79db6534e 100644
--- a/catalog/rest/auth.go
+++ b/catalog/rest/auth.go
@@ -76,8 +76,7 @@ func (o *Oauth2AuthManager) AuthHeaderWithContext(ctx 
context.Context) (string,
 func (o *Oauth2AuthManager) authHeader() (string, string, error) {
        tok, err := o.tokenSource.Token()
        if err != nil {
-               var re *oauth2.RetrieveError
-               if errors.As(err, &re) {
+               if re, ok := errors.AsType[*oauth2.RetrieveError](err); ok {
                        return "", "", oauthError{
                                code: re.ErrorCode,
                                desc: re.ErrorDescription,
diff --git a/catalog/rest/scan_planning.go b/catalog/rest/scan_planning.go
index b8c974651..3ae6b6d70 100644
--- a/catalog/rest/scan_planning.go
+++ b/catalog/rest/scan_planning.go
@@ -893,8 +893,7 @@ func (r *Catalog) WaitForPlan(ctx context.Context, ident 
table.Identifier, planI
 // ErrServiceUnavailable preserves compatibility with callers or transports 
that
 // return the sentinel without the package's concrete errorResponse wrapper.
 func scanPlanPollRetry(err error) (time.Duration, bool) {
-       var restErr errorResponse
-       if errors.As(err, &restErr) {
+       if restErr, ok := errors.AsType[errorResponse](err); ok {
                switch restErr.statusCode {
                case http.StatusRequestTimeout,
                        http.StatusTooManyRequests,
diff --git a/catalog/rest/scan_planning_parity_test.go 
b/catalog/rest/scan_planning_parity_test.go
index 526f9ff52..98f60d13b 100644
--- a/catalog/rest/scan_planning_parity_test.go
+++ b/catalog/rest/scan_planning_parity_test.go
@@ -182,7 +182,7 @@ func newPlanningParityTable(t *testing.T) (table.Metadata, 
*iceio.MemFS) {
                b.SplitOffsets([]int64{4, 40, 70})
                b.LowerBoundValues(map[int][]byte{2: 
lo}).UpperBoundValues(map[int][]byte{2: hi})
                b.ValueCounts(map[int]int64{1: 10, 2: 
10}).NullValueCounts(map[int]int64{1: 0, 2: 0})
-               entries = append(entries, 
iceberg.NewManifestEntryBuilder(iceberg.EntryStatusADDED, parityPtr(int64(10)), 
b.Build()).SequenceNum(1).Build())
+               entries = append(entries, 
iceberg.NewManifestEntryBuilder(iceberg.EntryStatusADDED, new(int64(10)), 
b.Build()).SequenceNum(1).Build())
        }
        var data bytes.Buffer
        mf, err := iceberg.WriteManifest("mem://parity/data.avro", &data, 2, 
spec, schema, 10, entries)
@@ -202,7 +202,7 @@ func newPlanningParityTable(t *testing.T) (table.Metadata, 
*iceio.MemFS) {
                        if content == iceberg.EntryContentEqDeletes {
                                b.EqualityFieldIDs([]int{2})
                        }
-                       require.NoError(t, 
writer.Add(iceberg.NewManifestEntryBuilder(iceberg.EntryStatusADDED, 
parityPtr(int64(20)), b.Build()).SequenceNum(2).Build()))
+                       require.NoError(t, 
writer.Add(iceberg.NewManifestEntryBuilder(iceberg.EntryStatusADDED, 
new(int64(20)), b.Build()).SequenceNum(2).Build()))
                }
        }
        require.NoError(t, writer.Close())
@@ -221,7 +221,7 @@ func newPlanningParityTable(t *testing.T) (table.Metadata, 
*iceio.MemFS) {
                path := fmt.Sprintf("mem://parity/list-%d.avro", snapshotID)
                var parentSnapshotID *int64
                if i == 1 {
-                       parentSnapshotID = parityPtr(int64(10))
+                       parentSnapshotID = new(int64(10))
                }
                var list bytes.Buffer
                require.NoError(t, iceberg.WriteManifestList(2, &list, 
snapshotID, parentSnapshotID, &seq, 0, manifests))
@@ -233,7 +233,7 @@ func newPlanningParityTable(t *testing.T) (table.Metadata, 
*iceio.MemFS) {
                }
                require.NoError(t, builder.AddSnapshot(&table.Snapshot{
                        SnapshotID: snapshotID, ParentSnapshotID: 
parentSnapshotID, SequenceNumber: seq,
-                       TimestampMs: time.Now().UnixMilli() + int64(i+1), 
ManifestList: path, SchemaID: parityPtr(0),
+                       TimestampMs: time.Now().UnixMilli() + int64(i+1), 
ManifestList: path, SchemaID: new(0),
                }))
        }
        require.NoError(t, builder.SetSnapshotRef("main", 20, table.BranchRef))
@@ -527,8 +527,6 @@ func parityDeletes(files []iceberg.DataFile) []parityDelete 
{
        return out
 }
 
-func parityPtr[T any](v T) *T { return &v }
-
 // Local residuals are already bound; wire residuals and the original filter
 // are unbound. Preserve the former and bind the latter without a JSON round
 // trip, so the comparison does not normalize through the codec under test.
diff --git a/catalog/rest/scan_planning_retry.go 
b/catalog/rest/scan_planning_retry.go
index 79ace6471..c3fc47f49 100644
--- a/catalog/rest/scan_planning_retry.go
+++ b/catalog/rest/scan_planning_retry.go
@@ -44,8 +44,7 @@ func retryScanPlanning[T any](ctx context.Context, operation 
string, request fun
                        return zero, err
                }
                result, err := request()
-               var responseError errorResponse
-               if !errors.As(err, &responseError) {
+               if _, ok := errors.AsType[errorResponse](err); !ok {
                        return result, err
                }
                retryAfter, retryable := scanPlanPollRetry(err)
diff --git a/catalog/rest/scan_planning_test.go 
b/catalog/rest/scan_planning_test.go
index 093eca2cd..bf049a8ff 100644
--- a/catalog/rest/scan_planning_test.go
+++ b/catalog/rest/scan_planning_test.go
@@ -448,13 +448,13 @@ func TestPlanTableScanRequest(t *testing.T) {
                        name:       "completed",
                        response:   
`{"status":"completed","plan-id":"plan-1","plan-tasks":["task-1"]}`,
                        wantStatus: PlanStatusCompleted,
-                       wantPlanID: stringPtr("plan-1"),
+                       wantPlanID: new("plan-1"),
                },
                {
                        name:       "submitted",
                        response:   `{"status":"submitted","plan-id":"plan-2"}`,
                        wantStatus: PlanStatusSubmitted,
-                       wantPlanID: stringPtr("plan-2"),
+                       wantPlanID: new("plan-2"),
                },
                {
                        name:       "failed",
@@ -957,8 +957,6 @@ func writeRESTNotFound(t *testing.T, w http.ResponseWriter, 
errType string) {
        require.NoError(t, err)
 }
 
-func stringPtr(s string) *string { return &s }
-
 // TestPlanTableScanRequestFromEncodesFilter checks the row filter serializes 
to
 // ExpressionParser JSON on the wire request, and that trivial filters are
 // dropped so the server plans without one.
@@ -1059,8 +1057,9 @@ func scanFilterSchema() *iceberg.Schema {
 // encoding needs.
 type scanTestMetadata struct{ schema *iceberg.Schema }
 
-func (m scanTestMetadata) CurrentSchema() *iceberg.Schema               { 
return m.schema }
-func (m scanTestMetadata) Schemas() []*iceberg.Schema                   { 
return []*iceberg.Schema{m.schema} }
+func (m scanTestMetadata) CurrentSchema() *iceberg.Schema { return m.schema }
+func (m scanTestMetadata) Schemas() []*iceberg.Schema     { return 
[]*iceberg.Schema{m.schema} }
+
 func (m scanTestMetadata) PartitionSpec() iceberg.PartitionSpec         { 
return iceberg.PartitionSpec{} }
 func (m scanTestMetadata) PartitionSpecByID(int) *iceberg.PartitionSpec { 
return nil }
 func (m scanTestMetadata) CurrentSnapshot() *table.Snapshot             { 
return nil }
diff --git a/catalog/rest/scan_task_decoder_bench_test.go 
b/catalog/rest/scan_task_decoder_bench_test.go
index b22d56951..c7130484d 100644
--- a/catalog/rest/scan_task_decoder_bench_test.go
+++ b/catalog/rest/scan_task_decoder_bench_test.go
@@ -59,8 +59,8 @@ func deletionVectorScanTasksWire(taskCount int, explicitOwner 
bool) ScanTasks {
        dataFile := *base.FileScanTasks[0].DataFile
        deleteFile := base.DeleteFiles[0]
        deleteFile.FileFormat = "puffin"
-       deleteFile.ContentOffset = int64Ptr(10)
-       deleteFile.ContentSizeInBytes = int64Ptr(20)
+       deleteFile.ContentOffset = new(int64(10))
+       deleteFile.ContentSizeInBytes = new(int64(20))
 
        wire := ScanTasks{
                FileScanTasks: make([]RESTFileScanTask, taskCount),
@@ -72,7 +72,7 @@ func deletionVectorScanTasksWire(taskCount int, explicitOwner 
bool) ScanTasks {
                delete := deleteFile
                delete.FilePath = 
fmt.Sprintf("s3://bucket/table/delete-%d.puffin", i)
                if explicitOwner {
-                       delete.ReferencedDataFile = stringPtr(data.FilePath)
+                       delete.ReferencedDataFile = new(data.FilePath)
                }
 
                wire.FileScanTasks[i] = RESTFileScanTask{
diff --git a/catalog/rest/scan_task_decoder_test.go 
b/catalog/rest/scan_task_decoder_test.go
index 9cd8de8a9..b796c4a17 100644
--- a/catalog/rest/scan_task_decoder_test.go
+++ b/catalog/rest/scan_task_decoder_test.go
@@ -114,8 +114,8 @@ func TestDecodeScanTasksFullPayload(t *testing.T) {
        }, task.File.Partition())
        assert.Equal(t, []byte{0x0a, 0x0b}, task.File.KeyMetadata())
        assert.Equal(t, []int64{4, 128}, task.File.SplitOffsets())
-       assert.Equal(t, intPtr(3), task.File.SortOrderID())
-       assert.Equal(t, int64Ptr(99), task.FirstRowID)
+       assert.Equal(t, new(3), task.File.SortOrderID())
+       assert.Equal(t, new(int64(99)), task.FirstRowID)
        assert.Equal(t, map[int]int64{1: 800, 2: 1200}, task.File.ColumnSizes())
        assert.Equal(t, map[int]int64{1: 100, 2: 100}, task.File.ValueCounts())
        assert.Equal(t, map[int]int64{1: 0, 2: 1}, task.File.NullValueCounts())
@@ -137,9 +137,9 @@ func TestDecodeScanTasksFullPayload(t *testing.T) {
        require.Len(t, task.DeletionVectorFiles, 1)
        dv := task.DeletionVectorFiles[0]
        assert.Equal(t, iceberg.PuffinFile, dv.FileFormat())
-       assert.Equal(t, stringPtr("s3://bucket/table/data.parquet"), 
dv.ReferencedDataFile())
-       assert.Equal(t, int64Ptr(25), dv.ContentOffset())
-       assert.Equal(t, int64Ptr(50), dv.ContentSizeInBytes())
+       assert.Equal(t, new("s3://bucket/table/data.parquet"), 
dv.ReferencedDataFile())
+       assert.Equal(t, new(int64(25)), dv.ContentOffset())
+       assert.Equal(t, new(int64(50)), dv.ContentSizeInBytes())
 }
 
 func TestDecodeScanTasksAcceptsLegacyJavaContentValues(t *testing.T) {
@@ -278,14 +278,14 @@ func 
TestDecodeScanTasksDerivesDeletionVectorTargetWhenOmitted(t *testing.T) {
        wire := validScanTasksWire()
        wire.FileScanTasks[0].DeleteFileReferences = []int{0}
        wire.DeleteFiles[0].FileFormat = "puffin"
-       wire.DeleteFiles[0].ContentOffset = int64Ptr(10)
-       wire.DeleteFiles[0].ContentSizeInBytes = int64Ptr(20)
+       wire.DeleteFiles[0].ContentOffset = new(int64(10))
+       wire.DeleteFiles[0].ContentSizeInBytes = new(int64(20))
 
        tasks, err := DecodeScanTasks(wire, metadata, metadata.schema, nil)
        require.NoError(t, err)
        require.Len(t, tasks, 1)
        require.Len(t, tasks[0].DeletionVectorFiles, 1)
-       assert.Equal(t, stringPtr("s3://bucket/table/data.parquet"), 
tasks[0].DeletionVectorFiles[0].ReferencedDataFile())
+       assert.Equal(t, new("s3://bucket/table/data.parquet"), 
tasks[0].DeletionVectorFiles[0].ReferencedDataFile())
 }
 
 func TestRESTValueMapMatchesJavaContentFileParser(t *testing.T) {
@@ -364,7 +364,7 @@ func 
TestDecodeScanTasksKeyMetadataMatchesJavaContentFileParser(t *testing.T) {
        wire := validScanTasksWire()
        // This value mirrors Java TestContentFileParser's all-optional 
data-file
        // fixture. SingleValueParser encodes binary values as hexadecimal 
strings.
-       wire.FileScanTasks[0].DataFile.KeyMetadata = 
stringPtr("00000000000000000000000000000000")
+       wire.FileScanTasks[0].DataFile.KeyMetadata = 
new("00000000000000000000000000000000")
 
        tasks, err := DecodeScanTasks(wire, metadata, metadata.schema, nil)
        require.NoError(t, err)
@@ -473,8 +473,8 @@ func TestDecodeScanTasksRejectsMalformedPayloads(t 
*testing.T) {
                        mutate: func(w *ScanTasks) {
                                w.DeleteFiles[0].Content = "equality-deletes"
                                w.DeleteFiles[0].EqualityIDs = []int{1}
-                               w.DeleteFiles[0].ContentOffset = int64Ptr(10)
-                               w.DeleteFiles[0].ContentSizeInBytes = 
int64Ptr(20)
+                               w.DeleteFiles[0].ContentOffset = new(int64(10))
+                               w.DeleteFiles[0].ContentSizeInBytes = 
new(int64(20))
                        },
                        want: "must not carry position-delete reference or blob 
offsets",
                },
@@ -509,7 +509,7 @@ func TestDecodeScanTasksRejectsMalformedPayloads(t 
*testing.T) {
                {
                        name: "referenced data file disagrees with task",
                        mutate: func(w *ScanTasks) {
-                               w.DeleteFiles[0].ReferencedDataFile = 
stringPtr("s3://bucket/table/other.parquet")
+                               w.DeleteFiles[0].ReferencedDataFile = 
new("s3://bucket/table/other.parquet")
                                w.FileScanTasks[0].DeleteFileReferences = 
[]int{0}
                        },
                        want: "task data-file",
@@ -518,8 +518,8 @@ func TestDecodeScanTasksRejectsMalformedPayloads(t 
*testing.T) {
                        name: "deletion vector referenced by different data 
files",
                        mutate: func(w *ScanTasks) {
                                w.DeleteFiles[0].FileFormat = "puffin"
-                               w.DeleteFiles[0].ContentOffset = int64Ptr(10)
-                               w.DeleteFiles[0].ContentSizeInBytes = 
int64Ptr(20)
+                               w.DeleteFiles[0].ContentOffset = new(int64(10))
+                               w.DeleteFiles[0].ContentSizeInBytes = 
new(int64(20))
                                w.FileScanTasks[0].DeleteFileReferences = 
[]int{0}
                                secondDataFile := *w.FileScanTasks[0].DataFile
                                secondDataFile.FilePath = 
"s3://bucket/table/other.parquet"
@@ -692,6 +692,7 @@ func newScanTaskDecoderMetadata() *scanTaskDecoderMetadata {
 
 func (m *scanTaskDecoderMetadata) CurrentSchema() *iceberg.Schema { return 
m.schema }
 func (m *scanTaskDecoderMetadata) Schemas() []*iceberg.Schema     { return 
[]*iceberg.Schema{m.schema} }
+
 func (m *scanTaskDecoderMetadata) PartitionSpec() iceberg.PartitionSpec {
        return m.spec
 }
@@ -715,9 +716,6 @@ func mustLiteral(t *testing.T, value string, typ 
iceberg.Type) iceberg.Literal {
        return literal
 }
 
-func intPtr(value int) *int       { return &value }
-func int64Ptr(value int64) *int64 { return &value }
-
 func TestPartitionDecodePlanKeepsValuesIndependent(t *testing.T) {
        t.Parallel()
 
diff --git a/catalog/rest/wait_for_plan_test.go 
b/catalog/rest/wait_for_plan_test.go
index 5035073b0..aac1bc52f 100644
--- a/catalog/rest/wait_for_plan_test.go
+++ b/catalog/rest/wait_for_plan_test.go
@@ -667,7 +667,7 @@ func TestWaitForPlanForwardsAccessDelegation(t *testing.T) {
        })
 
        _, err := cat.WaitForPlan(context.Background(), table.Identifier{"db", 
"tbl"}, "plan-1", WaitForPlanOptions{
-               AccessDelegation: stringPtr("remote-signing"),
+               AccessDelegation: new("remote-signing"),
        })
        require.NoError(t, err)
 }
diff --git a/catalog/sql/sql.go b/catalog/sql/sql.go
index 61370d1c6..5a29937ab 100644
--- a/catalog/sql/sql.go
+++ b/catalog/sql/sql.go
@@ -352,8 +352,7 @@ func isRetryableSerializableError(err error) bool {
                }
        }
 
-       var mysqlErr *mysql.MySQLError
-       if errors.As(err, &mysqlErr) {
+       if mysqlErr, ok := errors.AsType[*mysql.MySQLError](err); ok {
                switch mysqlErr.Number {
                case 1205, 1213: // lock wait timeout, deadlock
                        return true
diff --git a/cmd/iceberg/upgrade_rollback_test.go 
b/cmd/iceberg/upgrade_rollback_test.go
index 3464fb759..70d5a3279 100644
--- a/cmd/iceberg/upgrade_rollback_test.go
+++ b/cmd/iceberg/upgrade_rollback_test.go
@@ -227,7 +227,7 @@ func TestResolveRollbackSnapshotIDExplicit(t *testing.T) {
 
        got, err := resolveRollbackSnapshotID(tbl, &RollbackCmd{
                TableID:    "db.events",
-               SnapshotID: int64Ptr(100),
+               SnapshotID: new(int64(100)),
        })
 
        require.NoError(t, err)
@@ -332,7 +332,7 @@ func TestValidateRollbackSelector(t *testing.T) {
        }{
                {
                        name:    "snapshot id only",
-                       cmd:     RollbackCmd{SnapshotID: int64Ptr(100)},
+                       cmd:     RollbackCmd{SnapshotID: new(int64(100))},
                        wantErr: "",
                },
                {
@@ -342,7 +342,7 @@ func TestValidateRollbackSelector(t *testing.T) {
                },
                {
                        name:    "both selectors",
-                       cmd:     RollbackCmd{SnapshotID: int64Ptr(100), 
Timestamp: "2026-01-15T03:00:00Z"},
+                       cmd:     RollbackCmd{SnapshotID: new(int64(100)), 
Timestamp: "2026-01-15T03:00:00Z"},
                        wantErr: "mutually exclusive",
                },
                {
@@ -389,7 +389,7 @@ func TestResolveRollbackSnapshotIDErrors(t *testing.T) {
                },
                {
                        name:    "missing snapshot id",
-                       cmd:     RollbackCmd{TableID: "db.events", SnapshotID: 
int64Ptr(999)},
+                       cmd:     RollbackCmd{TableID: "db.events", SnapshotID: 
new(int64(999))},
                        wantErr: "snapshot 999 not found",
                },
        }
@@ -551,7 +551,7 @@ func TestRunRollbackRejectsNonAncestor(t *testing.T) {
        exitCode := captureExit(func() {
                runRollback(context.Background(), &errOut, cat, &RollbackCmd{
                        TableID:    "db.events",
-                       SnapshotID: int64Ptr(300),
+                       SnapshotID: new(int64(300)),
                        Yes:        true,
                })
        })
@@ -575,7 +575,7 @@ func TestRunRollbackRejectsInvalidSelectorsBeforeLoad(t 
*testing.T) {
                        name: "snapshot id and timestamp",
                        cmd: RollbackCmd{
                                TableID:    "db.events",
-                               SnapshotID: int64Ptr(100),
+                               SnapshotID: new(int64(100)),
                                Timestamp:  
time.UnixMilli(1515100955770).UTC().Format(time.RFC3339),
                        },
                        wantErr: "mutually exclusive",
@@ -707,10 +707,6 @@ func upgradeRollbackTestTable(t *testing.T) *table.Table {
        return table.New([]string{"db", "events"}, meta, "", nil, nil)
 }
 
-func int64Ptr(v int64) *int64 {
-       return &v
-}
-
 type errCapture struct {
        textOutput
        lastErr  error
diff --git a/codec/data_file_test.go b/codec/data_file_test.go
index d414254b9..3eb9ca21d 100644
--- a/codec/data_file_test.go
+++ b/codec/data_file_test.go
@@ -279,8 +279,8 @@ var expectedDataFileMethods = []string{
 func dataFileInterfaceMethods() []string {
        t := reflect.TypeFor[iceberg.DataFile]()
        out := make([]string, 0, t.NumMethod())
-       for i := range t.NumMethod() {
-               out = append(out, t.Method(i).Name)
+       for method := range t.Methods() {
+               out = append(out, method.Name)
        }
        sort.Strings(out)
 
diff --git a/go.mod b/go.mod
index 525f08069..a9c93bdef 100644
--- a/go.mod
+++ b/go.mod
@@ -17,7 +17,7 @@
 
 module github.com/apache/iceberg-go
 
-go 1.25.9
+go 1.26.0
 
 require (
        cloud.google.com/go/storage v1.66.0
diff --git a/literals.go b/literals.go
index 4f6e27e07..fd3cac903 100644
--- a/literals.go
+++ b/literals.go
@@ -627,6 +627,7 @@ func (f Float32Literal) Type() Type                    { 
return PrimitiveTypes.F
 func (f Float32Literal) Value() float32                { return float32(f) }
 func (f Float32Literal) Any() any                      { return f.Value() }
 func (f Float32Literal) String() string                { return 
strconv.FormatFloat(float64(f), 'g', -1, 32) }
+
 func (f Float32Literal) To(t Type) (Literal, error) {
        switch t := t.(type) {
        case Float32Type:
@@ -675,6 +676,7 @@ func (f Float64Literal) Type() Type                    { 
return PrimitiveTypes.F
 func (f Float64Literal) Value() float64                { return float64(f) }
 func (f Float64Literal) Any() any                      { return f.Value() }
 func (f Float64Literal) String() string                { return 
strconv.FormatFloat(float64(f), 'g', -1, 64) }
+
 func (f Float64Literal) To(t Type) (Literal, error) {
        switch t := t.(type) {
        case Float32Type:
@@ -873,9 +875,10 @@ func (t *TimestampLiteral) UnmarshalBinary(data []byte) 
error {
 type TimestampNsLiteral TimestampNano
 
 func (TimestampNsLiteral) Comparator() Comparator[TimestampNano] { return 
cmp.Compare[TimestampNano] }
-func (t TimestampNsLiteral) Type() Type                          { return 
PrimitiveTypes.TimestampNs }
-func (t TimestampNsLiteral) Value() TimestampNano                { return 
TimestampNano(t) }
-func (t TimestampNsLiteral) Any() any                            { return 
t.Value() }
+
+func (t TimestampNsLiteral) Type() Type           { return 
PrimitiveTypes.TimestampNs }
+func (t TimestampNsLiteral) Value() TimestampNano { return TimestampNano(t) }
+func (t TimestampNsLiteral) Any() any             { return t.Value() }
 func (t TimestampNsLiteral) String() string {
        tm := TimestampNano(t).ToTime()
 
diff --git a/manifest.go b/manifest.go
index 259c96457..65eb82f56 100644
--- a/manifest.go
+++ b/manifest.go
@@ -2237,7 +2237,7 @@ func (m *ManifestListWriter) AddManifests(files 
[]ManifestFile) (err error) {
                                        ErrInvalidArgument, m.version, 
file.Version())
                        }
 
-                       wrapped := *(file.(*manifestFile))
+                       wrapped := *file.(*manifestFile)
                        ensurePartitionList(&wrapped.PartitionList)
                        if m.version == 3 {
                                // Ref: 
https://github.com/apache/iceberg/blob/ea2071568dc66148b483a82eefedcd2992b435f7/core/src/main/java/org/apache/iceberg/ManifestListWriter.java#L157-L168
diff --git a/manifest_test.go b/manifest_test.go
index 1db955fa4..a8357378c 100644
--- a/manifest_test.go
+++ b/manifest_test.go
@@ -4205,7 +4205,7 @@ func (m *ManifestTestSuite) 
TestV3ManifestListRejectsV1ManifestWithUnknownRowCou
 
        for _, tt := range tests {
                m.Run(tt.name, func() {
-                       legacy := *(manifestFileRecordsV1[0].(*manifestFile))
+                       legacy := *manifestFileRecordsV1[0].(*manifestFile)
                        legacy.AddedRowsCount = tt.addedRows
                        legacy.ExistingRowsCount = tt.existingRows
 
@@ -4230,7 +4230,7 @@ func (m *ManifestTestSuite) 
TestV3ManifestListRejectsV1ManifestWithUnknownRowCou
        }
 
        m.Run("mixed batch failure poisons writer", func() {
-               valid := *(manifestFileRecordsV1[0].(*manifestFile))
+               valid := *manifestFileRecordsV1[0].(*manifestFile)
                valid.Path = "valid.avro"
                unknown := valid
                unknown.Path = "unknown-counts.avro"
diff --git a/name_mapping_test.go b/name_mapping_test.go
index 7e4be6bba..30da26794 100644
--- a/name_mapping_test.go
+++ b/name_mapping_test.go
@@ -26,32 +26,30 @@ import (
        "github.com/stretchr/testify/require"
 )
 
-func makeID(v int) *int { return &v }
-
 var tableNameMappingNested = iceberg.NameMapping{
-       {FieldID: makeID(1), Names: []string{"foo"}},
-       {FieldID: makeID(2), Names: []string{"bar"}},
-       {FieldID: makeID(3), Names: []string{"baz"}},
+       {FieldID: new(1), Names: []string{"foo"}},
+       {FieldID: new(2), Names: []string{"bar"}},
+       {FieldID: new(3), Names: []string{"baz"}},
        {
-               FieldID: makeID(4), Names: []string{"qux"},
-               Fields: []iceberg.MappedField{{FieldID: makeID(5), Names: 
[]string{"element"}}},
+               FieldID: new(4), Names: []string{"qux"},
+               Fields: []iceberg.MappedField{{FieldID: new(5), Names: 
[]string{"element"}}},
        },
-       {FieldID: makeID(6), Names: []string{"quux"}, Fields: 
[]iceberg.MappedField{
-               {FieldID: makeID(7), Names: []string{"key"}},
-               {FieldID: makeID(8), Names: []string{"value"}, Fields: 
[]iceberg.MappedField{
-                       {FieldID: makeID(9), Names: []string{"key"}},
-                       {FieldID: makeID(10), Names: []string{"value"}},
+       {FieldID: new(6), Names: []string{"quux"}, Fields: 
[]iceberg.MappedField{
+               {FieldID: new(7), Names: []string{"key"}},
+               {FieldID: new(8), Names: []string{"value"}, Fields: 
[]iceberg.MappedField{
+                       {FieldID: new(9), Names: []string{"key"}},
+                       {FieldID: new(10), Names: []string{"value"}},
                }},
        }},
-       {FieldID: makeID(11), Names: []string{"location"}, Fields: 
[]iceberg.MappedField{
-               {FieldID: makeID(12), Names: []string{"element"}, Fields: 
[]iceberg.MappedField{
-                       {FieldID: makeID(13), Names: []string{"latitude"}},
-                       {FieldID: makeID(14), Names: []string{"longitude"}},
+       {FieldID: new(11), Names: []string{"location"}, Fields: 
[]iceberg.MappedField{
+               {FieldID: new(12), Names: []string{"element"}, Fields: 
[]iceberg.MappedField{
+                       {FieldID: new(13), Names: []string{"latitude"}},
+                       {FieldID: new(14), Names: []string{"longitude"}},
                }},
        }},
-       {FieldID: makeID(15), Names: []string{"person"}, Fields: 
[]iceberg.MappedField{
-               {FieldID: makeID(16), Names: []string{"name"}},
-               {FieldID: makeID(17), Names: []string{"age"}},
+       {FieldID: new(15), Names: []string{"person"}, Fields: 
[]iceberg.MappedField{
+               {FieldID: new(16), Names: []string{"name"}},
+               {FieldID: new(17), Names: []string{"age"}},
        }},
 }
 
@@ -63,13 +61,13 @@ func TestJsonMappedField(t *testing.T) {
        }{
                {
                        "simple", `{"field-id": 1, "names": ["id", 
"record_id"]}`,
-                       iceberg.MappedField{FieldID: makeID(1), Names: 
[]string{"id", "record_id"}},
+                       iceberg.MappedField{FieldID: new(1), Names: 
[]string{"id", "record_id"}},
                },
                {
                        "with null fields", `{"field-id": 1, "names": ["id", 
"record_id"], "fields": null}`,
-                       iceberg.MappedField{FieldID: makeID(1), Names: 
[]string{"id", "record_id"}},
+                       iceberg.MappedField{FieldID: new(1), Names: 
[]string{"id", "record_id"}},
                },
-               {"no names", `{"field-id": 1, "names": []}`, 
iceberg.MappedField{FieldID: makeID(1), Names: []string{}}},
+               {"no names", `{"field-id": 1, "names": []}`, 
iceberg.MappedField{FieldID: new(1), Names: []string{}}},
        }
 
        for _, tt := range tests {
@@ -97,11 +95,11 @@ func TestNameMappingFromJson(t *testing.T) {
 
        assert.Equal(t, nm, iceberg.NameMapping{
                {FieldID: nil, Names: []string{"foo", "bar"}},
-               {FieldID: makeID(1), Names: []string{"id", "record_id"}},
-               {FieldID: makeID(2), Names: []string{"data"}},
-               {FieldID: makeID(3), Names: []string{"location"}, Fields: 
[]iceberg.MappedField{
-                       {FieldID: makeID(4), Names: []string{"latitude", 
"lat"}},
-                       {FieldID: makeID(5), Names: []string{"longitude", 
"long"}},
+               {FieldID: new(1), Names: []string{"id", "record_id"}},
+               {FieldID: new(2), Names: []string{"data"}},
+               {FieldID: new(3), Names: []string{"location"}, Fields: 
[]iceberg.MappedField{
+                       {FieldID: new(4), Names: []string{"latitude", "lat"}},
+                       {FieldID: new(5), Names: []string{"longitude", "long"}},
                }},
        })
 }
@@ -111,7 +109,7 @@ func TestApplyNameMappingUsesAlias(t *testing.T) {
                iceberg.NestedField{ID: 100, Name: "renamed", Type: 
iceberg.PrimitiveTypes.String},
        )
        mapping := iceberg.NameMapping{
-               {FieldID: makeID(1), Names: []string{"legacy", "renamed"}},
+               {FieldID: new(1), Names: []string{"legacy", "renamed"}},
        }
 
        result, err := iceberg.ApplyNameMapping(schema, mapping)
@@ -164,39 +162,39 @@ func TestNameMappingToString(t *testing.T) {
        ([location] -> 3 ([lat, latitude] -> 4), ([long, longitude] -> 5))
 ]`, iceberg.NameMapping{
                {Names: []string{"foo"}},
-               {FieldID: makeID(1), Names: []string{"id", "record_id"}},
-               {FieldID: makeID(2), Names: []string{"data"}},
-               {FieldID: makeID(3), Names: []string{"location"}, Fields: 
[]iceberg.MappedField{
-                       {FieldID: makeID(4), Names: []string{"lat", 
"latitude"}},
-                       {FieldID: makeID(5), Names: []string{"long", 
"longitude"}},
+               {FieldID: new(1), Names: []string{"id", "record_id"}},
+               {FieldID: new(2), Names: []string{"data"}},
+               {FieldID: new(3), Names: []string{"location"}, Fields: 
[]iceberg.MappedField{
+                       {FieldID: new(4), Names: []string{"lat", "latitude"}},
+                       {FieldID: new(5), Names: []string{"long", "longitude"}},
                }},
        }.String())
 }
 
 func TestUpdateNameMapping(t *testing.T) {
        originalMapping := iceberg.NameMapping{
-               {FieldID: makeID(1), Names: []string{"foo"}},
-               {FieldID: makeID(2), Names: []string{"bar"}},
-               {FieldID: makeID(3), Names: []string{"baz"}},
-               {FieldID: makeID(4), Names: []string{"qux"}, Fields: 
[]iceberg.MappedField{
-                       {FieldID: makeID(5), Names: []string{"element"}},
+               {FieldID: new(1), Names: []string{"foo"}},
+               {FieldID: new(2), Names: []string{"bar"}},
+               {FieldID: new(3), Names: []string{"baz"}},
+               {FieldID: new(4), Names: []string{"qux"}, Fields: 
[]iceberg.MappedField{
+                       {FieldID: new(5), Names: []string{"element"}},
                }},
-               {FieldID: makeID(6), Names: []string{"quux"}, Fields: 
[]iceberg.MappedField{
-                       {FieldID: makeID(7), Names: []string{"key"}},
-                       {FieldID: makeID(8), Names: []string{"value"}, Fields: 
[]iceberg.MappedField{
-                               {FieldID: makeID(9), Names: []string{"key"}},
-                               {FieldID: makeID(10), Names: []string{"value"}},
+               {FieldID: new(6), Names: []string{"quux"}, Fields: 
[]iceberg.MappedField{
+                       {FieldID: new(7), Names: []string{"key"}},
+                       {FieldID: new(8), Names: []string{"value"}, Fields: 
[]iceberg.MappedField{
+                               {FieldID: new(9), Names: []string{"key"}},
+                               {FieldID: new(10), Names: []string{"value"}},
                        }},
                }},
-               {FieldID: makeID(11), Names: []string{"location"}, Fields: 
[]iceberg.MappedField{
-                       {FieldID: makeID(12), Names: []string{"element"}, 
Fields: []iceberg.MappedField{
-                               {FieldID: makeID(13), Names: 
[]string{"latitude"}},
-                               {FieldID: makeID(14), Names: 
[]string{"longitude"}},
+               {FieldID: new(11), Names: []string{"location"}, Fields: 
[]iceberg.MappedField{
+                       {FieldID: new(12), Names: []string{"element"}, Fields: 
[]iceberg.MappedField{
+                               {FieldID: new(13), Names: []string{"latitude"}},
+                               {FieldID: new(14), Names: 
[]string{"longitude"}},
                        }},
                }},
-               {FieldID: makeID(15), Names: []string{"person"}, Fields: 
[]iceberg.MappedField{
-                       {FieldID: makeID(16), Names: []string{"name"}},
-                       {FieldID: makeID(17), Names: []string{"age"}},
+               {FieldID: new(15), Names: []string{"person"}, Fields: 
[]iceberg.MappedField{
+                       {FieldID: new(16), Names: []string{"name"}},
+                       {FieldID: new(17), Names: []string{"age"}},
                }},
        }
 
@@ -286,7 +284,7 @@ func TestUpdateNameMapping(t *testing.T) {
                )
                require.NoError(t, err)
                assert.Equal(t, iceberg.NameMapping{{
-                       FieldID: makeID(1),
+                       FieldID: new(1),
                        Names:   []string{"original", "renamed"},
                }}, result)
        })
@@ -309,31 +307,31 @@ func TestUpdateNameMapping(t *testing.T) {
                require.NoError(t, err)
 
                expected := iceberg.NameMapping{
-                       {FieldID: makeID(1), Names: []string{"foo", 
"foo_update"}},
-                       {FieldID: makeID(2), Names: []string{"bar"}},
-                       {FieldID: makeID(3), Names: []string{"baz"}},
-                       {FieldID: makeID(4), Names: []string{"qux"}, Fields: 
[]iceberg.MappedField{
-                               {FieldID: makeID(5), Names: 
[]string{"element"}},
+                       {FieldID: new(1), Names: []string{"foo", "foo_update"}},
+                       {FieldID: new(2), Names: []string{"bar"}},
+                       {FieldID: new(3), Names: []string{"baz"}},
+                       {FieldID: new(4), Names: []string{"qux"}, Fields: 
[]iceberg.MappedField{
+                               {FieldID: new(5), Names: []string{"element"}},
                        }},
-                       {FieldID: makeID(6), Names: []string{"quux"}, Fields: 
[]iceberg.MappedField{
-                               {FieldID: makeID(7), Names: []string{"key"}},
-                               {FieldID: makeID(8), Names: []string{"value"}, 
Fields: []iceberg.MappedField{
-                                       {FieldID: makeID(9), Names: 
[]string{"key"}},
-                                       {FieldID: makeID(10), Names: 
[]string{"value"}},
+                       {FieldID: new(6), Names: []string{"quux"}, Fields: 
[]iceberg.MappedField{
+                               {FieldID: new(7), Names: []string{"key"}},
+                               {FieldID: new(8), Names: []string{"value"}, 
Fields: []iceberg.MappedField{
+                                       {FieldID: new(9), Names: 
[]string{"key"}},
+                                       {FieldID: new(10), Names: 
[]string{"value"}},
                                }},
                        }},
-                       {FieldID: makeID(11), Names: []string{"location"}, 
Fields: []iceberg.MappedField{
-                               {FieldID: makeID(12), Names: 
[]string{"element"}, Fields: []iceberg.MappedField{
-                                       {FieldID: makeID(13), Names: 
[]string{"latitude"}},
-                                       {FieldID: makeID(14), Names: 
[]string{"longitude"}},
+                       {FieldID: new(11), Names: []string{"location"}, Fields: 
[]iceberg.MappedField{
+                               {FieldID: new(12), Names: []string{"element"}, 
Fields: []iceberg.MappedField{
+                                       {FieldID: new(13), Names: 
[]string{"latitude"}},
+                                       {FieldID: new(14), Names: 
[]string{"longitude"}},
                                }},
                        }},
-                       {FieldID: makeID(15), Names: []string{"person"}, 
Fields: []iceberg.MappedField{
-                               {FieldID: makeID(17), Names: []string{"age"}},
-                               {FieldID: makeID(19), Names: []string{"name"}},
-                               {FieldID: makeID(20), Names: 
[]string{"add_20"}},
+                       {FieldID: new(15), Names: []string{"person"}, Fields: 
[]iceberg.MappedField{
+                               {FieldID: new(17), Names: []string{"age"}},
+                               {FieldID: new(19), Names: []string{"name"}},
+                               {FieldID: new(20), Names: []string{"add_20"}},
                        }},
-                       {FieldID: makeID(18), Names: []string{"add_18"}},
+                       {FieldID: new(18), Names: []string{"add_18"}},
                }
 
                assert.Equal(t, expected, result)
@@ -350,28 +348,28 @@ func TestUpdateNameMapping(t *testing.T) {
                require.NoError(t, err)
 
                expected := iceberg.NameMapping{
-                       {FieldID: makeID(1), Names: []string{"foo", "new_foo"}},
-                       {FieldID: makeID(2), Names: []string{"bar", "new_bar"}},
-                       {FieldID: makeID(3), Names: []string{"baz"}},
-                       {FieldID: makeID(4), Names: []string{"qux"}, Fields: 
[]iceberg.MappedField{
-                               {FieldID: makeID(5), Names: 
[]string{"element"}},
+                       {FieldID: new(1), Names: []string{"foo", "new_foo"}},
+                       {FieldID: new(2), Names: []string{"bar", "new_bar"}},
+                       {FieldID: new(3), Names: []string{"baz"}},
+                       {FieldID: new(4), Names: []string{"qux"}, Fields: 
[]iceberg.MappedField{
+                               {FieldID: new(5), Names: []string{"element"}},
                        }},
-                       {FieldID: makeID(6), Names: []string{"quux"}, Fields: 
[]iceberg.MappedField{
-                               {FieldID: makeID(7), Names: []string{"key"}},
-                               {FieldID: makeID(8), Names: []string{"value"}, 
Fields: []iceberg.MappedField{
-                                       {FieldID: makeID(9), Names: 
[]string{"key"}},
-                                       {FieldID: makeID(10), Names: 
[]string{"value"}},
+                       {FieldID: new(6), Names: []string{"quux"}, Fields: 
[]iceberg.MappedField{
+                               {FieldID: new(7), Names: []string{"key"}},
+                               {FieldID: new(8), Names: []string{"value"}, 
Fields: []iceberg.MappedField{
+                                       {FieldID: new(9), Names: 
[]string{"key"}},
+                                       {FieldID: new(10), Names: 
[]string{"value"}},
                                }},
                        }},
-                       {FieldID: makeID(11), Names: []string{"location"}, 
Fields: []iceberg.MappedField{
-                               {FieldID: makeID(12), Names: 
[]string{"element"}, Fields: []iceberg.MappedField{
-                                       {FieldID: makeID(13), Names: 
[]string{"latitude"}},
-                                       {FieldID: makeID(14), Names: 
[]string{"longitude"}},
+                       {FieldID: new(11), Names: []string{"location"}, Fields: 
[]iceberg.MappedField{
+                               {FieldID: new(12), Names: []string{"element"}, 
Fields: []iceberg.MappedField{
+                                       {FieldID: new(13), Names: 
[]string{"latitude"}},
+                                       {FieldID: new(14), Names: 
[]string{"longitude"}},
                                }},
                        }},
-                       {FieldID: makeID(15), Names: []string{"person"}, 
Fields: []iceberg.MappedField{
-                               {FieldID: makeID(16), Names: []string{"name"}},
-                               {FieldID: makeID(17), Names: []string{"age"}},
+                       {FieldID: new(15), Names: []string{"person"}, Fields: 
[]iceberg.MappedField{
+                               {FieldID: new(16), Names: []string{"name"}},
+                               {FieldID: new(17), Names: []string{"age"}},
                        }},
                }
 
@@ -393,31 +391,31 @@ func TestUpdateNameMapping(t *testing.T) {
                require.NoError(t, err)
 
                expected := iceberg.NameMapping{
-                       {FieldID: makeID(1), Names: []string{"foo"}},
-                       {FieldID: makeID(2), Names: []string{"bar"}},
-                       {FieldID: makeID(3), Names: []string{"baz"}},
-                       {FieldID: makeID(4), Names: []string{"qux"}, Fields: 
[]iceberg.MappedField{
-                               {FieldID: makeID(5), Names: 
[]string{"element"}},
+                       {FieldID: new(1), Names: []string{"foo"}},
+                       {FieldID: new(2), Names: []string{"bar"}},
+                       {FieldID: new(3), Names: []string{"baz"}},
+                       {FieldID: new(4), Names: []string{"qux"}, Fields: 
[]iceberg.MappedField{
+                               {FieldID: new(5), Names: []string{"element"}},
                        }},
-                       {FieldID: makeID(6), Names: []string{"quux"}, Fields: 
[]iceberg.MappedField{
-                               {FieldID: makeID(7), Names: []string{"key"}},
-                               {FieldID: makeID(8), Names: []string{"value"}, 
Fields: []iceberg.MappedField{
-                                       {FieldID: makeID(9), Names: 
[]string{"key"}},
-                                       {FieldID: makeID(10), Names: 
[]string{"value"}},
+                       {FieldID: new(6), Names: []string{"quux"}, Fields: 
[]iceberg.MappedField{
+                               {FieldID: new(7), Names: []string{"key"}},
+                               {FieldID: new(8), Names: []string{"value"}, 
Fields: []iceberg.MappedField{
+                                       {FieldID: new(9), Names: 
[]string{"key"}},
+                                       {FieldID: new(10), Names: 
[]string{"value"}},
                                }},
                        }},
-                       {FieldID: makeID(11), Names: []string{"location"}, 
Fields: []iceberg.MappedField{
-                               {FieldID: makeID(12), Names: 
[]string{"element"}, Fields: []iceberg.MappedField{
-                                       {FieldID: makeID(13), Names: 
[]string{"latitude"}},
-                                       {FieldID: makeID(14), Names: 
[]string{"longitude"}},
+                       {FieldID: new(11), Names: []string{"location"}, Fields: 
[]iceberg.MappedField{
+                               {FieldID: new(12), Names: []string{"element"}, 
Fields: []iceberg.MappedField{
+                                       {FieldID: new(13), Names: 
[]string{"latitude"}},
+                                       {FieldID: new(14), Names: 
[]string{"longitude"}},
                                }},
                        }},
-                       {FieldID: makeID(15), Names: []string{"person"}, 
Fields: []iceberg.MappedField{
-                               {FieldID: makeID(16), Names: []string{"name"}},
-                               {FieldID: makeID(17), Names: []string{"age"}},
-                               {FieldID: makeID(22), Names: []string{"email"}},
+                       {FieldID: new(15), Names: []string{"person"}, Fields: 
[]iceberg.MappedField{
+                               {FieldID: new(16), Names: []string{"name"}},
+                               {FieldID: new(17), Names: []string{"age"}},
+                               {FieldID: new(22), Names: []string{"email"}},
                        }},
-                       {FieldID: makeID(21), Names: 
[]string{"new_root_field"}},
+                       {FieldID: new(21), Names: []string{"new_root_field"}},
                }
 
                assert.Equal(t, expected, result)
diff --git a/partitions.go b/partitions.go
index 3cf043e18..58014bd41 100644
--- a/partitions.go
+++ b/partitions.go
@@ -230,8 +230,7 @@ func (p *PartitionField) unmarshal(b []byte, binding 
specBinding) error {
 
 func unmarshalJSONField(data json.RawMessage, field string, value any) error {
        if err := json.Unmarshal(data, value); err != nil {
-               var typeErr *json.UnmarshalTypeError
-               if errors.As(err, &typeErr) {
+               if typeErr, ok := errors.AsType[*json.UnmarshalTypeError](err); 
ok {
                        typeErr.Struct = ""
                        typeErr.Field = field
                }
diff --git a/puffin/puffin_reader.go b/puffin/puffin_reader.go
index ab2c6c0e6..b858a3f78 100644
--- a/puffin/puffin_reader.go
+++ b/puffin/puffin_reader.go
@@ -509,16 +509,23 @@ func (r *Reader) readFooter() error {
        // FooterPayloadSize defines a single JSON footer object. Reject 
trailing
        // content deliberately, even though some other Iceberg implementations
        // accept padding or additional values inside the footer payload.
-       if decoder.More() {
-               return errors.New("puffin: unexpected content after footer 
JSON")
-       }
-       if _, err := decoder.Token(); !errors.Is(err, io.EOF) {
+       //
+       // A failed decompression read also stops the decoder here; report that
+       // error rather than trailing content. Since Go 1.27, Decoder.More 
reports
+       // true on non-EOF read errors, so both checks need it.
+       trailingContentErr := func() error {
                if compressedFooter != nil && compressedFooter.err != nil {
                        return fmt.Errorf("puffin: read compressed footer: %w", 
compressedFooter.err)
                }
 
                return errors.New("puffin: unexpected content after footer 
JSON")
        }
+       if decoder.More() {
+               return trailingContentErr()
+       }
+       if _, err := decoder.Token(); !errors.Is(err, io.EOF) {
+               return trailingContentErr()
+       }
        if limitedFooter != nil && limitedFooter.N == 0 {
                return fmt.Errorf("puffin: footer exceeds maximum size %d", 
r.maxFooterSize)
        }
diff --git a/table/arrow_utils.go b/table/arrow_utils.go
index c974b8d69..9173bfc15 100644
--- a/table/arrow_utils.go
+++ b/table/arrow_utils.go
@@ -662,7 +662,8 @@ func (c convertToArrow) Map(m iceberg.MapType, keyResult, 
valResult arrow.Field)
 }
 
 func (c convertToArrow) Primitive(iceberg.PrimitiveType) arrow.Field { 
panic("shouldn't be called") }
-func (c convertToArrow) Variant(iceberg.VariantType) arrow.Field     { 
panic("shouldn't be called") }
+
+func (c convertToArrow) Variant(iceberg.VariantType) arrow.Field { 
panic("shouldn't be called") }
 
 func (c convertToArrow) VisitFixed(f iceberg.FixedType) arrow.Field {
        return arrow.Field{Type: &arrow.FixedSizeBinaryType{ByteWidth: f.Len()}}
diff --git a/table/arrow_utils_test.go b/table/arrow_utils_test.go
index 580847211..8eabb9e08 100644
--- a/table/arrow_utils_test.go
+++ b/table/arrow_utils_test.go
@@ -290,8 +290,6 @@ func TestArrowSchemaToIceberg(t *testing.T) {
        }
 }
 
-func makeID(v int) *int { return &v }
-
 var (
        icebergSchemaNested = iceberg.NewSchema(0,
                iceberg.NestedField{
@@ -1103,37 +1101,37 @@ func TestArrowSchemaWithNameMapping(t *testing.T) {
                err      string
        }{
                {"simple", schemaWithoutIDs, iceberg.NameMapping{
-                       {FieldID: makeID(1), Names: []string{"foo"}},
-                       {FieldID: makeID(2), Names: []string{"bar"}},
-                       {FieldID: makeID(3), Names: []string{"baz"}},
+                       {FieldID: new(1), Names: []string{"foo"}},
+                       {FieldID: new(2), Names: []string{"bar"}},
+                       {FieldID: new(3), Names: []string{"baz"}},
                }, icebergSchemaSimple, ""},
                {"field missing", schemaWithoutIDs, iceberg.NameMapping{
-                       {FieldID: makeID(1), Names: []string{"foo"}},
+                       {FieldID: new(1), Names: []string{"foo"}},
                }, nil, "field missing from name mapping: bar"},
                {"nested schema", schemaNestedWithoutIDs, iceberg.NameMapping{
-                       {FieldID: makeID(1), Names: []string{"foo"}},
-                       {FieldID: makeID(2), Names: []string{"bar"}},
-                       {FieldID: makeID(3), Names: []string{"baz"}},
+                       {FieldID: new(1), Names: []string{"foo"}},
+                       {FieldID: new(2), Names: []string{"bar"}},
+                       {FieldID: new(3), Names: []string{"baz"}},
                        {
-                               FieldID: makeID(4), Names: []string{"qux"},
-                               Fields: []iceberg.MappedField{{FieldID: 
makeID(5), Names: []string{"element"}}},
-                       },
-                       {FieldID: makeID(6), Names: []string{"quux"}, Fields: 
[]iceberg.MappedField{
-                               {FieldID: makeID(7), Names: []string{"key"}},
-                               {FieldID: makeID(8), Names: []string{"value"}, 
Fields: []iceberg.MappedField{
-                                       {FieldID: makeID(9), Names: 
[]string{"key"}},
-                                       {FieldID: makeID(10), Names: 
[]string{"value"}},
+                               FieldID: new(4), Names: []string{"qux"},
+                               Fields: []iceberg.MappedField{{FieldID: new(5), 
Names: []string{"element"}}},
+                       },
+                       {FieldID: new(6), Names: []string{"quux"}, Fields: 
[]iceberg.MappedField{
+                               {FieldID: new(7), Names: []string{"key"}},
+                               {FieldID: new(8), Names: []string{"value"}, 
Fields: []iceberg.MappedField{
+                                       {FieldID: new(9), Names: 
[]string{"key"}},
+                                       {FieldID: new(10), Names: 
[]string{"value"}},
                                }},
                        }},
-                       {FieldID: makeID(11), Names: []string{"location"}, 
Fields: []iceberg.MappedField{
-                               {FieldID: makeID(12), Names: 
[]string{"element"}, Fields: []iceberg.MappedField{
-                                       {FieldID: makeID(13), Names: 
[]string{"latitude"}},
-                                       {FieldID: makeID(14), Names: 
[]string{"longitude"}},
+                       {FieldID: new(11), Names: []string{"location"}, Fields: 
[]iceberg.MappedField{
+                               {FieldID: new(12), Names: []string{"element"}, 
Fields: []iceberg.MappedField{
+                                       {FieldID: new(13), Names: 
[]string{"latitude"}},
+                                       {FieldID: new(14), Names: 
[]string{"longitude"}},
                                }},
                        }},
-                       {FieldID: makeID(15), Names: []string{"person"}, 
Fields: []iceberg.MappedField{
-                               {FieldID: makeID(16), Names: []string{"name"}},
-                               {FieldID: makeID(17), Names: []string{"age"}},
+                       {FieldID: new(15), Names: []string{"person"}, Fields: 
[]iceberg.MappedField{
+                               {FieldID: new(16), Names: []string{"name"}},
+                               {FieldID: new(17), Names: []string{"age"}},
                        }},
                }, icebergSchemaNested, ""},
        }
diff --git a/table/dv/deletion_vector_bench_test.go 
b/table/dv/deletion_vector_bench_test.go
index f752273c5..f07b1318d 100644
--- a/table/dv/deletion_vector_bench_test.go
+++ b/table/dv/deletion_vector_bench_test.go
@@ -138,7 +138,7 @@ func benchmarkDVFiles(b *testing.B, numDVs int) 
[]iceberg.DataFile {
 
                offset, size := meta.Offset, meta.Length
                file := newDVTestFile(path, 1, &offset, &size)
-               file.referencedDataFile = strPtr(referencedDataFile)
+               file.referencedDataFile = new(referencedDataFile)
                files[i] = file
        }
 
diff --git a/table/dv/deletion_vector_test.go b/table/dv/deletion_vector_test.go
index bd9814e65..7192b1238 100644
--- a/table/dv/deletion_vector_test.go
+++ b/table/dv/deletion_vector_test.go
@@ -71,8 +71,6 @@ func (*mockDVFile) SortOrderID() *int                         
{ return nil }
 func (*mockDVFile) SpecID() int32                             { return 0 }
 func (*mockDVFile) FirstRowID() *int64                        { return nil }
 
-func strPtr(s string) *string { return &s }
-
 func readDVTestData(t *testing.T, name string) []byte {
        t.Helper()
        data, err := os.ReadFile(filepath.Join("testdata", "deletes", name))
@@ -252,7 +250,7 @@ func newDVTestFile(path string, count int64, offset, size 
*int64) *mockDVFile {
                path:               path,
                format:             iceberg.PuffinFile,
                count:              count,
-               referencedDataFile: strPtr("s3://bucket/data/data-001.parquet"),
+               referencedDataFile: new("s3://bucket/data/data-001.parquet"),
                contentOffset:      offset,
                contentSizeInBytes: size,
        }
@@ -592,7 +590,7 @@ func TestReadDVs(t *testing.T) {
        for i, meta := range metas {
                offset, size := meta.Offset, meta.Length
                file := newDVTestFile(path, 5, &offset, &size)
-               file.referencedDataFile = 
strPtr(fmt.Sprintf("s3://bucket/data/data-%03d.parquet", i+1))
+               file.referencedDataFile = 
new(fmt.Sprintf("s3://bucket/data/data-%03d.parquet", i+1))
                files[i] = file
        }
 
@@ -624,7 +622,7 @@ func TestReadDVs(t *testing.T) {
        t.Run("invalid blob identity", func(t *testing.T) {
                first := files[0].(*mockDVFile)
                second := *files[1].(*mockDVFile)
-               second.referencedDataFile = 
strPtr("s3://bucket/data/wrong.parquet")
+               second.referencedDataFile = 
new("s3://bucket/data/wrong.parquet")
 
                _, err := ReadDVs(iceio.LocalFS{}, []iceberg.DataFile{first, 
&second})
                require.ErrorIs(t, err, ErrInvalidDeletionVector)
@@ -667,8 +665,8 @@ func TestReadDVsCoalescesAdjacentBlobReads(t *testing.T) {
                newDVTestFile(path, 1, &secondOffset, &secondSize),
                newDVTestFile(path, 1, &firstOffset, &firstSize),
        }
-       files[0].(*mockDVFile).referencedDataFile = strPtr("data-002.parquet")
-       files[1].(*mockDVFile).referencedDataFile = strPtr("data-001.parquet")
+       files[0].(*mockDVFile).referencedDataFile = new("data-002.parquet")
+       files[1].(*mockDVFile).referencedDataFile = new("data-001.parquet")
 
        fs := &countingReadIO{base: iceio.LocalFS{}}
        bitmaps, err := ReadDVs(fs, files)
@@ -709,7 +707,7 @@ func TestReadDVsDoesNotCoalesceRangesOverSizeLimit(t 
*testing.T) {
        for i, meta := range metas {
                offset, size := meta.Offset, meta.Length
                file := newDVTestFile(path, cardinality, &offset, &size)
-               file.referencedDataFile = 
strPtr(fmt.Sprintf("data-%03d.parquet", i+1))
+               file.referencedDataFile = new(fmt.Sprintf("data-%03d.parquet", 
i+1))
                files[i] = file
        }
 
@@ -757,7 +755,7 @@ func TestReadDVsDoesNotCoalesceBlobsWithGaps(t *testing.T) {
        for i, meta := range metas {
                offset, size := meta.Offset, meta.Length
                file := newDVTestFile(path, 1, &offset, &size)
-               file.referencedDataFile = 
strPtr(fmt.Sprintf("data-%03d.parquet", i+1))
+               file.referencedDataFile = new(fmt.Sprintf("data-%03d.parquet", 
i+1))
                files[i] = file
        }
 
@@ -833,7 +831,7 @@ func TestReadDVMissingReferencedDataFile(t *testing.T) {
                referenced *string
        }{
                {name: "nil", referenced: nil},
-               {name: "empty", referenced: strPtr("")},
+               {name: "empty", referenced: new("")},
        } {
                t.Run(tt.name, func(t *testing.T) {
                        offset, size := int64(4), int64(50)
diff --git a/table/dv_scan_planning_test.go b/table/dv_scan_planning_test.go
index 86a4cea49..36d55f953 100644
--- a/table/dv_scan_planning_test.go
+++ b/table/dv_scan_planning_test.go
@@ -38,9 +38,6 @@ func (d *dvMockDataFile) ReferencedDataFile() *string { 
return d.referencedDataF
 func (d *dvMockDataFile) ContentOffset() *int64       { return d.contentOffset 
}
 func (d *dvMockDataFile) ContentSizeInBytes() *int64  { return 
d.contentSizeInBytes }
 
-func strPtr(s string) *string { return &s }
-func int64Ptr(v int64) *int64 { return &v }
-
 func TestIsDeletionVector(t *testing.T) {
        tests := []struct {
                name     string
@@ -71,9 +68,9 @@ func TestIsDeletionVector(t *testing.T) {
                                        contentType: 
iceberg.EntryContentPosDeletes,
                                        format:      iceberg.PuffinFile,
                                },
-                               referencedDataFile: 
strPtr("s3://bucket/data/file.parquet"),
-                               contentOffset:      int64Ptr(100),
-                               contentSizeInBytes: int64Ptr(256),
+                               referencedDataFile: 
new("s3://bucket/data/file.parquet"),
+                               contentOffset:      new(int64(100)),
+                               contentSizeInBytes: new(int64(256)),
                        },
                        expected: true,
                },
@@ -116,9 +113,9 @@ func TestManifestEntries_DVClassification(t *testing.T) {
                        contentType: iceberg.EntryContentPosDeletes,
                        format:      iceberg.PuffinFile,
                },
-               referencedDataFile: strPtr("s3://bucket/data/data-001.parquet"),
-               contentOffset:      int64Ptr(0),
-               contentSizeInBytes: int64Ptr(128),
+               referencedDataFile: new("s3://bucket/data/data-001.parquet"),
+               contentOffset:      new(int64(0)),
+               contentSizeInBytes: new(int64(128)),
        }
 
        // Equality delete entry
@@ -220,9 +217,9 @@ func TestManifestEntries_ConcurrentMerge(t *testing.T) {
                                contentType: iceberg.EntryContentPosDeletes,
                                format:      iceberg.PuffinFile,
                        },
-                       referencedDataFile: 
strPtr("s3://bucket/data/data-001.parquet"),
-                       contentOffset:      int64Ptr(0),
-                       contentSizeInBytes: int64Ptr(128),
+                       referencedDataFile: 
new("s3://bucket/data/data-001.parquet"),
+                       contentOffset:      new(int64(0)),
+                       contentSizeInBytes: new(int64(128)),
                }),
        }
 
@@ -251,9 +248,9 @@ func TestDVMatchingToDataFiles(t *testing.T) {
                        path:        "s3://bucket/data/dv-001.puffin",
                        contentType: iceberg.EntryContentPosDeletes,
                },
-               referencedDataFile: strPtr(dataFilePath),
-               contentOffset:      int64Ptr(0),
-               contentSizeInBytes: int64Ptr(128),
+               referencedDataFile: new(dataFilePath),
+               contentOffset:      new(int64(0)),
+               contentSizeInBytes: new(int64(128)),
        }
 
        dvForData2 := &dvMockDataFile{
@@ -261,9 +258,9 @@ func TestDVMatchingToDataFiles(t *testing.T) {
                        path:        "s3://bucket/data/dv-002.puffin",
                        contentType: iceberg.EntryContentPosDeletes,
                },
-               referencedDataFile: strPtr(otherDataFilePath),
-               contentOffset:      int64Ptr(0),
-               contentSizeInBytes: int64Ptr(64),
+               referencedDataFile: new(otherDataFilePath),
+               contentOffset:      new(int64(0)),
+               contentSizeInBytes: new(int64(64)),
        }
 
        snapshotID := int64(1)
@@ -301,9 +298,9 @@ func TestDVMatchingNoMatch(t *testing.T) {
                        path:        "s3://bucket/data/dv-001.puffin",
                        contentType: iceberg.EntryContentPosDeletes,
                },
-               referencedDataFile: strPtr("s3://bucket/data/data-999.parquet"),
-               contentOffset:      int64Ptr(0),
-               contentSizeInBytes: int64Ptr(128),
+               referencedDataFile: new("s3://bucket/data/data-999.parquet"),
+               contentOffset:      new(int64(0)),
+               contentSizeInBytes: new(int64(128)),
        }
 
        dvEntries := []iceberg.ManifestEntry{
@@ -329,9 +326,9 @@ func TestBuildDVIndex_RejectsMultipleDVsPerDataFile(t 
*testing.T) {
                        path:        "s3://bucket/data/dv-001.puffin",
                        contentType: iceberg.EntryContentPosDeletes,
                },
-               referencedDataFile: strPtr(dataFilePath),
-               contentOffset:      int64Ptr(0),
-               contentSizeInBytes: int64Ptr(128),
+               referencedDataFile: new(dataFilePath),
+               contentOffset:      new(int64(0)),
+               contentSizeInBytes: new(int64(128)),
        }
 
        dv2 := &dvMockDataFile{
@@ -339,9 +336,9 @@ func TestBuildDVIndex_RejectsMultipleDVsPerDataFile(t 
*testing.T) {
                        path:        "s3://bucket/data/dv-002.puffin",
                        contentType: iceberg.EntryContentPosDeletes,
                },
-               referencedDataFile: strPtr(dataFilePath),
-               contentOffset:      int64Ptr(256),
-               contentSizeInBytes: int64Ptr(64),
+               referencedDataFile: new(dataFilePath),
+               contentOffset:      new(int64(256)),
+               contentSizeInBytes: new(int64(64)),
        }
 
        dvEntries := []iceberg.ManifestEntry{
@@ -364,9 +361,9 @@ func TestMatchDVToData_SequenceNumberGuard(t *testing.T) {
                        path:        "s3://bucket/data/dv-001.puffin",
                        contentType: iceberg.EntryContentPosDeletes,
                },
-               referencedDataFile: strPtr(dataFilePath),
-               contentOffset:      int64Ptr(0),
-               contentSizeInBytes: int64Ptr(128),
+               referencedDataFile: new(dataFilePath),
+               contentOffset:      new(int64(0)),
+               contentSizeInBytes: new(int64(128)),
        }
 
        dvSeqNum := int64(5)
@@ -420,10 +417,10 @@ func TestMatchDVToData_NilDVSequenceNumber(t *testing.T) {
                dataSeq  *int64 // nil → unset
                expectDV bool
        }{
-               {"unset DV seq, real data seq — applies (regression)", nil, 
int64Ptr(7), true},
+               {"unset DV seq, real data seq — applies (regression)", nil, 
new(int64(7)), true},
                {"unset DV seq and unset data seq — applies", nil, nil, true},
-               {"known DV seq 0, newer data — skipped (guard stays tight)", 
int64Ptr(0), int64Ptr(5), false},
-               {"known DV seq 0, same data seq 0 — applies", int64Ptr(0), 
int64Ptr(0), true},
+               {"known DV seq 0, newer data — skipped (guard stays tight)", 
new(int64(0)), new(int64(5)), false},
+               {"known DV seq 0, same data seq 0 — applies", new(int64(0)), 
new(int64(0)), true},
        }
 
        for _, tt := range tests {
@@ -433,9 +430,9 @@ func TestMatchDVToData_NilDVSequenceNumber(t *testing.T) {
                                        path:        
"s3://bucket/data/dv-001.puffin",
                                        contentType: 
iceberg.EntryContentPosDeletes,
                                },
-                               referencedDataFile: strPtr(dataFilePath),
-                               contentOffset:      int64Ptr(0),
-                               contentSizeInBytes: int64Ptr(128),
+                               referencedDataFile: new(dataFilePath),
+                               contentOffset:      new(int64(0)),
+                               contentSizeInBytes: new(int64(128)),
                        }
                        dvEntries := []iceberg.ManifestEntry{
                                
iceberg.NewManifestEntry(iceberg.EntryStatusADDED, &snapshotID, tt.dvSeq, nil, 
dvFile),
@@ -470,9 +467,9 @@ func TestFileScanTask_DeletionVectorFilesField(t 
*testing.T) {
                        contentType: iceberg.EntryContentPosDeletes,
                        format:      iceberg.PuffinFile,
                },
-               referencedDataFile: strPtr("s3://bucket/data/data-001.parquet"),
-               contentOffset:      int64Ptr(0),
-               contentSizeInBytes: int64Ptr(128),
+               referencedDataFile: new("s3://bucket/data/data-001.parquet"),
+               contentOffset:      new(int64(0)),
+               contentSizeInBytes: new(int64(128)),
        }
 
        task := FileScanTask{
diff --git a/table/dv_scanner_read_test.go b/table/dv_scanner_read_test.go
index c466e3d30..ab94fba93 100644
--- a/table/dv_scanner_read_test.go
+++ b/table/dv_scanner_read_test.go
@@ -96,9 +96,9 @@ func newDVMockDataFile(puffinPath, referencedDataFile string, 
offset, contentSiz
                        format:      iceberg.PuffinFile,
                        count:       recordCount,
                },
-               referencedDataFile: strPtr(referencedDataFile),
-               contentOffset:      int64Ptr(offset),
-               contentSizeInBytes: int64Ptr(contentSize),
+               referencedDataFile: new(referencedDataFile),
+               contentOffset:      new(offset),
+               contentSizeInBytes: new(contentSize),
        }
 }
 
@@ -223,9 +223,9 @@ func TestLazyDeletionVectorLoaderReadPath(t *testing.T) {
                                contentType: iceberg.EntryContentPosDeletes,
                                format:      iceberg.PuffinFile,
                        },
-                       referencedDataFile: 
strPtr("file:///table/data/data.parquet"),
+                       referencedDataFile: 
new("file:///table/data/data.parquet"),
                        contentOffset:      nil,
-                       contentSizeInBytes: int64Ptr(42),
+                       contentSizeInBytes: new(int64(42)),
                }
 
                _, err := newLazyDeletionVectorLoader(fs, []FileScanTask{{
@@ -254,8 +254,8 @@ func TestLazyDeletionVectorLoaderReadPath(t *testing.T) {
                                contentType: iceberg.EntryContentPosDeletes,
                                format:      iceberg.PuffinFile,
                        },
-                       contentOffset:      int64Ptr(0),
-                       contentSizeInBytes: int64Ptr(0),
+                       contentOffset:      new(int64(0)),
+                       contentSizeInBytes: new(int64(0)),
                }
 
                var err error
diff --git a/table/incremental_append_scan_test.go 
b/table/incremental_append_scan_test.go
index e883b1484..a6ace522b 100644
--- a/table/incremental_append_scan_test.go
+++ b/table/incremental_append_scan_test.go
@@ -384,7 +384,7 @@ func incrementalAppendTestTable(t *testing.T) *Table {
 
        txn.meta.snapshotList = []Snapshot{
                {SnapshotID: 1, TimestampMs: 1000, ManifestList: 
"mem://default/table-location/metadata/snap-1.avro", SequenceNumber: 1, 
SchemaID: &schema.ID, Summary: &Summary{Operation: OpAppend}},
-               {SnapshotID: 2, ParentSnapshotID: int64Ptr(1), TimestampMs: 
2000, ManifestList: "mem://default/table-location/metadata/snap-2.avro", 
SequenceNumber: 2, SchemaID: &schema.ID, Summary: &Summary{Operation: 
OpAppend}},
+               {SnapshotID: 2, ParentSnapshotID: new(int64(1)), TimestampMs: 
2000, ManifestList: "mem://default/table-location/metadata/snap-2.avro", 
SequenceNumber: 2, SchemaID: &schema.ID, Summary: &Summary{Operation: 
OpAppend}},
        }
        txn.meta.snapshotLog = []SnapshotLogEntry{
                {SnapshotID: 1, TimestampMs: 1000},
@@ -461,8 +461,8 @@ func incrementalAppendMixedOperationTable(t *testing.T) 
*Table {
 
        txn.meta.snapshotList = []Snapshot{
                {SnapshotID: 1, TimestampMs: 1000, ManifestList: listAPath, 
SequenceNumber: 1, SchemaID: &schema.ID, Summary: &Summary{Operation: 
OpAppend}},
-               {SnapshotID: 2, ParentSnapshotID: int64Ptr(1), TimestampMs: 
2000, ManifestList: listBPath, SequenceNumber: 2, SchemaID: &schema.ID, 
Summary: &Summary{Operation: OpOverwrite}},
-               {SnapshotID: 3, ParentSnapshotID: int64Ptr(2), TimestampMs: 
3000, ManifestList: listCPath, SequenceNumber: 3, SchemaID: &schema.ID, 
Summary: &Summary{Operation: OpAppend}},
+               {SnapshotID: 2, ParentSnapshotID: new(int64(1)), TimestampMs: 
2000, ManifestList: listBPath, SequenceNumber: 2, SchemaID: &schema.ID, 
Summary: &Summary{Operation: OpOverwrite}},
+               {SnapshotID: 3, ParentSnapshotID: new(int64(2)), TimestampMs: 
3000, ManifestList: listCPath, SequenceNumber: 3, SchemaID: &schema.ID, 
Summary: &Summary{Operation: OpAppend}},
        }
        txn.meta.snapshotLog = []SnapshotLogEntry{
                {SnapshotID: 1, TimestampMs: 1000},
@@ -532,8 +532,8 @@ func incrementalAppendDivergentTable(t *testing.T) *Table {
        snapshots := []*Snapshot{
                {SnapshotID: 10, TimestampMs: baseTimestamp + 1, 
SequenceNumber: 1, Summary: &Summary{Operation: OpAppend}},
                {SnapshotID: 20, TimestampMs: baseTimestamp + 2, 
SequenceNumber: 2, Summary: &Summary{Operation: OpAppend}},
-               {SnapshotID: 21, ParentSnapshotID: int64Ptr(20), TimestampMs: 
baseTimestamp + 3, SequenceNumber: 3, Summary: &Summary{Operation: OpAppend}},
-               {SnapshotID: 22, ParentSnapshotID: int64Ptr(21), TimestampMs: 
baseTimestamp + 4, SequenceNumber: 4, Summary: &Summary{Operation: OpAppend}},
+               {SnapshotID: 21, ParentSnapshotID: new(int64(20)), TimestampMs: 
baseTimestamp + 3, SequenceNumber: 3, Summary: &Summary{Operation: OpAppend}},
+               {SnapshotID: 22, ParentSnapshotID: new(int64(21)), TimestampMs: 
baseTimestamp + 4, SequenceNumber: 4, Summary: &Summary{Operation: OpAppend}},
        }
        for _, snapshot := range snapshots {
                require.NoError(t, builder.AddSnapshot(snapshot))
@@ -615,7 +615,7 @@ func incrementalAppendExpiredExclusiveTable(t *testing.T) 
*Table {
                },
                {
                        SnapshotID:       3,
-                       ParentSnapshotID: int64Ptr(2),
+                       ParentSnapshotID: new(int64(2)),
                        TimestampMs:      3000,
                        ManifestList:     manifestListCPath,
                        SequenceNumber:   3,
diff --git a/table/incremental_changelog_scan_test.go 
b/table/incremental_changelog_scan_test.go
index 75c960e38..f94e67f09 100644
--- a/table/incremental_changelog_scan_test.go
+++ b/table/incremental_changelog_scan_test.go
@@ -463,8 +463,8 @@ func incrementalChangelogDivergentTable(t *testing.T) 
*Table {
        baseTimestamp := base.LastUpdatedMillis()
        snapshots := []*Snapshot{
                {SnapshotID: 1, TimestampMs: baseTimestamp + 1, SequenceNumber: 
1, Summary: &Summary{Operation: OpAppend}},
-               {SnapshotID: 2, ParentSnapshotID: int64Ptr(1), TimestampMs: 
baseTimestamp + 2, SequenceNumber: 2, Summary: &Summary{Operation: OpAppend}},
-               {SnapshotID: 3, ParentSnapshotID: int64Ptr(1), TimestampMs: 
baseTimestamp + 3, SequenceNumber: 3, Summary: &Summary{Operation: OpAppend}},
+               {SnapshotID: 2, ParentSnapshotID: new(int64(1)), TimestampMs: 
baseTimestamp + 2, SequenceNumber: 2, Summary: &Summary{Operation: OpAppend}},
+               {SnapshotID: 3, ParentSnapshotID: new(int64(1)), TimestampMs: 
baseTimestamp + 3, SequenceNumber: 3, Summary: &Summary{Operation: OpAppend}},
        }
        for _, snapshot := range snapshots {
                require.NoError(t, builder.AddSnapshot(snapshot))
@@ -555,9 +555,9 @@ func incrementalChangelogTestTable(t *testing.T) *Table {
 
        txn.meta.snapshotList = []Snapshot{
                {SnapshotID: 1, TimestampMs: 1000, ManifestList: listOnePath, 
SequenceNumber: 1, SchemaID: &schema.ID, Summary: &Summary{Operation: 
OpAppend}},
-               {SnapshotID: 2, ParentSnapshotID: int64Ptr(1), TimestampMs: 
2000, ManifestList: listTwoPath, SequenceNumber: 2, SchemaID: &schema.ID, 
Summary: &Summary{Operation: OpOverwrite}},
-               {SnapshotID: 3, ParentSnapshotID: int64Ptr(2), TimestampMs: 
3000, ManifestList: listThreePath, SequenceNumber: 3, SchemaID: &schema.ID, 
Summary: &Summary{Operation: OpReplace}},
-               {SnapshotID: 4, ParentSnapshotID: int64Ptr(3), TimestampMs: 
4000, ManifestList: listFourPath, SequenceNumber: 4, SchemaID: &schema.ID, 
Summary: &Summary{Operation: OpAppend}},
+               {SnapshotID: 2, ParentSnapshotID: new(int64(1)), TimestampMs: 
2000, ManifestList: listTwoPath, SequenceNumber: 2, SchemaID: &schema.ID, 
Summary: &Summary{Operation: OpOverwrite}},
+               {SnapshotID: 3, ParentSnapshotID: new(int64(2)), TimestampMs: 
3000, ManifestList: listThreePath, SequenceNumber: 3, SchemaID: &schema.ID, 
Summary: &Summary{Operation: OpReplace}},
+               {SnapshotID: 4, ParentSnapshotID: new(int64(3)), TimestampMs: 
4000, ManifestList: listFourPath, SequenceNumber: 4, SchemaID: &schema.ID, 
Summary: &Summary{Operation: OpAppend}},
        }
        txn.meta.snapshotLog = []SnapshotLogEntry{
                {SnapshotID: 1, TimestampMs: 1000},
@@ -659,9 +659,9 @@ func incrementalChangelogManifestRewriteTable(t *testing.T) 
*Table {
 
        txn.meta.snapshotList = []Snapshot{
                {SnapshotID: 1, TimestampMs: 1000, ManifestList: listOnePath, 
SequenceNumber: 1, SchemaID: &schema.ID, Summary: &Summary{Operation: 
OpAppend}},
-               {SnapshotID: 2, ParentSnapshotID: int64Ptr(1), TimestampMs: 
2000, ManifestList: listTwoPath, SequenceNumber: 2, SchemaID: &schema.ID, 
Summary: &Summary{Operation: OpAppend}},
-               {SnapshotID: 3, ParentSnapshotID: int64Ptr(2), TimestampMs: 
3000, ManifestList: listThreePath, SequenceNumber: 3, SchemaID: &schema.ID, 
Summary: &Summary{Operation: OpReplace}},
-               {SnapshotID: 4, ParentSnapshotID: int64Ptr(3), TimestampMs: 
4000, ManifestList: listFourPath, SequenceNumber: 4, SchemaID: &schema.ID, 
Summary: &Summary{Operation: OpAppend}},
+               {SnapshotID: 2, ParentSnapshotID: new(int64(1)), TimestampMs: 
2000, ManifestList: listTwoPath, SequenceNumber: 2, SchemaID: &schema.ID, 
Summary: &Summary{Operation: OpAppend}},
+               {SnapshotID: 3, ParentSnapshotID: new(int64(2)), TimestampMs: 
3000, ManifestList: listThreePath, SequenceNumber: 3, SchemaID: &schema.ID, 
Summary: &Summary{Operation: OpReplace}},
+               {SnapshotID: 4, ParentSnapshotID: new(int64(3)), TimestampMs: 
4000, ManifestList: listFourPath, SequenceNumber: 4, SchemaID: &schema.ID, 
Summary: &Summary{Operation: OpAppend}},
        }
        txn.meta.snapshotLog = []SnapshotLogEntry{
                {SnapshotID: 1, TimestampMs: 1000},
@@ -750,8 +750,8 @@ func incrementalChangelogDeleteManifestTable(t *testing.T) 
*Table {
 
        txn.meta.snapshotList = []Snapshot{
                {SnapshotID: 1, TimestampMs: 1000, ManifestList: listOnePath, 
SequenceNumber: 1, SchemaID: &schema.ID, Summary: &Summary{Operation: 
OpAppend}},
-               {SnapshotID: 2, ParentSnapshotID: int64Ptr(1), TimestampMs: 
2000, ManifestList: listTwoPath, SequenceNumber: 2, SchemaID: &schema.ID, 
Summary: &Summary{Operation: OpDelete}},
-               {SnapshotID: 3, ParentSnapshotID: int64Ptr(2), TimestampMs: 
3000, ManifestList: listThreePath, SequenceNumber: 3, SchemaID: &schema.ID, 
Summary: &Summary{Operation: OpAppend}},
+               {SnapshotID: 2, ParentSnapshotID: new(int64(1)), TimestampMs: 
2000, ManifestList: listTwoPath, SequenceNumber: 2, SchemaID: &schema.ID, 
Summary: &Summary{Operation: OpDelete}},
+               {SnapshotID: 3, ParentSnapshotID: new(int64(2)), TimestampMs: 
3000, ManifestList: listThreePath, SequenceNumber: 3, SchemaID: &schema.ID, 
Summary: &Summary{Operation: OpAppend}},
        }
        txn.meta.snapshotLog = []SnapshotLogEntry{
                {SnapshotID: 1, TimestampMs: 1000},
diff --git a/table/inspect_internal_test.go b/table/inspect_internal_test.go
index 57c992cd6..55de0c4cf 100644
--- a/table/inspect_internal_test.go
+++ b/table/inspect_internal_test.go
@@ -92,8 +92,8 @@ func inspectTestTable(identifier Identifier, snapshotRefs 
map[string]SnapshotRef
                Props:           iceberg.Properties{},
                SnapshotList: []Snapshot{
                        {SnapshotID: s1, TimestampMs: 1100, ManifestList: 
"/snap-101.avro"},
-                       {SnapshotID: s2, ParentSnapshotID: int64Ptr(s1), 
TimestampMs: 1200, ManifestList: "/snap-102.avro"},
-                       {SnapshotID: s3, ParentSnapshotID: int64Ptr(s1), 
TimestampMs: 1300, ManifestList: "/snap-103.avro"},
+                       {SnapshotID: s2, ParentSnapshotID: new(s1), 
TimestampMs: 1200, ManifestList: "/snap-102.avro"},
+                       {SnapshotID: s3, ParentSnapshotID: new(s1), 
TimestampMs: 1300, ManifestList: "/snap-103.avro"},
                },
                CurrentSnapshotID: &current,
                SnapshotLog: []SnapshotLogEntry{
@@ -514,7 +514,7 @@ func snapshotsTestTable() *Table {
                                },
                        },
                        // s2 intentionally carries no summary and no 
manifest-list path.
-                       {SnapshotID: s2, ParentSnapshotID: int64Ptr(s1), 
TimestampMs: 1200},
+                       {SnapshotID: s2, ParentSnapshotID: new(s1), 
TimestampMs: 1200},
                },
                CurrentSnapshotID:  &current,
                SortOrderList:      []SortOrder{UnsortedSortOrder},
@@ -948,7 +948,7 @@ func TestInspectDeleteFiles(t *testing.T) {
        entry := func(status iceberg.ManifestEntryStatus, file 
iceberg.DataFile) iceberg.ManifestEntry {
                sequenceNumber := int64(1)
 
-               return iceberg.NewManifestEntry(status, int64Ptr(snapshotID), 
&sequenceNumber, &sequenceNumber, file)
+               return iceberg.NewManifestEntry(status, new(snapshotID), 
&sequenceNumber, &sequenceNumber, file)
        }
        tbl := inspectFilesTableWithManifests(t, spec,
                inspectManifestSpec{
@@ -1312,7 +1312,7 @@ func TestInspectManifests(t *testing.T) {
                "mem://default/table-location/data/data.parquet", 
map[int]any{1000: int32(7)}, 3)
        sequenceNumber := int64(1)
        entry := iceberg.NewManifestEntry(
-               iceberg.EntryStatusADDED, int64Ptr(snapshotID), 
&sequenceNumber, &sequenceNumber, file)
+               iceberg.EntryStatusADDED, new(snapshotID), &sequenceNumber, 
&sequenceNumber, file)
 
        manifestPath := 
"mem://default/table-location/metadata/data-manifest.avro"
        manifestListPath := 
"mem://default/table-location/metadata/snap-1-manifest-list.avro"
@@ -1999,7 +1999,7 @@ func inspectDataFileEntries(t *testing.T, spec 
iceberg.PartitionSpec, count int)
                file := newTestDataFile(t, spec, path, nil)
                sequenceNumber := int64(1)
                entries = append(entries, iceberg.NewManifestEntry(
-                       iceberg.EntryStatusADDED, int64Ptr(snapshotID), 
&sequenceNumber, &sequenceNumber, file))
+                       iceberg.EntryStatusADDED, new(snapshotID), 
&sequenceNumber, &sequenceNumber, file))
        }
 
        return entries
@@ -2340,13 +2340,13 @@ func 
TestInspectDataFilesStreamsBatchesAndSkipsDeleted(t *testing.T) {
                        
"mem://default/table-location/data/live-"+strconv.Itoa(index)+".parquet", nil)
                sequenceNumber := int64(1)
                entries = append(entries, iceberg.NewManifestEntry(
-                       iceberg.EntryStatusADDED, int64Ptr(snapshotID), 
&sequenceNumber, &sequenceNumber, file))
+                       iceberg.EntryStatusADDED, new(snapshotID), 
&sequenceNumber, &sequenceNumber, file))
        }
        deletedPath := "mem://default/table-location/data/deleted.parquet"
        deleted := newTestDataFile(t, spec, deletedPath, nil)
        deletedSequenceNumber := int64(1)
        entries = append(entries, iceberg.NewManifestEntry(
-               iceberg.EntryStatusDELETED, int64Ptr(snapshotID), 
&deletedSequenceNumber, &deletedSequenceNumber, deleted))
+               iceberg.EntryStatusDELETED, new(snapshotID), 
&deletedSequenceNumber, &deletedSequenceNumber, deleted))
 
        manifestPath := 
"mem://default/table-location/metadata/data-manifest.avro"
        manifestListPath := 
"mem://default/table-location/metadata/snap-1-manifest-list.avro"
@@ -2400,7 +2400,7 @@ func TestInspectDataFilesReturnsPartitionValues(t 
*testing.T) {
                "mem://default/table-location/data/partitioned.parquet", 
map[int]any{1000: int32(7)})
        sequenceNumber := int64(1)
        entry := iceberg.NewManifestEntry(
-               iceberg.EntryStatusADDED, int64Ptr(snapshotID), 
&sequenceNumber, &sequenceNumber, file)
+               iceberg.EntryStatusADDED, new(snapshotID), &sequenceNumber, 
&sequenceNumber, file)
        tbl := inspectDataFilesTable(t, spec, []iceberg.ManifestEntry{entry})
 
        rr, err := tbl.Inspect().DataFiles(context.Background())
@@ -2423,7 +2423,7 @@ func 
TestInspectDataFilesEmitsEmptyBatchWhenAllEntriesAreDeleted(t *testing.T) {
                "mem://default/table-location/data/deleted.parquet", nil)
        sequenceNumber := int64(1)
        entry := iceberg.NewManifestEntry(
-               iceberg.EntryStatusDELETED, int64Ptr(snapshotID), 
&sequenceNumber, &sequenceNumber, file)
+               iceberg.EntryStatusDELETED, new(snapshotID), &sequenceNumber, 
&sequenceNumber, file)
        tbl := inspectDataFilesTable(t, spec, []iceberg.ManifestEntry{entry})
 
        rr, err := tbl.Inspect().DataFiles(context.Background())
@@ -2764,7 +2764,7 @@ func TestInspectPartitionsAggregatesDataAndDeletes(t 
*testing.T) {
        dataEntries := make([]iceberg.ManifestEntry, 0, len(dataFiles))
        for _, file := range dataFiles {
                dataEntries = append(dataEntries, iceberg.NewManifestEntry(
-                       iceberg.EntryStatusADDED, int64Ptr(snapshotID), 
&dataSequenceNumber, &dataSequenceNumber, file))
+                       iceberg.EntryStatusADDED, new(snapshotID), 
&dataSequenceNumber, &dataSequenceNumber, file))
        }
 
        dataManifestPath := 
"mem://default/table-location/metadata/data-manifest.avro"
@@ -2795,9 +2795,9 @@ func TestInspectPartitionsAggregatesDataAndDeletes(t 
*testing.T) {
                
iceberg.WithManifestWriterContent(iceberg.ManifestContentDeletes))
        require.NoError(t, err)
        require.NoError(t, deleteWriter.Add(iceberg.NewManifestEntry(
-               iceberg.EntryStatusADDED, int64Ptr(snapshotID), 
&dataSequenceNumber, &dataSequenceNumber, deleteFile)))
+               iceberg.EntryStatusADDED, new(snapshotID), &dataSequenceNumber, 
&dataSequenceNumber, deleteFile)))
        require.NoError(t, deleteWriter.Add(iceberg.NewManifestEntry(
-               iceberg.EntryStatusADDED, int64Ptr(snapshotID), 
&dataSequenceNumber, &dataSequenceNumber, equalityDeleteFile)))
+               iceberg.EntryStatusADDED, new(snapshotID), &dataSequenceNumber, 
&dataSequenceNumber, equalityDeleteFile)))
        require.NoError(t, deleteWriter.Close())
        deleteManifest, err := deleteWriter.ToManifestFile(deleteManifestPath, 
int64(deleteManifestBuf.Len()),
                iceberg.WithManifestFileContent(iceberg.ManifestContentDeletes))
@@ -2817,7 +2817,7 @@ func TestInspectPartitionsAggregatesDataAndDeletes(t 
*testing.T) {
                SequenceNumber: manifestListSequenceNumber,
                TimestampMs:    2000,
        }}
-       txn.meta.currentSnapshotID = int64Ptr(snapshotID)
+       txn.meta.currentSnapshotID = new(snapshotID)
        built, err := txn.meta.Build()
        require.NoError(t, err)
 
@@ -2862,7 +2862,7 @@ func 
TestInspectPartitionsLeavesSpecIDUnsetForExpiredSnapshot(t *testing.T) {
        var manifestBuf bytes.Buffer
        _, err := iceberg.WriteManifest(manifestPath, &manifestBuf, 2, spec, 
schema, expiredSnapshotID,
                []iceberg.ManifestEntry{iceberg.NewManifestEntry(
-                       iceberg.EntryStatusADDED, int64Ptr(expiredSnapshotID), 
&sequenceNumber, &sequenceNumber, file)})
+                       iceberg.EntryStatusADDED, new(expiredSnapshotID), 
&sequenceNumber, &sequenceNumber, file)})
        require.NoError(t, err)
        require.NoError(t, memIO.WriteFile(manifestPath, manifestBuf.Bytes()))
        manifest := iceberg.NewManifestFile(2, manifestPath, 
int64(manifestBuf.Len()), int32(spec.ID()), expiredSnapshotID).
@@ -2884,7 +2884,7 @@ func 
TestInspectPartitionsLeavesSpecIDUnsetForExpiredSnapshot(t *testing.T) {
                SequenceNumber: currentSequenceNumber,
                TimestampMs:    2000,
        }}
-       txn.meta.currentSnapshotID = int64Ptr(currentSnapshotID)
+       txn.meta.currentSnapshotID = new(currentSnapshotID)
        built, err := txn.meta.Build()
        require.NoError(t, err)
 
@@ -2952,8 +2952,8 @@ func TestInspectEntriesIncludesDeletedEntries(t 
*testing.T) {
                "mem://default/table-location/data/deleted.parquet", nil)
        sequenceNumber := int64(1)
        entries := []iceberg.ManifestEntry{
-               iceberg.NewManifestEntry(iceberg.EntryStatusADDED, 
int64Ptr(snapshotID), &sequenceNumber, &sequenceNumber, addedFile),
-               iceberg.NewManifestEntry(iceberg.EntryStatusDELETED, 
int64Ptr(snapshotID), &sequenceNumber, &sequenceNumber, deletedFile),
+               iceberg.NewManifestEntry(iceberg.EntryStatusADDED, 
new(snapshotID), &sequenceNumber, &sequenceNumber, addedFile),
+               iceberg.NewManifestEntry(iceberg.EntryStatusDELETED, 
new(snapshotID), &sequenceNumber, &sequenceNumber, deletedFile),
        }
 
        manifestPath := 
"mem://default/table-location/metadata/data-manifest.avro"
@@ -2973,7 +2973,7 @@ func TestInspectEntriesIncludesDeletedEntries(t 
*testing.T) {
                ManifestList:   manifestListPath,
                SequenceNumber: sequenceNumber,
        }}
-       txn.meta.currentSnapshotID = int64Ptr(snapshotID)
+       txn.meta.currentSnapshotID = new(snapshotID)
        built, err := txn.meta.Build()
        require.NoError(t, err)
 
diff --git a/table/metadata_builder_internal_test.go 
b/table/metadata_builder_internal_test.go
index 64b1135d9..b0a881249 100644
--- a/table/metadata_builder_internal_test.go
+++ b/table/metadata_builder_internal_test.go
@@ -1083,7 +1083,7 @@ func TestRemoveSnapshotsPrunesSnapshotLogHistory(t 
*testing.T) {
                {SnapshotID: snapshot2ID, TimestampMs: baseTimestamp + 2},
                {SnapshotID: snapshot3ID, TimestampMs: baseTimestamp + 3},
        }
-       builder.currentSnapshotID = ptr(snapshot3ID)
+       builder.currentSnapshotID = new(snapshot3ID)
        builder.refs = map[string]SnapshotRef{
                MainBranch: {SnapshotID: snapshot3ID, SnapshotRefType: 
BranchRef},
        }
@@ -1219,7 +1219,7 @@ func TestRemoveSnapshotsWithCurrentSnapshotAndEmptyLog(t 
*testing.T) {
                        LastPartitionID:   &lastPartitionID,
                        Props:             iceberg.Properties{},
                        SnapshotList:      []Snapshot{{SnapshotID: removedID}, 
{SnapshotID: currentID}},
-                       CurrentSnapshotID: ptr(currentID),
+                       CurrentSnapshotID: new(currentID),
                        SnapshotLog:       []SnapshotLogEntry{},
                        SortOrderList:     []SortOrder{UnsortedSortOrder},
                        SnapshotRefs: map[string]SnapshotRef{
@@ -3796,8 +3796,8 @@ func fillNonZero(v reflect.Value, seen 
map[reflect.Type]bool) bool {
                return true
        case reflect.Struct:
                filled := false
-               for i := range v.NumField() {
-                       if fillNonZero(fieldValue(v.Field(i)), seen) {
+               for _, field := range v.Fields() {
+                       if fillNonZero(fieldValue(field), seen) {
                                filled = true
                        }
                }
diff --git a/table/pos_delete_partitioned_fanout_writer_test.go 
b/table/pos_delete_partitioned_fanout_writer_test.go
index 08d3aae2f..17229dd19 100644
--- a/table/pos_delete_partitioned_fanout_writer_test.go
+++ b/table/pos_delete_partitioned_fanout_writer_test.go
@@ -736,10 +736,6 @@ func (m *dataFileMatcher) Format(val iceberg.DataFile) 
string {
 // defaultPositionDeleteMatching is a convenience preset for the options we 
want to match for position delete matching
 var defaultPositionDeleteMatching = 
[]dataFileMatcherOption{withContentTypeMatching(), withColumnSizesMatching(), 
withCountMatching(), withFileFormatMatching(), withSpecIDMatching(), 
withPartitionMatching(), withCountMatching(), withSortOrderIDMatching()}
 
-// ptr returns a pointer to v. A generic stand-in for the various one-off
-// ptr-helpers previously sprinkled across the internal package tests.
-func ptr[T any](v T) *T { return &v }
-
 // Position deletes are ordered by (file_path, pos), never by a table sort
 // order, so their sort order id stays null.
 func TestPositionDeleteUnpartitionedSortOrderID(t *testing.T) {
diff --git a/table/rebuild_manifest_test.go b/table/rebuild_manifest_test.go
index b6df27e95..5a68ef99c 100644
--- a/table/rebuild_manifest_test.go
+++ b/table/rebuild_manifest_test.go
@@ -174,8 +174,8 @@ func TestStagedSnapshotStillValid(t *testing.T) {
                {"v1 ignores sequence numbers", v1, &Snapshot{}, true},
                {"v2 sequence number ahead", v2, &Snapshot{SequenceNumber: 
v2.LastSequenceNumber() + 1}, true},
                {"v2 sequence number equal", v2, &Snapshot{SequenceNumber: 
v2.LastSequenceNumber()}, false},
-               {"v3 first-row-id at the cursor", v3, &Snapshot{SequenceNumber: 
v3.LastSequenceNumber() + 1, FirstRowID: ptr(v3.NextRowID())}, true},
-               {"v3 first-row-id behind", v3, &Snapshot{SequenceNumber: 
v3.LastSequenceNumber() + 1, FirstRowID: ptr(v3.NextRowID() - 1)}, false},
+               {"v3 first-row-id at the cursor", v3, &Snapshot{SequenceNumber: 
v3.LastSequenceNumber() + 1, FirstRowID: new(v3.NextRowID())}, true},
+               {"v3 first-row-id behind", v3, &Snapshot{SequenceNumber: 
v3.LastSequenceNumber() + 1, FirstRowID: new(v3.NextRowID() - 1)}, false},
                {"v3 first-row-id missing", v3, &Snapshot{SequenceNumber: 
v3.LastSequenceNumber() + 1}, false},
                {"nil fresh metadata", nil, &Snapshot{}, true},
        }
@@ -512,7 +512,7 @@ func TestRebuildFn_SummaryRebasedAgainstFreshParent(t 
*testing.T) {
        parentManifestListPath := 
"mem://default/table-location/metadata/fresh-parent-snap.avro"
        out, createErr := wfs.Create(parentManifestListPath)
        require.NoError(t, createErr)
-       writeErr := iceberg.WriteManifestList(2, out, 77, nil, ptr(int64(0)), 
0, nil)
+       writeErr := iceberg.WriteManifestList(2, out, 77, nil, new(int64(0)), 
0, nil)
        require.NoError(t, writeErr)
        require.NoError(t, out.Close())
 
diff --git a/table/requirement_test.go b/table/requirement_test.go
index 0e580093c..19b41f7ac 100644
--- a/table/requirement_test.go
+++ b/table/requirement_test.go
@@ -228,7 +228,7 @@ func TestParseRequirementAcceptsExplicitZero(t *testing.T) {
                {name: "default sort order id", data: 
`{"type":"assert-default-sort-order-id","default-sort-order-id":0}`, expected: 
table.AssertDefaultSortOrderID(0)},
                {name: "last assigned field id", data: 
`{"type":"assert-last-assigned-field-id","last-assigned-field-id":0}`, 
expected: table.AssertLastAssignedFieldID(0)},
                {name: "last assigned partition id", data: 
`{"type":"assert-last-assigned-partition-id","last-assigned-partition-id":0}`, 
expected: table.AssertLastAssignedPartitionID(0)},
-               {name: "snapshot id", data: 
`{"type":"assert-ref-snapshot-id","ref":"main","snapshot-id":0}`, expected: 
table.AssertRefSnapshotID("main", ptr(int64(0)))},
+               {name: "snapshot id", data: 
`{"type":"assert-ref-snapshot-id","ref":"main","snapshot-id":0}`, expected: 
table.AssertRefSnapshotID("main", new(int64(0)))},
        }
 
        for _, tt := range tests {
@@ -261,7 +261,7 @@ func 
TestParseRequirementRefRequiresRefButAllowsNullSnapshotID(t *testing.T) {
 func TestParseRequirementRefAcceptsNumericSnapshotID(t *testing.T) {
        actual, err := 
table.ParseRequirementBytes([]byte(`{"type":"assert-ref-snapshot-id","ref":"main","snapshot-id":42}`))
        require.NoError(t, err)
-       assert.Equal(t, table.AssertRefSnapshotID("main", ptr(int64(42))), 
actual)
+       assert.Equal(t, table.AssertRefSnapshotID("main", new(int64(42))), 
actual)
 }
 
 func TestAssertRefSnapshotIDValidate(t *testing.T) {
@@ -269,12 +269,12 @@ func TestAssertRefSnapshotIDValidate(t *testing.T) {
        require.NoError(t, err)
 
        t.Run("matching ref passes", func(t *testing.T) {
-               req := table.AssertRefSnapshotID("test", 
ptr(int64(3051729675574597004)))
+               req := table.AssertRefSnapshotID("test", 
new(int64(3051729675574597004)))
                assert.NoError(t, req.Validate(meta))
        })
 
        t.Run("mismatched snapshot id includes expected and found", func(t 
*testing.T) {
-               req := table.AssertRefSnapshotID("test", ptr(int64(1)))
+               req := table.AssertRefSnapshotID("test", new(int64(1)))
                err := req.Validate(meta)
                require.Error(t, err)
                assert.Contains(t, err.Error(), `"test"`)
@@ -292,7 +292,7 @@ func TestAssertRefSnapshotIDValidate(t *testing.T) {
        })
 
        t.Run("ref missing but expected includes expected snapshot", func(t 
*testing.T) {
-               req := table.AssertRefSnapshotID("nonexistent", ptr(int64(42)))
+               req := table.AssertRefSnapshotID("nonexistent", new(int64(42)))
                err := req.Validate(meta)
                require.Error(t, err)
                assert.Contains(t, err.Error(), `"nonexistent"`)
@@ -301,7 +301,7 @@ func TestAssertRefSnapshotIDValidate(t *testing.T) {
        })
 
        t.Run("nil metadata returns error", func(t *testing.T) {
-               req := table.AssertRefSnapshotID("main", ptr(int64(1)))
+               req := table.AssertRefSnapshotID("main", new(int64(1)))
                assert.Error(t, req.Validate(nil))
        })
 
diff --git a/table/scan_metrics_test.go b/table/scan_metrics_test.go
index 9a566fee7..0ed2f6118 100644
--- a/table/scan_metrics_test.go
+++ b/table/scan_metrics_test.go
@@ -174,8 +174,8 @@ func TestApplyResultDeleteMetrics(t *testing.T) {
        // the whole Puffin file size, so filesize (the Puffin length) must be 
ignored.
        dv := &dvMockDataFile{
                mockDataFile:       mockDataFile{path: "s3://b/deletes.puffin", 
filesize: 9999},
-               referencedDataFile: strPtr("s3://b/data-2.parquet"),
-               contentSizeInBytes: int64Ptr(10),
+               referencedDataFile: new("s3://b/data-2.parquet"),
+               contentSizeInBytes: new(int64(10)),
        }
 
        // posA applies to both data-file tasks: matching Java's per-task
@@ -216,12 +216,12 @@ func TestApplyResultDeleteMetricsDVsShareOnePuffin(t 
*testing.T) {
        dv1 := &dvMockDataFile{
                mockDataFile:       mockDataFile{path: puffin, filesize: 9999},
                referencedDataFile: &ref1,
-               contentSizeInBytes: int64Ptr(30),
+               contentSizeInBytes: new(int64(30)),
        }
        dv2 := &dvMockDataFile{
                mockDataFile:       mockDataFile{path: puffin, filesize: 9999},
                referencedDataFile: &ref2,
-               contentSizeInBytes: int64Ptr(70),
+               contentSizeInBytes: new(int64(70)),
        }
 
        tasks := []FileScanTask{
@@ -303,7 +303,7 @@ func TestPlanFilesEmitsReportForRealSnapshot(t *testing.T) {
 
        df := newTestDataFile(t, spec, 
"mem://default/table-location/data-1.parquet", nil)
        entries := []iceberg.ManifestEntry{
-               iceberg.NewManifestEntry(iceberg.EntryStatusADDED, 
int64Ptr(snapshotID), nil, nil, df),
+               iceberg.NewManifestEntry(iceberg.EntryStatusADDED, 
new(snapshotID), nil, nil, df),
        }
        var manifestBuf bytes.Buffer
        manifest, err := iceberg.WriteManifest(manifestPath, &manifestBuf, 2, 
spec, schema, snapshotID, entries)
diff --git a/table/scan_planning.go b/table/scan_planning.go
index c41fca5ad..4b6a12162 100644
--- a/table/scan_planning.go
+++ b/table/scan_planning.go
@@ -76,7 +76,7 @@ type ScanPlanningMetadata interface {
 
 // Compile-time guard that the full Metadata interface still satisfies the
 // narrowed planner view, so callers can pass a table.Metadata directly.
-var _ ScanPlanningMetadata = (Metadata)(nil)
+var _ ScanPlanningMetadata = Metadata(nil)
 
 // Compile-time guard that Scan exposes the lifecycle contract as io.Closer.
 var _ io.Closer = (*Scan)(nil)
diff --git a/table/scanner_empty_manifest_bench_test.go 
b/table/scanner_empty_manifest_bench_test.go
index 1d21f6f5f..af4634343 100644
--- a/table/scanner_empty_manifest_bench_test.go
+++ b/table/scanner_empty_manifest_bench_test.go
@@ -105,7 +105,7 @@ func newEmptyManifestBenchmarkTable(
 
        manifestListPath := tableLocation + "/metadata/snap-1.avro"
        var listBuf bytes.Buffer
-       require.NoError(b, iceberg.WriteManifestList(2, &listBuf, snapshotID, 
nil, ptr(sequenceNum), 0, manifests))
+       require.NoError(b, iceberg.WriteManifestList(2, &listBuf, snapshotID, 
nil, new(sequenceNum), 0, manifests))
        require.NoError(b, fs.WriteFile(manifestListPath, listBuf.Bytes()))
 
        meta, err := NewMetadata(schema, &spec, UnsortedSortOrder, 
tableLocation, nil)
diff --git a/table/scanner_manifest_entries_bench_test.go 
b/table/scanner_manifest_entries_bench_test.go
index 71caf1493..58651f6d3 100644
--- a/table/scanner_manifest_entries_bench_test.go
+++ b/table/scanner_manifest_entries_bench_test.go
@@ -146,9 +146,9 @@ func benchmarkManifestEntries(count int, content 
iceberg.ManifestContent) []iceb
                        &mockDataFile{path: "eq-delete.parquet", contentType: 
iceberg.EntryContentEqDeletes},
                        &dvMockDataFile{
                                mockDataFile:       mockDataFile{path: 
"dv.puffin", contentType: iceberg.EntryContentPosDeletes, format: 
iceberg.PuffinFile},
-                               referencedDataFile: strPtr("data.parquet"),
-                               contentOffset:      int64Ptr(0),
-                               contentSizeInBytes: int64Ptr(128),
+                               referencedDataFile: new("data.parquet"),
+                               contentOffset:      new(int64(0)),
+                               contentSizeInBytes: new(int64(128)),
                        },
                }
        }
diff --git a/table/snapshot_producers.go b/table/snapshot_producers.go
index 490fb2528..9cb0b1dd9 100644
--- a/table/snapshot_producers.go
+++ b/table/snapshot_producers.go
@@ -1762,16 +1762,16 @@ func (sp *snapshotProducer) 
commitManifests(newManifests, addedContent []iceberg
        // creates it).
        baseHeadID := sp.txn.baseRefSnapshotID(branch)
 
-       return []Update{
-                       addSnap,
-                       // Carry over the branch's existing retention settings 
so advancing
-                       // the ref on commit does not silently discard them. 
The update
-                       // encodes exactly the current ref's retention 
(settings the branch
-                       // lacks stay 0 and are dropped by the `omitempty` 
tags); the catalog
-                       // applies a set-snapshot-ref as a pure replace, so 
this fully
-                       // determines the resulting ref rather than merging 
with the old one.
-                       sp.txn.meta.NewRetainingSnapshotRefUpdate(branch, 
sp.snapshotID, BranchRef),
-               }, []Requirement{
-                       AssertRefSnapshotID(branch, baseHeadID),
-               }, nil
+       updates := []Update{
+               addSnap,
+               // Carry over the branch's existing retention settings so 
advancing
+               // the ref on commit does not silently discard them. The update
+               // encodes exactly the current ref's retention (settings the 
branch
+               // lacks stay 0 and are dropped by the `omitempty` tags); the 
catalog
+               // applies a set-snapshot-ref as a pure replace, so this fully
+               // determines the resulting ref rather than merging with the 
old one.
+               sp.txn.meta.NewRetainingSnapshotRefUpdate(branch, 
sp.snapshotID, BranchRef),
+       }
+
+       return updates, []Requirement{AssertRefSnapshotID(branch, baseHeadID)}, 
nil
 }
diff --git a/table/snapshot_producers_test.go b/table/snapshot_producers_test.go
index 47e60e13d..f69bdd1a9 100644
--- a/table/snapshot_producers_test.go
+++ b/table/snapshot_producers_test.go
@@ -976,7 +976,7 @@ func TestRebuildManifestListSummaryFailureCreatesNoOutput(t 
*testing.T) {
        parentManifestList := 
"mem://default/table-location/metadata/fresh-parent.avro"
        out, err := wfs.Create(parentManifestList)
        require.NoError(t, err)
-       require.NoError(t, iceberg.WriteManifestList(2, out, 77, nil, 
ptr(int64(0)), 0, nil))
+       require.NoError(t, iceberg.WriteManifestList(2, out, 77, nil, 
new(int64(0)), 0, nil))
        require.NoError(t, out.Close())
 
        sp.op = Operation("unsupported")
@@ -1924,7 +1924,7 @@ func TestSummaryOnRetry_SkipsAlreadyRemovedDeleteFile(t 
*testing.T) {
        parentManifestList := 
"mem://default/table-location/metadata/fresh-parent-skip.avro"
        out, err := wfs.Create(parentManifestList)
        require.NoError(t, err)
-       require.NoError(t, iceberg.WriteManifestList(2, out, 77, nil, 
ptr(int64(0)), 0, nil))
+       require.NoError(t, iceberg.WriteManifestList(2, out, 77, nil, 
new(int64(0)), 0, nil))
        require.NoError(t, out.Close())
 
        freshParent := &Snapshot{
@@ -2027,7 +2027,7 @@ func 
TestCheckRemovedFiles_AbortsWhenRewriteTargetMissing(t *testing.T) {
        parentManifestList := 
"mem://default/table-location/metadata/fresh-parent-diverged.avro"
        out, err := wfs.Create(parentManifestList)
        require.NoError(t, err)
-       require.NoError(t, iceberg.WriteManifestList(2, out, 99, nil, 
ptr(int64(0)), 0, nil))
+       require.NoError(t, iceberg.WriteManifestList(2, out, 99, nil, 
new(int64(0)), 0, nil))
        require.NoError(t, out.Close())
 
        freshParent := &Snapshot{SnapshotID: 99, ManifestList: 
parentManifestList}
diff --git a/table/snapshots_test.go b/table/snapshots_test.go
index b6b5f2311..e81b6c7e6 100644
--- a/table/snapshots_test.go
+++ b/table/snapshots_test.go
@@ -370,32 +370,32 @@ func TestValidateRowLineage(t *testing.T) {
                },
                {
                        name:       "valid: both set",
-                       firstRowID: ptr(int64(0)),
-                       addedRows:  ptr(int64(100)),
+                       firstRowID: new(int64(0)),
+                       addedRows:  new(int64(100)),
                        wantErr:    "",
                },
                {
                        name:       "valid: zero added rows",
-                       firstRowID: ptr(int64(30)),
-                       addedRows:  ptr(int64(0)),
+                       firstRowID: new(int64(30)),
+                       addedRows:  new(int64(0)),
                        wantErr:    "",
                },
                {
                        name:       "invalid: first-row-id set but added-rows 
nil",
-                       firstRowID: ptr(int64(0)),
+                       firstRowID: new(int64(0)),
                        addedRows:  nil,
                        wantErr:    "added-rows is required when first-row-id 
is set",
                },
                {
                        name:       "invalid: negative added-rows",
-                       firstRowID: ptr(int64(0)),
-                       addedRows:  ptr(int64(-1)),
+                       firstRowID: new(int64(0)),
+                       addedRows:  new(int64(-1)),
                        wantErr:    "added-rows cannot be negative: -1",
                },
                {
                        name:       "invalid: negative first-row-id",
-                       firstRowID: ptr(int64(-1)),
-                       addedRows:  ptr(int64(100)),
+                       firstRowID: new(int64(-1)),
+                       addedRows:  new(int64(100)),
                        wantErr:    "first-row-id cannot be negative: -1",
                },
        }
@@ -419,10 +419,6 @@ func TestValidateRowLineage(t *testing.T) {
        }
 }
 
-func ptr[T any](v T) *T {
-       return &v
-}
-
 func TestSnapshotUnmarshalRequiresSnapshotIDAndTimestamp(t *testing.T) {
        tests := []struct {
                name    string
diff --git a/table/sorting.go b/table/sorting.go
index 9b80b9f03..80c288740 100644
--- a/table/sorting.go
+++ b/table/sorting.go
@@ -245,8 +245,7 @@ func validateSortSourceID(id int, binding orderBinding) 
error {
 
 func unmarshalJSONField(data json.RawMessage, field string, value any) error {
        if err := json.Unmarshal(data, value); err != nil {
-               var typeErr *json.UnmarshalTypeError
-               if errors.As(err, &typeErr) {
+               if typeErr, ok := errors.AsType[*json.UnmarshalTypeError](err); 
ok {
                        typeErr.Struct = ""
                        typeErr.Field = field
                }
diff --git a/table/substrait/substrait.go b/table/substrait/substrait.go
index bc8b36655..e09fc4629 100644
--- a/table/substrait/substrait.go
+++ b/table/substrait/substrait.go
@@ -136,7 +136,8 @@ func (c convertToSubstrait) Map(m iceberg.MapType, 
keyResult, valResult types.Ty
 }
 
 func (convertToSubstrait) Primitive(iceberg.PrimitiveType) types.Type { 
panic("should not be called") }
-func (convertToSubstrait) Variant(iceberg.VariantType) types.Type     { 
panic("should not be called") }
+
+func (convertToSubstrait) Variant(iceberg.VariantType) types.Type { 
panic("should not be called") }
 
 func (convertToSubstrait) VisitFixed(f iceberg.FixedType) types.Type {
        return &types.FixedBinaryType{Length: int32(f.Len())}
diff --git a/table/transaction_internal_test.go 
b/table/transaction_internal_test.go
index ce2d4c2b0..b9eedc2db 100644
--- a/table/transaction_internal_test.go
+++ b/table/transaction_internal_test.go
@@ -724,7 +724,7 @@ func TestExpireSnapshotsRetainsYoungUnreferencedSnapshots(t 
*testing.T) {
                        now := time.Now().UnixMilli()
                        require.NoError(t, txn.meta.AddSnapshot(&Snapshot{
                                SnapshotID:       30,
-                               ParentSnapshotID: transactionTestPtr(int64(10)),
+                               ParentSnapshotID: new(int64(10)),
                                SequenceNumber:   3,
                                ManifestList:     
"mem://default/table-location/metadata/manifest-30.avro",
                                Summary:          &Summary{Operation: OpAppend},
@@ -802,7 +802,7 @@ func 
TestExpireSnapshotsRetainsOnlyRefHeadsWhenMinSnapshotsToKeepIsZero(t *testi
        // interior ancestor held by no ref head.
        require.NoError(t, txn.meta.AddSnapshot(&Snapshot{
                SnapshotID:       30,
-               ParentSnapshotID: transactionTestPtr(int64(20)),
+               ParentSnapshotID: new(int64(20)),
                SequenceNumber:   3,
                ManifestList:     
"mem://default/table-location/metadata/manifest-30.avro",
                Summary:          &Summary{Operation: OpAppend},
@@ -832,7 +832,7 @@ func 
TestExpireSnapshotsRetainsOnlyRefHeadsWhenMinSnapshotsToKeepIsZero(t *testi
 // the retention walk, leaving AncestorsOf's cycle guard as the only exit.
 func TestExpireSnapshotsTerminatesOnParentCycle(t *testing.T) {
        txn := newTransactionWithSnapshotRefs(t)
-       expireSnapshotsSnapshot(t, txn, 10).ParentSnapshotID = 
transactionTestPtr(int64(20))
+       expireSnapshotsSnapshot(t, txn, 10).ParentSnapshotID = new(int64(20))
 
        done := make(chan error, 1)
        go func() { done <- txn.ExpireSnapshots() }()
@@ -1480,12 +1480,12 @@ func 
TestTransactionApplyKeepsRefAssertionsForDistinctRefs(t *testing.T) {
        base := int64(10)
        err := txn.apply(nil, []Requirement{
                AssertRefSnapshotID(MainBranch, &base),
-               AssertRefSnapshotID("feature", transactionTestPtr(int64(20))),
+               AssertRefSnapshotID("feature", new(int64(20))),
        })
        require.NoError(t, err)
        require.Len(t, txn.reqs, 2)
        requireContainsRefSnapshotRequirement(t, txn.reqs, MainBranch, &base)
-       requireContainsRefSnapshotRequirement(t, txn.reqs, "feature", 
transactionTestPtr(int64(20)))
+       requireContainsRefSnapshotRequirement(t, txn.reqs, "feature", 
new(int64(20)))
 }
 
 // TestTransactionApplyDedupesIdenticalNonRefRequirements confirms that non-ref
@@ -1541,7 +1541,7 @@ func TestRollbackToSnapshotPreservesRetention(t 
*testing.T) {
 
        require.NoError(t, txn.meta.AddSnapshot(&Snapshot{
                SnapshotID:       20,
-               ParentSnapshotID: transactionTestPtr(int64(10)),
+               ParentSnapshotID: new(int64(10)),
                SequenceNumber:   2,
                ManifestList:     
"mem://default/table-location/metadata/manifest-20.avro",
                Summary:          &Summary{Operation: OpAppend},
@@ -1582,7 +1582,7 @@ func newTransactionWithSnapshotRefs(t *testing.T) 
*Transaction {
 
        require.NoError(t, txn.meta.AddSnapshot(&Snapshot{
                SnapshotID:       20,
-               ParentSnapshotID: transactionTestPtr(int64(10)),
+               ParentSnapshotID: new(int64(10)),
                SequenceNumber:   2,
                ManifestList:     
"mem://default/table-location/metadata/manifest-20.avro",
                Summary:          &Summary{Operation: OpAppend},
@@ -1608,10 +1608,6 @@ func requireContainsRefSnapshotRequirement(t *testing.T, 
requirements []Requirem
        t.Fatalf("expected assertRefSnapshotID requirement for ref %q and 
snapshot id %v not found", ref, snapshotID)
 }
 
-func transactionTestPtr[T any](v T) *T {
-       return &v
-}
-
 func transactionTestInt64PtrEqual(left, right *int64) bool {
        if left == nil || right == nil {
                return left == right
@@ -1644,7 +1640,7 @@ func newRollbackBranchTable(t *testing.T) *Table {
        }))
        require.NoError(t, txn.meta.AddSnapshot(&Snapshot{
                SnapshotID:       20,
-               ParentSnapshotID: transactionTestPtr(int64(10)),
+               ParentSnapshotID: new(int64(10)),
                SequenceNumber:   2,
                ManifestList:     
"mem://default/table-location/metadata/manifest-20.avro",
                Summary:          &Summary{Operation: OpAppend},
@@ -1652,7 +1648,7 @@ func newRollbackBranchTable(t *testing.T) *Table {
        }))
        require.NoError(t, txn.meta.AddSnapshot(&Snapshot{
                SnapshotID:       30,
-               ParentSnapshotID: transactionTestPtr(int64(20)),
+               ParentSnapshotID: new(int64(20)),
                SequenceNumber:   3,
                ManifestList:     
"mem://default/table-location/metadata/manifest-30.avro",
                Summary:          &Summary{Operation: OpAppend},
@@ -1660,7 +1656,7 @@ func newRollbackBranchTable(t *testing.T) *Table {
        }))
        require.NoError(t, txn.meta.AddSnapshot(&Snapshot{
                SnapshotID:       40,
-               ParentSnapshotID: transactionTestPtr(int64(10)),
+               ParentSnapshotID: new(int64(10)),
                SequenceNumber:   4,
                ManifestList:     
"mem://default/table-location/metadata/manifest-40.avro",
                Summary:          &Summary{Operation: OpAppend},
@@ -1725,7 +1721,7 @@ func TestRollbackToSnapshotOnBranchDoesNotCorruptMain(t 
*testing.T) {
        require.Equal(t, BranchRef, featureRef.SnapshotRefType, "the 
rolled-back ref must stay a branch")
        requireUntouchedRollbackRefs(t, branchTxn, "feature")
 
-       requireContainsRefSnapshotRequirement(t, branchTxn.reqs, "feature", 
transactionTestPtr(int64(30)))
+       requireContainsRefSnapshotRequirement(t, branchTxn.reqs, "feature", 
new(int64(30)))
 }
 
 // TestRollbackToSnapshotValidatesAncestryAgainstTargetBranch rejects snapshot 
20:
@@ -1822,7 +1818,7 @@ func TestRollbackToSnapshotOnMainIsUnchanged(t 
*testing.T) {
                require.Equal(t, int64(10), *txn.meta.currentSnapshotID,
                        "rolling main back must also move the current-snapshot 
pointer")
                requireUntouchedRollbackRefs(t, txn, MainBranch)
-               requireContainsRefSnapshotRequirement(t, txn.reqs, MainBranch, 
transactionTestPtr(int64(20)))
+               requireContainsRefSnapshotRequirement(t, txn.reqs, MainBranch, 
new(int64(20)))
        })
 
        t.Run("refuses when only a branch has a head", func(t *testing.T) {
@@ -1848,7 +1844,7 @@ func TestRollbackToSnapshotOnMainIsUnchanged(t 
*testing.T) {
 func TestRollbackToSnapshotSharesOneBaseAssertionWithProducer(t *testing.T) {
        producerAssertion := func(txn *Transaction) error {
                return txn.apply(nil, []Requirement{
-                       AssertRefSnapshotID("feature", 
transactionTestPtr(int64(30))),
+                       AssertRefSnapshotID("feature", new(int64(30))),
                })
        }
 
diff --git a/website/src/install.md b/website/src/install.md
index eb02d6d59..44985fbfb 100644
--- a/website/src/install.md
+++ b/website/src/install.md
@@ -24,7 +24,7 @@ In this quickstart, we’ll glean insights from code segments 
and learn how to:
 ## Requirements
 
 <div class="warning">
-Go 1.25 or later is required to build.
+Go 1.26 or later is required to build.
 </div>
 
 ## Installation

Reply via email to