Skip to content

feat(scan): make FileScanTask serializable - #3091

Open
blackmwk wants to merge 11 commits into
apache:mainfrom
blackmwk:ir-3089
Open

feat(scan): make FileScanTask serializable#3091
blackmwk wants to merge 11 commits into
apache:mainfrom
blackmwk:ir-3089

Conversation

@blackmwk

@blackmwk blackmwk commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

What changes are included in this PR?

  • Replace the placeholder serde failures on FileScanTask context fields with working serialization.
  • Add a private serde adapter for FileScanTask that serializes partition data through the existing RawLiteral implementation.
  • Use the task schema and partition spec as the type context required to reconstruct partition literals during deserialization.
  • Serialize partition specs, name mappings, and unified partition types through their existing serde implementations.
  • Expand round-trip coverage for a fully populated scan task, including partition data and all optional scan context fields.

The existing key_metadata trust boundary is unchanged: encrypted-file key metadata remains part of a serialized scan task as documented on the field.

Are these changes tested?

  • cargo test -p iceberg --lib (1,585 passed)
  • cargo clippy -p iceberg --lib --tests -- -D warnings
  • cargo fmt --all -- --check
  • git diff --check
  • make check-public-api

AI Disclosure

Codex was used to assist with implementation, regression-test scaffolding, review follow-up, and validation. I reviewed the resulting design and diff, and verified it with the tests and linters listed above. There are no known unresolved assumptions or uncertainties.

Replace the placeholder serde errors with a lossless representation for partition literals and use the existing serde implementations for the remaining scan context fields. Expand round-trip coverage to include a fully populated task and every primitive partition literal.

[apache#3089](apache#3089)
Comment thread crates/iceberg/src/scan/task.rs Outdated
Comment thread crates/iceberg/src/scan/task.rs Outdated
Move the self-describing serde representation into Literal so scan task partitions use the shared values-layer implementation. Cover primitive and nested literal round trips and remove the task-local helper requested in review.
Record the new Serialize and Deserialize implementations for Literal and Struct.
Comment thread crates/iceberg/src/spec/values/literal.rs Outdated
Serialize partition data through the existing RawLiteral implementation using the task schema and partition spec. Remove the direct Literal and Struct serde implementation and keep the public API unchanged.
Comment thread crates/iceberg/src/scan/task.rs Outdated
Comment thread crates/iceberg/src/scan/task.rs Outdated
Comment thread crates/iceberg/src/scan/task.rs Outdated
Comment thread crates/iceberg/src/scan/task.rs Outdated
Comment thread crates/iceberg/src/scan/task.rs Outdated
Comment thread crates/iceberg/src/scan/task.rs Outdated
Comment thread crates/iceberg/src/scan/mod.rs Outdated
@blackmwk
blackmwk marked this pull request as ready for review August 31, 2026 05:17

@laskoviymishka laskoviymishka 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.

Nice to see this one finally get a real serde path — the mirror-struct approach is clean, and the move to full-struct assert_eq! round-trips is a real step up from the old field-by-field checks.

I'd hold it before merging, though. The partition encoding is the load-bearing new behavior here, and there's a case that breaks a straight Rust-to-Rust round-trip.

The main concern is timestamp_ns / timestamptz_ns partition columns. Both are backed by PrimitiveLiteral::Long, so they serialize as JSON integers fine, but the Long arm in values/serde.rs has no branch to turn them back into a literal on deserialize — so any V3 table partitioned on a nanosecond timestamp produces FileScanTasks that fail to deserialize once this lands. This is the first caller to actually exercise that path, which is why the gap surfaces here. I'd add the two missing arms in serde.rs and a round-trip test that pins them.

A few things I'd want to settle before merge:

  • Add the TimestampNs / TimestamptzNs arms in values/serde.rs and a timestamp_ns partition round-trip test.
  • Pin the partition = Some / partition_spec = None behavior with an explicit guard + test — right now it either silently drops the partition values or errors opaquely, and nobody's sure which.
  • Handle (or at least document) partition-evolution + dropped-source-column, which currently makes serialize fail.
  • Drop the per-serialize self.clone() in favor of TryFrom<&FileScanTask>, add skip_serializing_if to record_count, and swap use super::* for explicit imports to match the other _serde modules.

One more worth a look but I won't block on it: the Record arm in serde.rs rebuilds the partition struct in JSON field order rather than schema order, so a non-Rust JSON producer could map values to the wrong partition slots. serde_json round-trips fine, so it doesn't bite the current use case, but it's fragile enough to be worth a follow-up.

Once those are addressed, happy to take another pass and approve.

Comment thread crates/iceberg/src/scan/mod.rs
Comment thread crates/iceberg/src/scan/task.rs Outdated
Comment thread crates/iceberg/src/scan/task.rs
Comment thread crates/iceberg/src/scan/task.rs Outdated
Comment thread crates/iceberg/src/scan/task.rs Outdated
Comment thread crates/iceberg/src/scan/task.rs Outdated
blackmwk added a commit to blackmwk/iceberg-rust that referenced this pull request Sep 1, 2026
Validate partition arity and transformed value types while preserving support for historical partition specs whose source columns were dropped. Port the partition coverage from PR apache#3091 to builder regression tests.

Generated-by: Codex (GPT-5)
@blackmwk

blackmwk commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

hi, @laskoviymishka thanks for the careful review. After second thought I think we should not do validation in the ser/de path, instead we should do it when the build happens. We should merge #3131 first

CTTY pushed a commit that referenced this pull request Sep 2, 2026
* refactor(scan): Validate FileScanTask construction

Make FileScanTask fields private, expose read-only getters, and validate builder output so non-empty partition data always has an associated partition spec.

Generated-by: Codex (GPT-5)

* refactor(scan): Simplify FileScanTask validation

Use typed-builder output conversion for validation instead of coupling the custom build method to generated typestate arguments.

Generated-by: Codex (GPT-5)

* fix(scan): Validate FileScanTask partition data

Validate partition arity and transformed value types while preserving support for historical partition specs whose source columns were dropped. Port the partition coverage from PR #3091 to builder regression tests.

Generated-by: Codex (GPT-5)

* fix(scan): Refine partition validation

Enforce symmetric partition/spec presence and tuple arity while avoiding per-value transform validation during task construction. Update the spec-id scan fixture to provide its partition tuple.

Generated-by: Codex (GPT-5)

* fix(scan): Validate partition specs against schema

Preserve historical specs with dropped source columns while validating resolvable partition specs against the task schema. Add regression coverage for an incompatible evolved schema.

Generated-by: Codex (GPT-5)

* fix(scan): Always validate partition specs

Remove the dropped-source shortcut and rely directly on PartitionSpec::partition_type for schema validation. Update dropped-source coverage to assert the resulting planning error.

Generated-by: Codex (GPT-5)
# Conflicts:
#	crates/iceberg/src/scan/mod.rs
#	crates/iceberg/src/scan/task.rs
@blackmwk

blackmwk commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

I think this pr is ready for review, cc @laskoviymishka @CTTY @kevinjqliu PTAL

@CTTY CTTY left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM!

cc @laskoviymishka

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make FileScanTask serializable.

4 participants