@@ -985,6 +985,70 @@ TEST(SystemTableReadInteTest, TestReadOptimizedPrimaryKeyProjectionAndPredicateP
985985 ASSERT_TRUE (result->Equals (expected)) << result->ToString ();
986986}
987987
988+ TEST (SystemTableReadInteTest, TestReadOptimizedSystemTableNestedProjection) {
989+ auto payload_type =
990+ arrow::struct_ ({arrow::field (" a" , arrow::int32 ()), arrow::field (" b" , arrow::utf8 ())});
991+ arrow::FieldVector fields = {
992+ arrow::field (" k" , arrow::int32 ()),
993+ arrow::field (" payload" , payload_type),
994+ arrow::field (" extra" , arrow::int32 ()),
995+ };
996+ auto schema = arrow::schema (fields);
997+ std::map<std::string, std::string> options = {{Options::FILE_SYSTEM , " local" },
998+ {Options::FILE_FORMAT , " parquet" },
999+ {Options::MANIFEST_FORMAT , " avro" },
1000+ {Options::BUCKET , " 1" },
1001+ {Options::BUCKET_KEY , " k" }};
1002+ auto dir = UniqueTestDirectory::Create ();
1003+ ASSERT_TRUE (dir);
1004+ ASSERT_OK_AND_ASSIGN (std::unique_ptr<TestHelper> helper,
1005+ TestHelper::Create (dir->Str (), schema,
1006+ /* partition_keys=*/ {}, /* primary_keys=*/ {" k" }, options,
1007+ /* is_streaming_mode=*/ true ));
1008+ std::string table_path = PathUtil::JoinPath (dir->Str (), " foo.db/bar" );
1009+
1010+ ASSERT_OK_AND_ASSIGN (
1011+ std::unique_ptr<RecordBatch> batch,
1012+ TestHelper::MakeRecordBatch (arrow::struct_ (fields),
1013+ R"( [[1, [10, "x"], 100], [2, [20, "y"], 200]])" ,
1014+ /* partition_map=*/ {}, /* bucket=*/ 0 , {}));
1015+ ASSERT_OK (WriteAndFullCompact (std::move (batch), /* commit_identifier=*/ 0 , helper.get ()));
1016+
1017+ ScanContextBuilder scan_context_builder (table_path + " $ro" );
1018+ scan_context_builder.SetOptions (options);
1019+ ASSERT_OK_AND_ASSIGN (std::unique_ptr<ScanContext> scan_context, scan_context_builder.Finish ());
1020+ ASSERT_OK_AND_ASSIGN (std::unique_ptr<TableScan> table_scan,
1021+ TableScan::Create (std::move (scan_context)));
1022+ ASSERT_OK_AND_ASSIGN (std::shared_ptr<Plan> plan, table_scan->CreatePlan ());
1023+
1024+ auto projected_schema = arrow::schema ({
1025+ arrow::field (" k" , arrow::int32 ()),
1026+ arrow::field (" payload" , arrow::struct_ ({arrow::field (" a" , arrow::int32 ())})),
1027+ });
1028+ auto c_projected_schema = std::make_unique<ArrowSchema>();
1029+ ASSERT_TRUE (arrow::ExportSchema (*projected_schema, c_projected_schema.get ()).ok ());
1030+ ReadContextBuilder read_context_builder (table_path + " $ro" );
1031+ read_context_builder.SetOptions (options).SetReadSchema (std::move (c_projected_schema));
1032+ ASSERT_OK_AND_ASSIGN (std::unique_ptr<ReadContext> read_context, read_context_builder.Finish ());
1033+ ASSERT_OK_AND_ASSIGN (std::unique_ptr<TableRead> table_read,
1034+ TableRead::Create (std::move (read_context)));
1035+ ASSERT_OK_AND_ASSIGN (std::unique_ptr<BatchReader> batch_reader,
1036+ table_read->CreateReader (plan->Splits ()));
1037+ ASSERT_OK_AND_ASSIGN (std::shared_ptr<arrow::ChunkedArray> result,
1038+ ReadResultCollector::CollectResult (batch_reader.get ()));
1039+
1040+ std::shared_ptr<arrow::DataType> expected_type = arrow::struct_ ({
1041+ arrow::field (" _VALUE_KIND" , arrow::int8 ()),
1042+ arrow::field (" k" , arrow::int32 ()),
1043+ arrow::field (" payload" , arrow::struct_ ({arrow::field (" a" , arrow::int32 ())})),
1044+ });
1045+ std::shared_ptr<arrow::ChunkedArray> expected;
1046+ ASSERT_TRUE (arrow::ipc::internal::json::ChunkedArrayFromJSON (
1047+ expected_type, {R"( [[0, 1, [10]], [0, 2, [20]]])" }, &expected)
1048+ .ok ());
1049+ ASSERT_TRUE (result->Equals (expected)) << result->ToString ();
1050+ }
1051+
9881052TEST (SystemTableReadInteTest, TestReadOptimizedSystemTableWithBranch) {
9891053 arrow::FieldVector fields = {
9901054 arrow::field (" k" , arrow::int32 ()),
0 commit comments