This is an automated email from the ASF dual-hosted git repository.
JingsongLi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/paimon.git
The following commit(s) were added to refs/heads/master by this push:
new 606d2dff70 [python] Refuse physical metadata system tables on
query-auth tables (#10839)
606d2dff70 is described below
commit 606d2dff7066a47648910841adaaab18b8a31359
Author: Jiajia Li <[email protected]>
AuthorDate: Wed Oct 28 20:01:46 2026 +0800
[python] Refuse physical metadata system tables on query-auth tables
(#10839)
---
.../pypaimon/table/system/system_table_loader.py | 8 +++++++
.../system/system_table_catalog_dispatch_test.py | 26 +++++++++++++++++++++-
2 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/paimon-python/pypaimon/table/system/system_table_loader.py
b/paimon-python/pypaimon/table/system/system_table_loader.py
index b924fab248..f6c9087b50 100644
--- a/paimon-python/pypaimon/table/system/system_table_loader.py
+++ b/paimon-python/pypaimon/table/system/system_table_loader.py
@@ -81,12 +81,20 @@ SYSTEM_TABLE_LOADERS: Dict[str, Callable[...,
"SystemTable"]] = {
}
+_PHYSICAL_METADATA_TABLES = ("files", "file_key_ranges", "binlog",
"statistics")
+
+
def load(name: str, base_table: "FileStoreTable") -> Optional["SystemTable"]:
"""Return the SystemTable implementation for ``name`` or ``None``.
Callers (typically a Catalog) treat ``None`` as "no such system
table" and surface a ``TableNotExistException`` to the user.
"""
+ name = name.lower()
+ if name in _PHYSICAL_METADATA_TABLES and
base_table.options.query_auth_enabled:
+ raise NotImplementedError(
+ "System table '{}' is not supported on a query-auth table: it
reports "
+ "raw file statistics, which column masking cannot be applied
to.".format(name))
factory = SYSTEM_TABLE_LOADERS.get(name)
if factory is None:
return None
diff --git
a/paimon-python/pypaimon/tests/system/system_table_catalog_dispatch_test.py
b/paimon-python/pypaimon/tests/system/system_table_catalog_dispatch_test.py
index ef47e97924..fcb3475cdf 100644
--- a/paimon-python/pypaimon/tests/system/system_table_catalog_dispatch_test.py
+++ b/paimon-python/pypaimon/tests/system/system_table_catalog_dispatch_test.py
@@ -31,6 +31,7 @@ import unittest
from pypaimon import CatalogFactory, Schema
from pypaimon.catalog.catalog_exception import TableNotExistException
+from pypaimon.common.options.core_options import CoreOptions
from pypaimon.schema.data_types import DataField
from pypaimon.table.file_store_table import FileStoreTable
from pypaimon.table.system import system_table_loader
@@ -107,6 +108,21 @@ class
FilesystemCatalogSystemTableDispatchTest(unittest.TestCase):
with self.assertRaises(TableNotExistException):
self.catalog.get_table("db.does_not_exist$snapshots")
+ def test_query_auth_rejects_physical_metadata_tables(self):
+ fields = self.catalog.get_table("db.t").fields
+ self.catalog.create_table(
+ "db.auth", Schema(fields=fields, options={"query-auth.enabled":
"true"}), False)
+ for name in ("files", "file_key_ranges", "binlog", "statistics",
"FILES"):
+ with self.subTest(name=name):
+ with self.assertRaises(NotImplementedError) as cm:
+ self.catalog.get_table("db.auth$" + name)
+ self.assertEqual(
+ "System table '{}' is not supported on a query-auth table:
it reports "
+ "raw file statistics, which column masking cannot be
applied to.".format(name.lower()),
+ str(cm.exception))
+ self.assertEqual("snapshots",
self.catalog.get_table("db.auth$snapshots").system_table_name())
+ self.assertEqual("files",
self.catalog.get_table("db.t$files").system_table_name())
+
class RestCatalogSystemTableDispatchTest(unittest.TestCase):
"""Tests that RESTCatalog.get_table dispatches identically to FileSystem.
@@ -117,7 +133,7 @@ class RestCatalogSystemTableDispatchTest(unittest.TestCase):
Stubbing it lets these tests stay fast and focused on the new branch.
"""
- def _build_catalog(self):
+ def _build_catalog(self, options=None):
from pypaimon.catalog.rest.rest_catalog import RESTCatalog
catalog = RESTCatalog.__new__(RESTCatalog)
@@ -139,6 +155,7 @@ class RestCatalogSystemTableDispatchTest(unittest.TestCase):
base = _FakeBaseTable()
base.identifier = identifier
+ base.options = CoreOptions.from_dict(options or {})
return base
catalog._load_data_table = fake_load_data_table
@@ -189,6 +206,13 @@ class
RestCatalogSystemTableDispatchTest(unittest.TestCase):
with self.assertRaises(TableNotExistException):
catalog.get_table("db.t$definitely_not_a_system_table")
+ def test_query_auth_rejects_physical_metadata_tables(self):
+ catalog, _ = self._build_catalog({"query-auth.enabled": "true"})
+ for name in ("files", "file_key_ranges", "binlog", "statistics"):
+ with self.subTest(name=name):
+ with self.assertRaisesRegex(NotImplementedError, "not
supported on a query-auth table"):
+ catalog.get_table("db.t$" + name)
+
if __name__ == "__main__":
unittest.main()