Skip to content

[adapters] Iceberg connector reads only columns declared in the SQL table#6638

Merged
ryzhyk merged 1 commit into
mainfrom
iceberg-used-columns
Jul 15, 2026
Merged

[adapters] Iceberg connector reads only columns declared in the SQL table#6638
ryzhyk merged 1 commit into
mainfrom
iceberg-used-columns

Conversation

@ryzhyk

@ryzhyk ryzhyk commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Replace the select * snapshot queries with an explicit column list: the intersection of the Iceberg snapshot schema and the SQL table declaration, mirroring the Delta connector's used_column_list. Undeclared table columns previously wasted IO and could fail deserialization for column types Feldera does not support.

The connector also honors the table-level skip_unused_columns property: a declared-but-unused column is skipped when it is nullable or has a default and snapshot_filter does not reference it. The property check lives in Relation::skip_unused_columns, used by both the Delta and Iceberg connectors.

Share ColumnNameSet and quote_sql_identifier between the Delta and Iceberg connectors by moving them to feldera-adapterlib.

Describe Manual Test Plan

Checklist

  • Unit tests added/updated
  • Integration tests added/updated
  • Documentation updated
  • Changelog updated

Breaking Changes?

Mark if you think the answer is yes for any of these components:

Describe Incompatible Changes

… table

Replace the `select *` snapshot queries with an explicit column list:
the intersection of the Iceberg snapshot schema and the SQL table
declaration, mirroring the Delta connector's `used_column_list`.
Undeclared table columns previously wasted IO and could fail
deserialization for column types Feldera does not support.

The connector also honors the table-level `skip_unused_columns`
property: a declared-but-unused column is skipped when it is nullable
or has a default and `snapshot_filter` does not reference it. The
property check lives in `Relation::skip_unused_columns`, used by both
the Delta and Iceberg connectors.

Share `ColumnNameSet` and `quote_sql_identifier` between the Delta
and Iceberg connectors by moving them to feldera-adapterlib.

Signed-off-by: Leonid Ryzhyk <ryzhyk@gmail.com>
@ryzhyk
ryzhyk requested a review from swanandx July 15, 2026 07:15
@ryzhyk ryzhyk added the connectors Issues related to the adapters/connectors crate label Jul 15, 2026

@swanandx swanandx left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

PR LGTM! just have one suggestion

Approving anyways to unblock. thanks!

Comment on lines +114 to +158
fn used_sql_columns(schema: &Relation, config: &IcebergReaderConfig) -> ColumnNameSet {
let skip = schema.skip_unused_columns();
let config_referenced = config_referenced_columns(config);
ColumnNameSet::from_names(
schema
.fields
.iter()
.filter(|f| !skip || !can_skip_column(f, &config_referenced))
.map(|f| f.name.name()),
)
}

/// Compute the subset of columns in the Iceberg table snapshot schema that
/// occur in the SQL table declaration (minus columns removed by
/// [`used_sql_columns`]), preserving the table schema's column order.
///
/// Snapshot queries select this subset instead of `*`, so the connector never
/// reads table columns the pipeline does not ingest. Besides being wasteful,
/// reading such columns can fail when their Arrow type is not supported by
/// the Feldera deserializer.
///
/// Iceberg schemas carry no case-sensitivity information, so column names are
/// matched in lowercased form (see [`ColumnNameSet`]).
fn used_columns(
table_schema: &ArrowSchema,
schema: &Relation,
config: &IcebergReaderConfig,
) -> Vec<String> {
let used = used_sql_columns(schema, config);
table_schema
.fields()
.iter()
.filter(|f| used.contains(f.name()))
.map(|f| f.name().to_string())
.collect()
}

/// Quoted, comma-separated column list for `select {} from snapshot` queries.
fn used_column_list(columns: &[String]) -> String {
columns
.iter()
.map(quote_sql_identifier)
.collect::<Vec<_>>()
.join(", ")
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

we should make declare them as methods of IcebergInputEndpointInner

where used_sql_columns: OnceLock<ColumnNameSet>andconfig_referenced_columns: OnceLock` are fields on that struct.

so we don't need to construct ColumnNameSet everytime

maybe this is fine for now ( as there is just snapshot mode ) but i would say let's stay consistent for now, and get rid of it if it isn't required later, wdyt?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Can't it be just computed during initialization. Either way, computing them once makes sense to me. I suppose we want to do this in both iceberg and delta connectors.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

delta already does declare them as i mentioned above, computing them just once. So we need to do this just for iceberg as quoted here

@mythical-fred mythical-fred left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LGTM

@@ -241,11 +268,16 @@ fn iceberg_localfs_input_test(
let script_path = "../iceberg/src/test/create_test_table_s3.py";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Nit: the changelog checkbox is unchecked. This is a user-visible behavior change (Iceberg connector now reads only declared columns instead of *, and honors skip_unused_columns). Worth a one-liner under Unreleased.

@ryzhyk
ryzhyk added this pull request to the merge queue Jul 15, 2026
Merged via the queue into main with commit 3c8a2b7 Jul 15, 2026
1 check passed
@ryzhyk
ryzhyk deleted the iceberg-used-columns branch July 15, 2026 18:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

connectors Issues related to the adapters/connectors crate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants