apache / apache/iceberg-rust

TableScanBuilder::with_case_sensitive(false) is ignored when binding scan filters

Open Beginner friendly
#2,490 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
1.4k
Forks
567
Avg merge
2d 2h
Merged PRs (30d)
93

Description

`TableScanBuilder::with_case_sensitive(false)` does not appear to be honored when the scan filter is bound.

What I found
- `TableScanBuilder::with_case_sensitive` stores the flag on the builder in `crates/iceberg/src/scan/mod.rs`
- `build()` later binds the scan predicate with `true` instead of the configured flag
- that bound predicate is then used for file metrics pruning in `process_data_manifest_entry`

Relevant code
- `crates/iceberg/src/scan/mod.rs:93`
- `crates/iceberg/src/scan/mod.rs:278`
- `crates/iceberg/src/scan/mod.rs:529`

Why this looks wrong
A scan configured with `with_case_sensitive(false)` should allow case-insensitive field resolution consistently across planning. Right now, filters are effectively bound case-sensitively during scan construction.

Expected behavior
A filter like `Reference("ID") == ...` should bind successfully against a schema field named `id` when the scan was configured with `with_case_sensitive(false)`.

Actual behavior
The filter is bound as if case sensitivity were still enabled, because `build()` hardcodes `true` during binding:

```rust
let snapshot_bound_predicate = if let Some(ref predicates) = self.filter {
Some(predicates.bind(schema.clone(), true)?)
} else {
None
};
```

There is also a smaller related gap in the same method: when the table has no current snapshot, `build()` returns early before binding the filter at all, so malformed filters can be skipped on empty tables. But the main issue here is the incorrect case-sensitivity handling on normal scans.

I did not find an obvious existing issue for this in a quick tracker search.

Contributor guide

Open the contributing guide

Research direction

Start in crates/iceberg/src/scan/mod.rs, especially the builder flag near line 93 and build() near line 278; trace the bound predicate into process_data_manifest_entry near line 529. Verify how scan filters are bound and how the no-snapshot early return behaves. Done means case-insensitive scans resolve Reference("ID") against a field named id, while normal scans retain case-sensitive behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
databases
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.