@@ -104,8 +104,7 @@ class MapSharedShreddingFileReaderTest : public ::testing::Test {
104104 const std::optional<std::string>& selected_keys_str = std::nullopt ) const {
105105 EXPECT_OK_AND_ASSIGN (auto c_file_schema, reader->GetFileSchema ());
106106 auto file_schema = arrow::ImportSchema (c_file_schema.get ()).ValueOrDie ();
107- std::map<std::string, MapSharedShreddingFileReader::SharedShreddingContext>
108- shared_shredding_name_to_context;
107+ std::map<std::string, std::unique_ptr<MapFieldReadPlan>> field_read_plans;
109108 for (const auto & field : file_schema->fields ()) {
110109 auto metadata = std::const_pointer_cast<arrow::KeyValueMetadata>(field->metadata ());
111110 if (!MapSharedShreddingUtils::HasShreddingMetadata (metadata)) {
@@ -135,12 +134,14 @@ class MapSharedShreddingFileReaderTest : public ::testing::Test {
135134 selected_keys.push_back (key_name);
136135 }
137136 }
138- shared_shredding_name_to_context.emplace (
139- field->name (), MapSharedShreddingFileReader::SharedShreddingContext (
140- meta, selected_keys, map_type));
137+ auto logical_map_field = field->WithType (map_type);
138+ EXPECT_OK_AND_ASSIGN (auto field_read_plan,
139+ MapFieldReadPlanFactory::CreateFullMapReadPlan (
140+ logical_map_field, meta, selected_keys));
141+ field_read_plans.emplace (field->name (), std::move (field_read_plan));
141142 }
142- return std::make_unique<MapSharedShreddingFileReader>(
143- std::move (reader), std::move (shared_shredding_name_to_context ), pool_);
143+ return std::make_unique<MapSharedShreddingFileReader>(std::move (reader),
144+ std::move (field_read_plans ), pool_);
144145 }
145146
146147 Result<std::unique_ptr<MapSharedShreddingFileReader>> CreateReader (
@@ -299,6 +300,94 @@ TEST_F(MapSharedShreddingFileReaderTest, TestAllExistSelectedKeysWithOverflow) {
299300 AssertChunkedArrayEquals (expected, actual);
300301}
301302
303+ TEST_F (MapSharedShreddingFileReaderTest, TestSelectedKeysStructProjection) {
304+ ASSERT_OK_AND_ASSIGN (auto physical_schema, PhysicalSchemaWithMetadata ());
305+ ASSERT_OK_AND_ASSIGN (auto physical_array, PhysicalArray ());
306+ auto mock_reader = std::make_unique<MockFileBatchReader>(
307+ physical_array, arrow::struct_ (physical_schema->fields ()), /* read_batch_size=*/ 10 );
308+ mock_reader->EnableRandomizeBatchSize (false );
309+
310+ auto selected_type =
311+ arrow::struct_ ({arrow::field (" 0" , arrow::int64 ()), arrow::field (" 1" , arrow::int64 ()),
312+ arrow::field (" 2" , arrow::int64 ())});
313+ auto selected_field = arrow::field (
314+ " tags" , selected_type, /* nullable=*/ true ,
315+ arrow::KeyValueMetadata::Make ({DataField::MAP_SELECTED_KEYS }, {" a,c,missing" }));
316+ ASSERT_OK_AND_ASSIGN (auto field_read_plan,
317+ MapFieldReadPlanFactory::CreateSharedSelectedKeysReadPlan (
318+ selected_field, TagsMeta (), {" a" , " c" , " missing" }));
319+ std::map<std::string, std::unique_ptr<MapFieldReadPlan>> contexts;
320+ contexts.emplace (" tags" , std::move (field_read_plan));
321+ auto reader = std::make_unique<MapSharedShreddingFileReader>(std::move (mock_reader),
322+ std::move (contexts), pool_);
323+
324+ auto read_schema =
325+ ExportSchema (arrow::schema ({arrow::field (" id" , arrow::int32 ()), selected_field}));
326+ ASSERT_OK (reader->SetReadSchema (read_schema.get (), /* predicate=*/ nullptr ,
327+ /* selection_bitmap=*/ std::nullopt ));
328+ ASSERT_OK_AND_ASSIGN (auto actual, ReadResultCollector::CollectResult (reader.get ()));
329+
330+ auto expected_type = arrow::struct_ ({arrow::field (" id" , arrow::int32 ()), selected_field});
331+ std::shared_ptr<arrow::ChunkedArray> expected;
332+ ASSERT_TRUE (arrow::ipc::internal::json::ChunkedArrayFromJSON (expected_type, {R"( [
333+ [1, [10, null, null]],
334+ [2, [40, 30, null]],
335+ [3, null],
336+ [4, [80, null, null]]
337+ ])" },
338+ &expected)
339+ .ok ());
340+ AssertChunkedArrayEquals (expected, actual);
341+ }
342+
343+ TEST_F (MapSharedShreddingFileReaderTest, TestSelectedKeysStructProjectionFromLegacyMap) {
344+ auto map_type = arrow::internal::checked_pointer_cast<arrow::MapType>(
345+ arrow::map (arrow::utf8 (), arrow::field (" value" , arrow::int64 ())));
346+ auto file_schema =
347+ arrow::schema ({arrow::field (" id" , arrow::int32 ()), arrow::field (" tags" , map_type)});
348+ auto file_array =
349+ arrow::ipc::internal::json::ArrayFromJSON (arrow::struct_ (file_schema->fields ()),
350+ R"( [
351+ [1, [["a", 10], ["c", null]]],
352+ [2, [["b", 20]]],
353+ [3, null]
354+ ])" )
355+ .ValueOrDie ();
356+ auto mock_reader = std::make_unique<MockFileBatchReader>(
357+ file_array, arrow::struct_ (file_schema->fields ()), /* read_batch_size=*/ 10 );
358+ mock_reader->EnableRandomizeBatchSize (false );
359+
360+ auto selected_type =
361+ arrow::struct_ ({arrow::field (" 0" , arrow::int64 ()), arrow::field (" 1" , arrow::int64 ())});
362+ auto selected_field =
363+ arrow::field (" tags" , selected_type, /* nullable=*/ true ,
364+ arrow::KeyValueMetadata::Make ({DataField::MAP_SELECTED_KEYS }, {" a,missing" }));
365+ ASSERT_OK_AND_ASSIGN (auto field_read_plan,
366+ MapFieldReadPlanFactory::CreateDefaultSelectedKeysReadPlan (
367+ file_schema->field (1 ), selected_field, {" a" , " missing" }));
368+ std::map<std::string, std::unique_ptr<MapFieldReadPlan>> contexts;
369+ contexts.emplace (" tags" , std::move (field_read_plan));
370+ auto reader = std::make_unique<MapSharedShreddingFileReader>(std::move (mock_reader),
371+ std::move (contexts), pool_);
372+
373+ auto read_schema =
374+ ExportSchema (arrow::schema ({arrow::field (" id" , arrow::int32 ()), selected_field}));
375+ ASSERT_OK (reader->SetReadSchema (read_schema.get (), /* predicate=*/ nullptr ,
376+ /* selection_bitmap=*/ std::nullopt ));
377+ ASSERT_OK_AND_ASSIGN (auto actual, ReadResultCollector::CollectResult (reader.get ()));
378+
379+ auto expected_type = arrow::struct_ ({arrow::field (" id" , arrow::int32 ()), selected_field});
380+ std::shared_ptr<arrow::ChunkedArray> expected;
381+ ASSERT_TRUE (arrow::ipc::internal::json::ChunkedArrayFromJSON (expected_type, {R"( [
382+ [1, [10, null]],
383+ [2, [null, null]],
384+ [3, null]
385+ ])" },
386+ &expected)
387+ .ok ());
388+ AssertChunkedArrayEquals (expected, actual);
389+ }
390+
302391TEST_F (MapSharedShreddingFileReaderTest, TestPartialExistSelectedKeys) {
303392 ASSERT_OK_AND_ASSIGN (auto reader,
304393 CreateReader (/* physical_array=*/ nullptr , /* physical_schema=*/ nullptr ,
0 commit comments