diff --git a/paimon-python/pypaimon/common/identifier.py b/paimon-python/pypaimon/common/identifier.py
index 45615233d1ec..a8ce6fbea0e3 100755
--- a/paimon-python/pypaimon/common/identifier.py
+++ b/paimon-python/pypaimon/common/identifier.py
@@ -107,4 +107,9 @@ def __hash__(self):
return hash((self.database, self.object, self.branch))
def is_system_table(self) -> bool:
- return self.object.startswith('$')
+ if SYSTEM_TABLE_SPLITTER not in self.object:
+ return False
+ parts = self.object.split(SYSTEM_TABLE_SPLITTER)
+ if len(parts) == 2:
+ return not parts[1].startswith(SYSTEM_BRANCH_PREFIX)
+ return len(parts) == 3
diff --git a/paimon-python/pypaimon/tests/identifier_test.py b/paimon-python/pypaimon/tests/identifier_test.py
index 7bb6bb548aab..806f16d599bc 100644
--- a/paimon-python/pypaimon/tests/identifier_test.py
+++ b/paimon-python/pypaimon/tests/identifier_test.py
@@ -92,6 +92,22 @@ def test_invalid_backtick_format_raises_error(self):
with self.assertRaises(ValueError):
Identifier.from_string("`a`.`b`.`c`")
+ def test_is_system_table_regular_table(self):
+ """A plain table object is not a system table."""
+ self.assertFalse(Identifier.create("mydb", "mytable").is_system_table())
+
+ def test_is_system_table_snapshots_suffix(self):
+ """object name '$snapshots' is a system table."""
+ self.assertTrue(Identifier.create("mydb", "orders$snapshots").is_system_table())
+
+ def test_is_system_table_schemas_suffix(self):
+ """object name '$schemas' is a system table."""
+ self.assertTrue(Identifier.create("mydb", "orders$schemas").is_system_table())
+
+ def test_is_system_table_files_suffix(self):
+ """object name '$files' is a system table."""
+ self.assertTrue(Identifier.create("mydb", "orders$files").is_system_table())
+
if __name__ == '__main__':
unittest.main()