Skip to content

feat(connector): Add support for widening nested fields - #28454

Open
Shreya-ibm wants to merge 1 commit into
prestodb:masterfrom
Shreya-ibm:feature/iceberg-nested-field-type-widening
Open

feat(connector): Add support for widening nested fields#28454
Shreya-ibm wants to merge 1 commit into
prestodb:masterfrom
Shreya-ibm:feature/iceberg-nested-field-type-widening

Conversation

@Shreya-ibm

@Shreya-ibm Shreya-ibm commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Description

Adds support for widening nested fields in Iceberg struct columns using ALTER TABLE ... ALTER COLUMN ... SET DATA TYPE.

Example:

ALTER TABLE table_name ALTER COLUMN struct_col.field SET DATA TYPE BIGINT;

Context

Fixes: #81606
Partially fixes: #75595

This branch adds support for nested field type widening while preserving the existing top-level type-widening behavior.
The implementation also ensures that existing data written before the schema evolution remains readable after widening.

Release Notes

== NO RELEASE NOTE ==

Summary by Sourcery

Enable widening of nested Iceberg struct fields through ALTER TABLE while preserving existing top-level type evolution behavior.

New Features:

  • Support ALTER TABLE ... ALTER COLUMN ... SET DATA TYPE for fields nested within Iceberg struct columns.
  • Propagate nested field type changes through the SQL, metadata, and connector APIs while retaining top-level column type changes.

Bug Fixes:

  • Preserve readability of existing Iceberg data after widening nested field types.

Tests:

  • Add parser, execution, and Iceberg integration coverage for nested field widening across supported file formats, including rejection of narrowing changes.

@prestodb-ci prestodb-ci added the from:IBM PR from IBM label Sep 8, 2026
@prestodb-ci
prestodb-ci requested a review from a team September 8, 2026 00:33
@sourcery-ai

sourcery-ai Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Extends ALTER COLUMN SET DATA TYPE from identifiers to qualified nested field paths, routes those updates through the metadata and connector APIs, and implements Iceberg struct-field widening with compatible reads of legacy data. Tests cover parsing, dispatch, cross-format schema evolution, old and new data, and narrowing rejection.

Sequence diagram for nested field type widening

sequenceDiagram
    participant User
    participant Parser
    participant SetColumnTypeTask
    participant MetadataManager
    participant IcebergMetadata
    participant IcebergTable

    User->>Parser: ALTER TABLE ... ALTER COLUMN struct_col.field SET DATA TYPE BIGINT
    Parser->>SetColumnTypeTask: SetColumnType(qualifiedName)
    SetColumnTypeTask->>MetadataManager: setFieldType(table, column, fieldPath, type)
    MetadataManager->>IcebergMetadata: setFieldType(session, table, column, fieldPath, type)
    IcebergMetadata->>IcebergTable: updateSchema().updateColumn(fieldName, BIGINT).commit()
    IcebergTable-->>User: Schema updated
Loading

Flow diagram for top-level and nested type alteration dispatch

flowchart TD
    A[ALTER COLUMN qualifiedName SET DATA TYPE] --> B[Parse column path]
    B --> C[Resolve root column handle]
    C --> D{Path has nested fields?}
    D -->|No| E[Metadata.setColumnType]
    D -->|Yes| F[Metadata.setFieldType]
    E --> G[ConnectorMetadata.setColumnType]
    F --> H[ConnectorMetadata.setFieldType]
    H --> I[Iceberg resolves struct field path]
    I --> J[Iceberg commits widened field type]
Loading

File-Level Changes

Change Details Files
Add end-to-end metadata plumbing for nested field type changes while retaining top-level column alterations.
  • Parse column paths as qualified names and route single-part paths to existing column updates.
  • Add field-path update methods through metadata managers, connector SPI, and classloader-safe delegation.
  • Provide a no-op remote metadata implementation and default unsupported behavior for connectors without support.
presto-parser/src/main/antlr4/com/facebook/presto/sql/parser/SqlBase.g4
presto-parser/src/main/java/com/facebook/presto/sql/parser/AstBuilder.java
presto-parser/src/main/java/com/facebook/presto/sql/tree/SetColumnType.java
presto-main-base/src/main/java/com/facebook/presto/execution/SetColumnTypeTask.java
presto-main-base/src/main/java/com/facebook/presto/metadata/Metadata.java
presto-main-base/src/main/java/com/facebook/presto/metadata/MetadataManager.java
presto-main-base/src/main/java/com/facebook/presto/metadata/StatsRecordingMetadataManager.java
presto-main-base/src/main/java/com/facebook/presto/catalogserver/RemoteMetadataManager.java
presto-spi/src/main/java/com/facebook/presto/spi/connector/ConnectorMetadata.java
presto-spi/src/main/java/com/facebook/presto/spi/connector/classloader/ClassLoaderSafeConnectorMetadata.java
Implement Iceberg nested schema evolution by resolving field paths and updating the targeted primitive field.
  • Traverse nested structs case-insensitively from the root Iceberg field and report invalid paths.
  • Apply the requested Iceberg primitive type through updateSchema and wrap failures as incompatible-column-type errors.
