Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions crates/iceberg/public-api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1328,6 +1328,20 @@ impl serde_core::ser::Serialize for iceberg::scan::FileScanTaskDeleteFile
pub fn iceberg::scan::FileScanTaskDeleteFile::serialize<__S>(&self, __serializer: __S) -> core::result::Result<<__S as serde_core::ser::Serializer>::Ok, <__S as serde_core::ser::Serializer>::Error> where __S: serde_core::ser::Serializer
impl<'de> serde_core::de::Deserialize<'de> for iceberg::scan::FileScanTaskDeleteFile
pub fn iceberg::scan::FileScanTaskDeleteFile::deserialize<__D>(__deserializer: __D) -> core::result::Result<Self, <__D as serde_core::de::Deserializer>::Error> where __D: serde_core::de::Deserializer<'de>
pub struct iceberg::scan::IncrementalAppendScanBuilder<'a>
impl<'a> iceberg::scan::IncrementalAppendScanBuilder<'a>
pub fn iceberg::scan::IncrementalAppendScanBuilder<'a>::build(self) -> iceberg::Result<iceberg::scan::TableScan>
pub fn iceberg::scan::IncrementalAppendScanBuilder<'a>::select(self, column_names: impl core::iter::traits::collect::IntoIterator<Item = impl alloc::string::ToString>) -> Self
pub fn iceberg::scan::IncrementalAppendScanBuilder<'a>::select_all(self) -> Self
pub fn iceberg::scan::IncrementalAppendScanBuilder<'a>::select_empty(self) -> Self
pub fn iceberg::scan::IncrementalAppendScanBuilder<'a>::with_batch_size(self, batch_size: core::option::Option<usize>) -> Self
pub fn iceberg::scan::IncrementalAppendScanBuilder<'a>::with_case_sensitive(self, case_sensitive: bool) -> Self
pub fn iceberg::scan::IncrementalAppendScanBuilder<'a>::with_concurrency_limit(self, limit: usize) -> Self
pub fn iceberg::scan::IncrementalAppendScanBuilder<'a>::with_data_file_concurrency_limit(self, limit: usize) -> Self
pub fn iceberg::scan::IncrementalAppendScanBuilder<'a>::with_filter(self, predicate: iceberg::expr::Predicate) -> Self
pub fn iceberg::scan::IncrementalAppendScanBuilder<'a>::with_manifest_entry_concurrency_limit(self, limit: usize) -> Self
pub fn iceberg::scan::IncrementalAppendScanBuilder<'a>::with_row_group_filtering_enabled(self, row_group_filtering_enabled: bool) -> Self
pub fn iceberg::scan::IncrementalAppendScanBuilder<'a>::with_row_selection_enabled(self, row_selection_enabled: bool) -> Self
pub struct iceberg::scan::ScanMetrics
impl iceberg::scan::ScanMetrics
pub fn iceberg::scan::ScanMetrics::bytes_read(&self) -> u64
Expand Down Expand Up @@ -3132,6 +3146,8 @@ pub struct iceberg::table::StaticTable(_)
impl iceberg::table::StaticTable
pub async fn iceberg::table::StaticTable::from_metadata(metadata: iceberg::spec::TableMetadata, table_ident: iceberg::TableIdent, file_io: iceberg::io::FileIO) -> iceberg::Result<Self>
pub async fn iceberg::table::StaticTable::from_metadata_file(metadata_location: &str, table_ident: iceberg::TableIdent, file_io: iceberg::io::FileIO) -> iceberg::Result<Self>
pub fn iceberg::table::StaticTable::incremental_append_scan(&self, from_snapshot_id: i64, to_snapshot_id: core::option::Option<i64>) -> iceberg::scan::IncrementalAppendScanBuilder<'_>
pub fn iceberg::table::StaticTable::incremental_append_scan_inclusive(&self, from_snapshot_id: i64, to_snapshot_id: core::option::Option<i64>) -> iceberg::scan::IncrementalAppendScanBuilder<'_>
pub fn iceberg::table::StaticTable::into_table(self) -> iceberg::table::Table
pub fn iceberg::table::StaticTable::metadata(&self) -> iceberg::spec::TableMetadataRef
pub fn iceberg::table::StaticTable::reader_builder(&self) -> iceberg::arrow::ArrowReaderBuilder
Expand All @@ -3147,6 +3163,8 @@ pub fn iceberg::table::Table::current_schema_ref(&self) -> iceberg::spec::Schema
pub fn iceberg::table::Table::encryption_manager(&self) -> core::option::Option<&iceberg::encryption::EncryptionManager>
pub fn iceberg::table::Table::file_io(&self) -> &iceberg::io::FileIO
pub fn iceberg::table::Table::identifier(&self) -> &iceberg::TableIdent
pub fn iceberg::table::Table::incremental_append_scan(&self, from_snapshot_id: i64, to_snapshot_id: core::option::Option<i64>) -> iceberg::scan::IncrementalAppendScanBuilder<'_>
pub fn iceberg::table::Table::incremental_append_scan_inclusive(&self, from_snapshot_id: i64, to_snapshot_id: core::option::Option<i64>) -> iceberg::scan::IncrementalAppendScanBuilder<'_>
pub fn iceberg::table::Table::inspect(&self) -> iceberg::inspect::MetadataTable<'_>
pub fn iceberg::table::Table::manifest_list_reader(&self, snapshot: &iceberg::spec::SnapshotRef) -> iceberg::spec::ManifestListReader
pub fn iceberg::table::Table::metadata(&self) -> &iceberg::spec::TableMetadata
Expand Down
35 changes: 34 additions & 1 deletion crates/iceberg/src/scan/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ use crate::spec::{
};
use crate::{Error, ErrorKind, Result};

/// Filter applied to each [`ManifestFile`] before fetching it.
/// Returns `true` to include the manifest, `false` to skip it.
pub(crate) type ManifestFileFilter = Arc<dyn Fn(&ManifestFile) -> bool + Send + Sync>;

/// Filter applied to each manifest entry after loading a manifest.
/// Returns `true` to include the entry, `false` to skip it.
pub(crate) type ManifestEntryFilter = Arc<dyn Fn(&ManifestEntryRef) -> bool + Send + Sync>;

/// Wraps a [`ManifestFile`] alongside the objects that are needed
/// to process it in a thread-safe manner
pub(crate) struct ManifestFileContext {
Expand All @@ -48,6 +56,7 @@ pub(crate) struct ManifestFileContext {
delete_file_index: DeleteFileIndex,
name_mapping: Option<Arc<NameMapping>>,
case_sensitive: bool,
entry_filter: Option<ManifestEntryFilter>,
partition_spec: Option<PartitionSpecRef>,
unified_partition_type: Option<Arc<StructType>>,
}
Expand Down Expand Up @@ -84,13 +93,20 @@ impl ManifestFileContext {
delete_file_index,
name_mapping,
case_sensitive,
entry_filter,
partition_spec,
unified_partition_type,
} = self;

let manifest = object_cache.get_manifest(&manifest_file).await?;

for manifest_entry in manifest.entries() {
if let Some(ref filter) = entry_filter
&& !filter(manifest_entry)
{
continue;
}

let manifest_entry_context = ManifestEntryContext {
// TODO: refactor to avoid the expensive ManifestEntry clone
manifest_entry: manifest_entry.clone(),
Expand Down Expand Up @@ -156,7 +172,6 @@ impl ManifestEntryContext {

/// PlanContext wraps a [`SnapshotRef`] alongside all the other
/// objects that are required to perform a scan file plan.
#[derive(Debug)]
pub(crate) struct PlanContext {
pub snapshot: SnapshotRef,

Expand All @@ -172,10 +187,21 @@ pub(crate) struct PlanContext {
pub partition_filter_cache: Arc<PartitionFilterCache>,
pub manifest_evaluator_cache: Arc<ManifestEvaluatorCache>,
pub expression_evaluator_cache: Arc<ExpressionEvaluatorCache>,
pub manifest_file_filter: Option<ManifestFileFilter>,
pub manifest_entry_filter: Option<ManifestEntryFilter>,

pub unified_partition_type: Option<Arc<StructType>>,
}

impl std::fmt::Debug for PlanContext {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("PlanContext")
.field("snapshot", &self.snapshot)
.field("case_sensitive", &self.case_sensitive)
.finish_non_exhaustive()
}
}

impl PlanContext {
pub(crate) async fn get_manifest_list(&self) -> Result<Arc<ManifestList>> {
self.object_cache
Expand Down Expand Up @@ -229,6 +255,12 @@ impl PlanContext {
// TODO: Ideally we could ditch this intermediate Vec as we return an iterator.
let mut filtered_mfcs = vec![];
for manifest_file in manifest_files {
if let Some(ref filter) = self.manifest_file_filter
&& !filter(manifest_file)
{
continue;
}

let tx = if manifest_file.content == ManifestContentType::Deletes {
delete_file_tx.clone()
} else {
Expand Down Expand Up @@ -299,6 +331,7 @@ impl PlanContext {
delete_file_index,
name_mapping: self.name_mapping.clone(),
case_sensitive: self.case_sensitive,
entry_filter: self.manifest_entry_filter.clone(),
partition_spec: self
.table_metadata
.partition_spec_by_id(manifest_file.partition_spec_id)
Expand Down
Loading
Loading