@@ -90,7 +90,7 @@ TEST(FileSystemCatalogTest, TestCreateSystemDatabaseAndTable) {
9090 /* ignore_if_exists=*/ true ),
9191 " Cannot create database for system database" );
9292 }
93- // do not support create system table
93+ // / Do not support create system table.
9494 {
9595 std::map<std::string, std::string> options;
9696 options[Options::FILE_SYSTEM ] = " local" ;
@@ -281,6 +281,100 @@ TEST(FileSystemCatalogTest, TestAuditLogAndBinlogSystemTableCatalog) {
281281 " Cannot rename system table" );
282282}
283283
284+ TEST (FileSystemCatalogTest, TestMetadataSystemTableCatalog) {
285+ std::map<std::string, std::string> options;
286+ options[Options::FILE_SYSTEM ] = " local" ;
287+ options[Options::FILE_FORMAT ] = " orc" ;
288+ ASSERT_OK_AND_ASSIGN (auto core_options, CoreOptions::FromMap (options));
289+ auto dir = UniqueTestDirectory::Create ();
290+ ASSERT_TRUE (dir);
291+ FileSystemCatalog catalog (core_options.GetFileSystem (), dir->Str ());
292+ ASSERT_OK (catalog.CreateDatabase (" db1" , options, /* ignore_if_exists=*/ true ));
293+
294+ auto typed_schema =
295+ arrow::schema ({arrow::field (" pk" , arrow::utf8 ()), arrow::field (" v" , arrow::int32 ())});
296+ ::ArrowSchema schema;
297+ ASSERT_TRUE (arrow::ExportSchema (*typed_schema, &schema).ok ());
298+ ASSERT_OK (catalog.CreateTable (Identifier (" db1" , " tbl1" ), &schema,
299+ /* partition_keys=*/ {}, /* primary_keys=*/ {" pk" }, options,
300+ /* ignore_if_exists=*/ false ));
301+ ArrowSchemaRelease (&schema);
302+
303+ std::vector<std::string> metadata_tables = {" snapshots" , " schemas" , " tags" , " branches" ,
304+ " consumers" };
305+ for (const auto & table_name : metadata_tables) {
306+ Identifier system_identifier (" db1" , " tbl1$" + table_name);
307+ ASSERT_OK_AND_ASSIGN (bool exists, catalog.TableExists (system_identifier));
308+ ASSERT_TRUE (exists) << table_name;
309+ ASSERT_OK_AND_ASSIGN (std::shared_ptr<Schema> system_schema,
310+ catalog.LoadTableSchema (system_identifier));
311+ ASSERT_TRUE (std::dynamic_pointer_cast<SystemTableSchema>(system_schema) != nullptr )
312+ << table_name;
313+ ASSERT_OK_AND_ASSIGN (auto c_schema, system_schema->GetArrowSchema ());
314+ auto loaded_schema_result = arrow::ImportSchema (c_schema.get ());
315+ ASSERT_TRUE (loaded_schema_result.ok ()) << loaded_schema_result.status ().ToString ();
316+ ASSERT_GT (loaded_schema_result.ValueUnsafe ()->num_fields (), 0 ) << table_name;
317+ }
318+
319+ ASSERT_OK_AND_ASSIGN (std::shared_ptr<Schema> snapshots_schema,
320+ catalog.LoadTableSchema (Identifier (" db1" , " tbl1$snapshots" )));
321+ ASSERT_OK_AND_ASSIGN (auto snapshots_c_schema, snapshots_schema->GetArrowSchema ());
322+ auto snapshots_arrow_schema = arrow::ImportSchema (snapshots_c_schema.get ()).ValueUnsafe ();
323+ ASSERT_EQ (snapshots_arrow_schema->field_names (),
324+ (std::vector<std::string>{
325+ " snapshot_id" , " schema_id" , " commit_user" , " commit_identifier" , " commit_kind" ,
326+ " commit_time" , " base_manifest_list" , " delta_manifest_list" ,
327+ " changelog_manifest_list" , " total_record_count" , " delta_record_count" ,
328+ " changelog_record_count" , " watermark" , " next_row_id" }));
329+ ASSERT_EQ (snapshots_arrow_schema->field (5 )->type ()->id (), arrow::Type::TIMESTAMP );
330+
331+ ASSERT_OK_AND_ASSIGN (std::shared_ptr<Schema> schemas_schema,
332+ catalog.LoadTableSchema (Identifier (" db1" , " tbl1$schemas" )));
333+ ASSERT_OK_AND_ASSIGN (auto schemas_c_schema, schemas_schema->GetArrowSchema ());
334+ auto schemas_arrow_schema = arrow::ImportSchema (schemas_c_schema.get ()).ValueUnsafe ();
335+ ASSERT_EQ (schemas_arrow_schema->field_names (),
336+ (std::vector<std::string>{" schema_id" , " fields" , " partition_keys" , " primary_keys" ,
337+ " options" , " comment" , " update_time" }));
338+ ASSERT_EQ (schemas_arrow_schema->field (6 )->type ()->id (), arrow::Type::TIMESTAMP );
339+
340+ ASSERT_OK_AND_ASSIGN (std::shared_ptr<Schema> tags_schema,
341+ catalog.LoadTableSchema (Identifier (" db1" , " tbl1$tags" )));
342+ ASSERT_OK_AND_ASSIGN (auto tags_c_schema, tags_schema->GetArrowSchema ());
343+ auto tags_arrow_schema = arrow::ImportSchema (tags_c_schema.get ()).ValueUnsafe ();
344+ ASSERT_EQ (tags_arrow_schema->field_names (),
345+ (std::vector<std::string>{" tag_name" , " snapshot_id" , " schema_id" , " commit_time" ,
346+ " record_count" , " create_time" , " time_retained" }));
347+ ASSERT_EQ (tags_arrow_schema->field (3 )->type ()->id (), arrow::Type::TIMESTAMP );
348+ ASSERT_EQ (tags_arrow_schema->field (5 )->type ()->id (), arrow::Type::TIMESTAMP );
349+
350+ ASSERT_OK_AND_ASSIGN (std::shared_ptr<Schema> branches_schema,
351+ catalog.LoadTableSchema (Identifier (" db1" , " tbl1$branches" )));
352+ ASSERT_OK_AND_ASSIGN (auto branches_c_schema, branches_schema->GetArrowSchema ());
353+ auto branches_arrow_schema = arrow::ImportSchema (branches_c_schema.get ()).ValueUnsafe ();
354+ ASSERT_EQ (branches_arrow_schema->field_names (),
355+ (std::vector<std::string>{" branch_name" , " create_time" }));
356+ ASSERT_EQ (branches_arrow_schema->field (1 )->type ()->id (), arrow::Type::TIMESTAMP );
357+
358+ ASSERT_OK_AND_ASSIGN (std::shared_ptr<Schema> consumers_schema,
359+ catalog.LoadTableSchema (Identifier (" db1" , " tbl1$consumers" )));
360+ ASSERT_OK_AND_ASSIGN (auto consumers_c_schema, consumers_schema->GetArrowSchema ());
361+ auto consumers_arrow_schema = arrow::ImportSchema (consumers_c_schema.get ()).ValueUnsafe ();
362+ ASSERT_EQ (consumers_arrow_schema->field_names (),
363+ (std::vector<std::string>{" consumer_id" , " next_snapshot_id" }));
364+ ASSERT_FALSE (consumers_arrow_schema->field (1 )->nullable ());
365+
366+ Identifier snapshots_identifier (" db1" , " tbl1$snapshots" );
367+ ::ArrowSchema system_create_schema;
368+ ASSERT_TRUE (arrow::ExportSchema (*typed_schema, &system_create_schema).ok ());
369+ ASSERT_NOK_WITH_MSG (
370+ catalog.CreateTable (snapshots_identifier, &system_create_schema, {}, {}, options, false ),
371+ " Cannot create table for system table" );
372+ ArrowSchemaRelease (&system_create_schema);
373+ ASSERT_NOK_WITH_MSG (catalog.DropTable (snapshots_identifier, false ), " Cannot drop system table" );
374+ ASSERT_NOK_WITH_MSG (catalog.RenameTable (snapshots_identifier, Identifier (" db1" , " tbl2" ), false ),
375+ " Cannot rename system table" );
376+ }
377+
284378TEST (FileSystemCatalogTest, TestCreateTableWithBlob) {
285379 std::map<std::string, std::string> options;
286380 options[Options::FILE_SYSTEM ] = " local" ;
@@ -625,7 +719,7 @@ TEST(FileSystemCatalogTest, TestDropTable) {
625719 ASSERT_OK_AND_ASSIGN (bool exist, catalog.TableExists (Identifier (" test_db" , " tbl1" )));
626720 ASSERT_FALSE (exist);
627721
628- // Test 4: Drop system table
722+ // / Test 4: Drop system table.
629723 ASSERT_NOK_WITH_MSG (
630724 catalog.DropTable (Identifier (" test_db" , " tbl$system" ),
631725 /* ignore_if_not_exists=*/ false ),
@@ -691,7 +785,7 @@ TEST(FileSystemCatalogTest, TestRenameTable) {
691785 /* ignore_if_not_exists=*/ false ),
692786 " Cannot rename table across databases. Cross-database rename is not supported." );
693787
694- // Test 6: Rename system table
788+ // / Test 6: Rename system table.
695789 ASSERT_NOK_WITH_MSG (catalog.RenameTable (Identifier (" test_db" , " tbl$system" ),
696790 Identifier (" test_db" , " new_system_tbl" ),
697791 /* ignore_if_not_exists=*/ false ),
0 commit comments