presto-iceberg/src/main/java/com/facebook/presto/iceberg/IcebergAbstractMetadata.java
Preserve compatibility when reading files written before nested widening.
  • Use the current column type when constructing Parquet nested fields instead of re-deriving the type from the physical Parquet schema.
presto-iceberg/src/main/java/com/facebook/presto/iceberg/IcebergPageSourceProvider.java
Add parser, execution-routing, and Iceberg integration coverage for nested widening behavior.
  • Verify qualified nested column parsing and dispatch separately from top-level changes.
  • Test INTEGER-to-BIGINT widening across supported file formats, readability of pre-existing rows, post-evolution writes, and rejection of narrowing.
presto-parser/src/test/java/com/facebook/presto/sql/parser/TestSqlParser.java
presto-main-base/src/test/java/com/facebook/presto/execution/TestSetColumnTypeTask.java
presto-iceberg/src/test/java/com/facebook/presto/iceberg/IcebergDistributedSmokeTestBase.java

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@prestodb-ci
prestodb-ci requested review from vinsu and removed request for a team September 8, 2026 00:33
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown

Codenotify: Notifying subscribers in CODENOTIFY files for diff c19af73...78163a7.

Notify File(s)
@aditi-pandit presto-parser/src/main/antlr4/com/facebook/presto/sql/parser/SqlBase.g4
@elharo presto-parser/src/main/antlr4/com/facebook/presto/sql/parser/SqlBase.g4
@kaikalur presto-parser/src/main/antlr4/com/facebook/presto/sql/parser/SqlBase.g4
@rschlussel presto-parser/src/main/antlr4/com/facebook/presto/sql/parser/SqlBase.g4

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="presto-iceberg/src/main/java/com/facebook/presto/iceberg/IcebergPageSourceProvider.java" line_range="399-397" />
<code_context>
                                 .ifPresent(value -> defaultValues.put(column.getId(), value));
                     }
                     else {
-                        Type type = column.getType();
-                        if (!parquetField.get().isPrimitive()) {
-                            MessageType parquetMessageType = new MessageType("", parquetField.get());
-                            Schema icebergSchema = ParquetSchemaUtil.convert(parquetMessageType);
-                            type = toPrestoType(icebergSchema.columns().get(0).type(), typeManager);
-                        }
-                        internalFields.add(constructField(type, lookupColumnByName(messageColumnIO, AvroSchemaUtil.makeCompatibleName(parquetField.get().getName()))));
+                        internalFields.add(constructField(column.getType(), lookupColumnByName(messageColumnIO, AvroSchemaUtil.makeCompatibleName(parquetField.get().getName()))));
                     }
                 }
</code_context>
<issue_to_address>
**issue (broader_impact):** After a nested Iceberg field is widened, this passes the current widened row type directly to the Parquet reader even when the file was written with the old nested physical type. Existing Parquet files therefore decode an INT32 nested value using the BIGINT field definition, causing old rows to fail to read or be decoded incorrectly.

**Triggers:** When reading Parquet data written before a nested INTEGER-to-BIGINT schema evolution.

**Suggested fix:** Retain the physical Parquet-to-Iceberg type conversion for non-primitive fields, or add an explicit schema-evolution coercion from the file's nested physical type to the current requested type.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨

@@ -396,13 +394,7 @@ private ConnectorPageSourceWithRowPositions createParquetPageSource(
.ifPresent(value -> defaultValues.put(column.getId(), value));
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

issue (broader_impact): After a nested Iceberg field is widened, this passes the current widened row type directly to the Parquet reader even when the file was written with the old nested physical type. Existing Parquet files therefore decode an INT32 nested value using the BIGINT field definition, causing old rows to fail to read or be decoded incorrectly.

Triggers: When reading Parquet data written before a nested INTEGER-to-BIGINT schema evolution.

Suggested fix: Retain the physical Parquet-to-Iceberg type conversion for non-primitive fields, or add an explicit schema-evolution coercion from the file's nested physical type to the current requested type.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

from:IBM PR from IBM

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants