Repository navigation
Conversation
- Add Table::Inspect() and metadata scan builders for column selection, projection, and case-sensitive name resolution. - Separate task planning from reading with reusable static tasks backed by captured table metadata. - Preserve scan configuration and metadata across builder changes and table refreshes. - Produce Arrow batches lazily through MetadataScanTaskReader, with reader-controlled batch sizes and independent stream lifetimes. - Keep canonical schemas and row conversion in each metadata table implementation, sharing batch construction and projection validation. - Add common Arrow table comparison utilities and tests for schemas, full reads, reordered projections, and stream behavior
a0fb6c8 to
346d3b7
Compare
| return std::nullopt; | ||
| } | ||
| return Result<std::optional<T>>(std::in_place, std::in_place, | ||
| std::move_if_noexcept(values_[index_++])); |
There was a problem hiding this comment.
this doesn't work with std::vector<bool> which returns a temporary proxy object for values_[index_++]
| /// The returned stream owns its read state and can outlive this scan. The caller | ||
| /// must release the stream and each returned schema or array independently. | ||
| /// Releasing the stream early closes the active task stream. To customize | ||
| /// batch size, open planned tasks with MetadataScanTaskReader instead. |
There was a problem hiding this comment.
It looks there's no public API for MetadataScanTaskReader to access internal fields of MetadataScanContext.
| new HistoryScan(std::move(context), std::move(task))); | ||
| } | ||
|
|
||
| Result<MetadataScanTaskStreamPtr> HistoryScan::PlanTasksStream() const { |
There was a problem hiding this comment.
The follow methods look same as SnapshotTable's. Can they be moved to superclass?
| struct MetadataScanContext { | ||
| MetadataTableKind kind; | ||
| std::shared_ptr<const TableMetadata> table_metadata; | ||
| std::string metadata_file_location; |
There was a problem hiding this comment.
How are metadata_file_location and io supposed to be used? It looks they are unused today.
There was a problem hiding this comment.
I guess these will be used by other metadata table kinds, such as AllManifestsTable, AllEntriesTable and AllFilesTable etc. in java impl.
| EXPECT_EQ(*metadata_table_->schema(), *expected); | ||
| } | ||
|
|
||
| TEST_F(SnapshotsTableTest, ScanEmptySnapshotList) { |
There was a problem hiding this comment.
Do we have the same coverage as before?
| @@ -0,0 +1,44 @@ | |||
| // Licensed to the Apache Software Foundation (ASF) under one | |||
There was a problem hiding this comment.
Our convention is to use /* */ blocks for license headers if you check existing files.
| field_ids.reserve(output_schema->fields().size()); | ||
| for (const auto& field : output_schema->fields()) { | ||
| ICEBERG_ASSIGN_OR_RAISE(auto canonical_field, | ||
| canonical_schema->FindFieldById(field.field_id())); |
There was a problem hiding this comment.
Should we use GetFieldById() here to check only top-level fields? FindFieldById() also finds nested fields, so a projection with summary.key (field ID 7) as a top-level field passes validation.
Make the scan surface a subset of the API proposed in apache#1066 so the two can converge: - MetadataTable::NewScan() is virtual and const, and ScanProjection() is const. - MetadataScanBuilder::Select() resolves names immediately with the current CaseSensitive() setting and records errors for Build(); Project() sets the output schema directly, and Build() rejects a null projection. - MetadataScan::ToArrowArrayStream() is virtual and const. - Projection validation rejects unknown columns, type changes, and projecting a nullable column as required, with the same messages as apache#1066. - Drop the time-travel options together with TimeTravelMetadataTable and SnapshotSelection, which apache#1066 also removes; nothing on main implements them. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…Build() Drop the MetadataScan class: separating a built scan from the Arrow stream it reads belongs to the task-based design in apache#1066. Build() now validates the options and returns the stream directly, and each call returns a new stream. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
| const std::shared_ptr<Schema>& projected_schema, int64_t batch_size) { | ||
| std::vector<size_t> snapshot_indices; | ||
| for (size_t i = 0; i < metadata->snapshots.size(); ++i) { | ||
| if (metadata->snapshots[i]) { |
There was a problem hiding this comment.
nit: no test exercises this skip when an entry in metadata->snapshots is null.
| return operation ? AppendString(column, *operation) : AppendNull(column); | ||
| } | ||
| case 5: // manifest_list | ||
| return snapshot.manifest_list.empty() |
There was a problem hiding this comment.
nit: no test exercises the empty manifest_list branch here.
| // Walk the current snapshot's ancestry; the insert check stops on cycles. | ||
| std::unordered_set<int64_t> ancestors; | ||
| for (auto current = metadata->current_snapshot_id; | ||
| current != kInvalidSnapshotId && ancestors.insert(current).second;) { |
There was a problem hiding this comment.
nit: the cycle guard here isn't tested against an actual cycle in the snapshot graph, so it's defensive-only right now.
Other Iceberg implementations
TableScanconfiguration where applicable. Static tables materialize rows intoStaticDataTask; other tables use tasks that read manifests or manifest lists. Metadata tasks participate in the file-scan task hierarchy and have JSON parsers.Table.Inspect()exposes methods for individual metadata tables and returns Arrow record readers. Snapshots and history are materialized into a single batch.table.inspect()exposes typed metadata-table objects with schemas and an asyncscan()returning an Arrow record-batch stream. The inspected snapshots, history, and manifests implementations build a batch before wrapping it in a stream.table.inspectexposes methods returning materialized PyArrow tables. Some manifest/file inspection paths use an executor to parallelize reads before collecting the results.Design decisions
ToArrowArrayStream()path. The builder selects output columns; the reader controls execution settings.TableScanBuilderand inherit from the ordinary data-file task hierarchyStructLikevalues or table-specific structs in a central variantTableMetadatafor snapshots/history tasksMetadataScanTaskReader::Options.