@@ -1601,6 +1601,79 @@ TEST_P(GlobalIndexTest, TestDataEvolutionBatchScanWithPartitionWithTwoFields) {
16011601 }
16021602}
16031603
1604+ TEST_P (GlobalIndexTest, TestScanIndexWithTwoIndexes) {
1605+ arrow::FieldVector fields = {
1606+ arrow::field (" f0" , arrow::utf8 ()), arrow::field (" f1" , arrow::list (arrow::float32 ())),
1607+ arrow::field (" f2" , arrow::int32 ()), arrow::field (" f3" , arrow::float64 ())};
1608+ std::map<std::string, std::string> lumina_options = {
1609+ {" lumina.dimension" , " 4" },
1610+ {" lumina.indextype" , " bruteforce" },
1611+ {" lumina.distance.metric" , " l2" },
1612+ {" lumina.encoding.type" , " encoding.rawf32" },
1613+ {" lumina.search.threadcount" , " 10" }};
1614+ auto schema = arrow::schema (fields);
1615+ std::map<std::string, std::string> options = {{Options::MANIFEST_FORMAT, " orc" },
1616+ {Options::FILE_FORMAT, GetParam ()},
1617+ {Options::FILE_SYSTEM, " local" },
1618+ {Options::ROW_TRACKING_ENABLED, " true" },
1619+ {Options::DATA_EVOLUTION_ENABLED, " true" }};
1620+ CreateTable (/* partition_keys=*/ {}, schema, options);
1621+
1622+ std::string table_path = PathUtil::JoinPath (dir_->Str (), " foo.db/bar" );
1623+ std::vector<std::string> write_cols = schema->field_names ();
1624+
1625+ auto src_array = std::dynamic_pointer_cast<arrow::StructArray>(
1626+ arrow::ipc::internal::json::ArrayFromJSON (arrow::struct_ (fields), R"( [
1627+ ["Alice", [0.0, 0.0, 0.0, 0.0], 10, 11.1],
1628+ ["Bob", [0.0, 1.0, 0.0, 1.0], 10, 12.1],
1629+ ["Emily", [1.0, 0.0, 1.0, 0.0], 10, 13.1],
1630+ ["Tony", [1.0, 1.0, 1.0, 1.0], 10, 14.1],
1631+ ["Lucy", [10.0, 10.0, 10.0, 10.0], 20, 15.1],
1632+ ["Bob", [10.0, 11.0, 10.0, 11.0], 20, 16.1],
1633+ ["Tony", [11.0, 10.0, 11.0, 10.0], 20, 17.1],
1634+ ["Alice", [11.0, 11.0, 11.0, 11.0], 20, 18.1],
1635+ ["Paul", [10.0, 10.0, 10.0, 10.0], 20, 19.1]
1636+ ])" )
1637+ .ValueOrDie ());
1638+ ASSERT_OK_AND_ASSIGN (auto commit_msgs, WriteArray (table_path, write_cols, src_array));
1639+ ASSERT_OK (Commit (table_path, commit_msgs));
1640+
1641+ // write and commit bitmap global index
1642+ ASSERT_OK (WriteIndex (table_path, /* partition_filters=*/ {}, " f0" , " bitmap" ,
1643+ /* options=*/ {}, Range (0 , 8 )));
1644+
1645+ // write and commit lumina global index
1646+ ASSERT_OK (WriteIndex (table_path, /* partition_filters=*/ {}, " f1" , " lumina" ,
1647+ /* options=*/ lumina_options, Range (0 , 8 )));
1648+
1649+ ASSERT_OK_AND_ASSIGN (
1650+ auto global_index_scan,
1651+ GlobalIndexScan::Create (table_path, /* snapshot_id=*/ std::nullopt ,
1652+ /* partitions=*/ std::nullopt , /* options=*/ lumina_options,
1653+ /* file_system=*/ nullptr , pool_));
1654+ ASSERT_OK_AND_ASSIGN (std::vector<Range> ranges, global_index_scan->GetRowRangeList ());
1655+ ASSERT_EQ (ranges, std::vector<Range>({Range (0 , 8 )}));
1656+ ASSERT_OK_AND_ASSIGN (auto range_scanner, global_index_scan->CreateRangeScan (Range (0 , 8 )));
1657+ // query f0
1658+ ASSERT_OK_AND_ASSIGN (auto index_readers, range_scanner->CreateReaders (" f0" ));
1659+ ASSERT_EQ (index_readers.size (), 1 );
1660+ ASSERT_OK_AND_ASSIGN (auto index_result,
1661+ index_readers[0 ]->VisitEqual (Literal (FieldType::STRING, " Alice" , 5 )));
1662+ ASSERT_EQ (index_result->ToString (), " {0,7}" );
1663+
1664+ // query f1
1665+ ASSERT_OK_AND_ASSIGN (index_readers, range_scanner->CreateReaders (" f1" ));
1666+ ASSERT_EQ (index_readers.size (), 1 );
1667+ std::vector<float > query = {11 .0f , 11 .0f , 11 .0f , 11 .0f };
1668+ ASSERT_OK_AND_ASSIGN (auto topk_result, index_readers[0 ]->VisitTopK (1 , query, /* filter=*/ nullptr ,
1669+ /* predicate*/ nullptr ));
1670+ ASSERT_EQ (topk_result->ToString (), " row ids: {7}, scores: {0}" );
1671+
1672+ // query f2
1673+ ASSERT_OK_AND_ASSIGN (index_readers, range_scanner->CreateReaders (" f2" ));
1674+ ASSERT_EQ (index_readers.size (), 0 );
1675+ }
1676+
16041677std::vector<std::string> GetTestValuesForGlobalIndexTest () {
16051678 std::vector<std::string> values = {" parquet" };
16061679#ifdef PAIMON_ENABLE_ORC
0 commit comments