JingsongLi commented on code in PR #10503:
URL: https://github.com/apache/paimon/pull/10503#discussion_r4244705566


##########
paimon-python/pypaimon/tests/rest/rest_server.py:
##########
@@ -197,6 +211,103 @@ def _dict_to_schema_change(change_dict: dict) -> 
SchemaChange:
         raise ValueError(f"Unknown schema change action: {action}")
 
 
+def _cursor_key(*parts: Optional[str]) -> str:
+    return "".join("-1:" if part is None else "{}:{}".format(len(part), part) 
for part in parts)
+
+
+def _permission_key(resource: PermissionResource, access: str, principal: str) 
-> str:
+    return _cursor_key(resource.get_type().name, resource.get_database(), 
resource.get_table(),
+                       resource.get_function(), resource.get_view(),
+                       PermissionAccess.canonicalize_for(resource, access), 
principal)
+
+
+def _assignment_key(assignment: PermissionAssignment) -> str:
+    return _permission_key(
+        assignment.get_resource(), assignment.get_access(), 
assignment.get_principal())
+
+
+def _policy_identity(policy: DataPolicy) -> Tuple[str, str, Optional[str]]:
+    mask = policy.get_column_mask()
+    return policy.type().name, policy.get_principal(), None if mask is None 
else mask.get_on_column()
+
+
+def _policy_key(policy: DataPolicy) -> str:
+    return _cursor_key(*_policy_identity(policy))
+
+
+def _policy_name(policy_type: str, principal: str, column: Optional[str]) -> 
str:
+    return ":".join(part for part in (policy_type, principal, column) if part 
is not None)
+
+
+def _resource_name(resource: PermissionResource) -> str:
+    name = resource.get_table() or resource.get_function() or 
resource.get_view()
+    return ".".join(part for part in (resource.get_database(), name) if part) 
or "catalog"
+
+
+def _referenced_columns(node: Any) -> set:
+    if isinstance(node, list):
+        return set().union(*(_referenced_columns(item) for item in node))
+    if not isinstance(node, dict):
+        return set()
+    found = {node["name"]} if "index" in node and "name" in node else set()

Review Comment:
   [P2] Collect name-only FIELD_REF references before validating schema changes
   
   A valid row-filter fieldRef can omit `index`, e.g. 
`{"kind":"LEAF","transform":{"name":"FIELD_REF","fieldRef":{"name":"id","type":"BIGINT"}},"function":"EQUAL","literals":[1]}`.
 Both the existing Python predicate parser and Java's FieldRef/remapping 
support this. Requiring `index` here makes `_policy_columns` return an empty 
set. I reproduced through HTTP: create this policy on `id`, then rename `id` to 
`user_id`; the rename succeeds and the stored policy still references `id`. 
This bypasses the new policy-preserving schema guard and leaves subsequent 
authorized reads with a stale policy. Please recognize field references by 
their transform structure/name, and cover the name-only form for policy 
creation and column rename/drop.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to