@@ -106,6 +106,14 @@ Status AppendPartitionSummaries(ArrowArray* array, const ManifestRow& row,
106106 return {};
107107}
108108
109+ Status AppendManifestCount (ArrowArray* array, const std::optional<int32_t >& count,
110+ bool applicable) {
111+ if (!applicable) {
112+ return AppendInt (array, 0 );
113+ }
114+ return count.has_value () ? AppendInt (array, *count) : AppendNull (array);
115+ }
116+
109117Status AppendManifest (ArrowRowBuilder& builder, const ManifestRow& row,
110118 const std::shared_ptr<Schema>& table_schema) {
111119 const auto & manifest = row.manifest ;
@@ -114,21 +122,23 @@ Status AppendManifest(ArrowRowBuilder& builder, const ManifestRow& row,
114122 ICEBERG_RETURN_UNEXPECTED (AppendString (builder.column (1 ), manifest.manifest_path ));
115123 ICEBERG_RETURN_UNEXPECTED (AppendInt (builder.column (2 ), manifest.manifest_length ));
116124 ICEBERG_RETURN_UNEXPECTED (AppendInt (builder.column (3 ), manifest.partition_spec_id ));
117- ICEBERG_RETURN_UNEXPECTED (AppendInt (builder.column (4 ), manifest.added_snapshot_id ));
125+ ICEBERG_PRECHECK (manifest.added_snapshot_id .has_value (),
126+ " Manifest '{}' has no added snapshot ID" , manifest.manifest_path );
127+ ICEBERG_RETURN_UNEXPECTED (AppendInt (builder.column (4 ), *manifest.added_snapshot_id ));
118128
119129 const bool data = manifest.content == ManifestContent::kData ;
120130 ICEBERG_RETURN_UNEXPECTED (
121- AppendInt (builder.column (5 ), data ? manifest.added_files_count . value_or ( 0 ) : 0 ));
131+ AppendManifestCount (builder.column (5 ), manifest.added_files_count , data ));
122132 ICEBERG_RETURN_UNEXPECTED (
123- AppendInt (builder.column (6 ), data ? manifest.existing_files_count . value_or ( 0 ) : 0 ));
133+ AppendManifestCount (builder.column (6 ), manifest.existing_files_count , data ));
124134 ICEBERG_RETURN_UNEXPECTED (
125- AppendInt (builder.column (7 ), data ? manifest.deleted_files_count . value_or ( 0 ) : 0 ));
135+ AppendManifestCount (builder.column (7 ), manifest.deleted_files_count , data ));
126136 ICEBERG_RETURN_UNEXPECTED (
127- AppendInt (builder.column (8 ), data ? 0 : manifest.added_files_count . value_or ( 0 ) ));
137+ AppendManifestCount (builder.column (8 ), manifest.added_files_count , !data ));
128138 ICEBERG_RETURN_UNEXPECTED (
129- AppendInt (builder.column (9 ), data ? 0 : manifest.existing_files_count . value_or ( 0 ) ));
139+ AppendManifestCount (builder.column (9 ), manifest.existing_files_count , !data ));
130140 ICEBERG_RETURN_UNEXPECTED (
131- AppendInt (builder.column (10 ), data ? 0 : manifest.deleted_files_count . value_or ( 0 ) ));
141+ AppendManifestCount (builder.column (10 ), manifest.deleted_files_count , !data ));
132142
133143 ICEBERG_ASSIGN_OR_RAISE (auto partition_type, row.spec ->PartitionType (*table_schema));
134144 ICEBERG_RETURN_UNEXPECTED (AppendPartitionSummaries (
@@ -150,12 +160,13 @@ const std::shared_ptr<Schema>& ManifestsTable::schema() const {
150160 SchemaField::MakeRequired (2 , " length" , int64 ()),
151161 SchemaField::MakeRequired (3 , " partition_spec_id" , int32 ()),
152162 SchemaField::MakeRequired (4 , " added_snapshot_id" , int64 ()),
153- SchemaField::MakeRequired (5 , " added_data_files_count" , int32 ()),
154- SchemaField::MakeRequired (6 , " existing_data_files_count" , int32 ()),
155- SchemaField::MakeRequired (7 , " deleted_data_files_count" , int32 ()),
156- SchemaField::MakeRequired (15 , " added_delete_files_count" , int32 ()),
157- SchemaField::MakeRequired (16 , " existing_delete_files_count" , int32 ()),
158- SchemaField::MakeRequired (17 , " deleted_delete_files_count" , int32 ()),
163+ // Legacy manifests can omit counts; unknown counts must stay null.
164+ SchemaField::MakeOptional (5 , " added_data_files_count" , int32 ()),
165+ SchemaField::MakeOptional (6 , " existing_data_files_count" , int32 ()),
166+ SchemaField::MakeOptional (7 , " deleted_data_files_count" , int32 ()),
167+ SchemaField::MakeOptional (15 , " added_delete_files_count" , int32 ()),
168+ SchemaField::MakeOptional (16 , " existing_delete_files_count" , int32 ()),
169+ SchemaField::MakeOptional (17 , " deleted_delete_files_count" , int32 ()),
159170 SchemaField::MakeRequired (
160171 8 , " partition_summaries" ,
161172 list (SchemaField::MakeRequired (
@@ -181,9 +192,9 @@ Result<ArrowArrayStream> ManifestsTable::ScanSnapshot(
181192 std::vector<ManifestRow> rows;
182193 if (snapshot != nullptr ) {
183194 ICEBERG_ASSIGN_OR_RAISE (auto specs_ref, source_table ()->specs ());
184- SnapshotCache snapshot_cache (snapshot.get ());
195+ SnapshotReader snapshot_reader (snapshot.get ());
185196 ICEBERG_ASSIGN_OR_RAISE (auto manifests,
186- snapshot_cache .Manifests (source_table ()->io ()));
197+ snapshot_reader .Manifests (source_table ()->io ()));
187198 rows.reserve (manifests.size ());
188199 for (const auto & manifest : manifests) {
189200 auto spec = specs_ref.get ().find (manifest.partition_spec_id );
0 commit comments