@@ -75,13 +75,26 @@ def __init__(self, identifier=None):
7575
7676
7777class _FakeScan :
78- def __init__ (self , plan , identifier = None ):
78+ def __init__ (self , plan , identifier = None , auth_result = None ):
7979 self ._plan = plan
8080 self .table = _FakeTable (identifier )
81+ self .file_scanner = _FakeFileScanner (plan )
82+ self ._auth_result = auth_result
8183
8284 def plan (self ):
8385 return self ._plan
8486
87+ def _TableScan__auth_query (self ):
88+ return self ._auth_result
89+
90+
91+ class _FakeFileScanner :
92+ def __init__ (self , plan ):
93+ self ._plan = plan
94+
95+ def scan (self ):
96+ return self ._plan
97+
8598
8699def _simple_filter_json (field_name = "dept" , value = "eng" ):
87100 return json .dumps ({
@@ -113,12 +126,28 @@ def test_no_auth_returns_original_plan(self):
113126 converted = result .convert_plan (plan )
114127 self .assertIs (converted , plan )
115128
129+ def test_no_auth_has_no_restrictions (self ):
130+ result = TableQueryAuthResult (None , None )
131+ self .assertFalse (result .has_restrictions )
132+
116133 def test_empty_filter_and_masking_returns_original (self ):
117134 result = TableQueryAuthResult ([], {})
118135 plan = _FakePlan ([_FakeSplit ()])
119136 converted = result .convert_plan (plan )
120137 self .assertIs (converted , plan )
121138
139+ def test_empty_filter_and_masking_has_no_restrictions (self ):
140+ result = TableQueryAuthResult ([], {})
141+ self .assertFalse (result .has_restrictions )
142+
143+ def test_filter_has_restrictions (self ):
144+ result = TableQueryAuthResult ([_simple_filter_json ()], None )
145+ self .assertTrue (result .has_restrictions )
146+
147+ def test_masking_has_restrictions (self ):
148+ result = TableQueryAuthResult (None , {"col" : '{"name":"NULL"}' })
149+ self .assertTrue (result .has_restrictions )
150+
122151 def test_blank_filter_entries_are_skipped (self ):
123152 result = TableQueryAuthResult (["" , None ], None )
124153 self .assertFalse (result .filter )
@@ -334,38 +363,81 @@ def test_no_restriction_returns_plan_unchanged(self):
334363 from pypaimon .read .table_scan import TableScan
335364
336365 plain_plan = _FakePlan ([_FakeSplit ()], snapshot_id = 5 )
337- scan = _FakeScan (plain_plan )
366+ scan = _FakeScan (plain_plan , auth_result = None )
338367 result = TableScan .plan_for_write (scan )
339368 self .assertIs (result , plain_plan )
340369
341370 def test_row_filter_restriction_raises (self ):
342371 from pypaimon .read .table_scan import TableScan
343372
344373 auth = TableQueryAuthResult ([_simple_filter_json ()], None )
345- wrapped_plan = _FakePlan ([QueryAuthSplit ( _FakeSplit (), auth )], snapshot_id = 5 )
346- scan = _FakeScan (wrapped_plan )
374+ plan = _FakePlan ([_FakeSplit ()], snapshot_id = 5 )
375+ scan = _FakeScan (plan , auth_result = auth )
347376 with self .assertRaises (TableNoPermissionException ):
348377 TableScan .plan_for_write (scan )
349378
350379 def test_column_masking_restriction_raises (self ):
351380 from pypaimon .read .table_scan import TableScan
352381
353382 auth = TableQueryAuthResult (None , {"col" : '{"name":"NULL"}' })
354- wrapped_plan = _FakePlan ([QueryAuthSplit ( _FakeSplit (), auth )], snapshot_id = 5 )
355- scan = _FakeScan (wrapped_plan )
383+ plan = _FakePlan ([_FakeSplit ()], snapshot_id = 5 )
384+ scan = _FakeScan (plan , auth_result = auth )
356385 with self .assertRaises (TableNoPermissionException ):
357386 TableScan .plan_for_write (scan )
358387
359- def test_mixed_splits_any_restricted_raises (self ):
388+ def test_empty_table_with_auth_still_raises (self ):
360389 from pypaimon .read .table_scan import TableScan
361390
362391 auth = TableQueryAuthResult ([_simple_filter_json ()], None )
363- wrapped_plan = _FakePlan (
364- [_FakeSplit (), QueryAuthSplit (_FakeSplit (), auth )], snapshot_id = 5 )
365- scan = _FakeScan (wrapped_plan )
392+ empty_plan = _FakePlan ([], snapshot_id = 5 )
393+ scan = _FakeScan (empty_plan , auth_result = auth )
366394 with self .assertRaises (TableNoPermissionException ):
367395 TableScan .plan_for_write (scan )
368396
397+ def test_no_restrictions_allows_write (self ):
398+ from pypaimon .read .table_scan import TableScan
399+
400+ plan = _FakePlan ([_FakeSplit ()], snapshot_id = 5 )
401+ scan = _FakeScan (plan , auth_result = None )
402+ result = TableScan .plan_for_write (scan )
403+ self .assertIs (result , plan )
404+
405+
406+ class TestResolveAuthResult (unittest .TestCase ):
407+
408+ def test_none_fn_returns_none (self ):
409+ from pypaimon .read .query_auth_split import resolve_auth_result
410+ self .assertIsNone (resolve_auth_result (None , None ))
411+
412+ def test_no_restrictions_returns_none (self ):
413+ from pypaimon .read .query_auth_split import resolve_auth_result
414+ fn = lambda select : TableQueryAuthResult (None , None )
415+ self .assertIsNone (resolve_auth_result (fn , None ))
416+
417+ def test_empty_filter_returns_none (self ):
418+ from pypaimon .read .query_auth_split import resolve_auth_result
419+ fn = lambda select : TableQueryAuthResult ([], {})
420+ self .assertIsNone (resolve_auth_result (fn , None ))
421+
422+ def test_blank_filter_stripped_returns_none (self ):
423+ from pypaimon .read .query_auth_split import resolve_auth_result
424+ fn = lambda select : TableQueryAuthResult (["" , None ], None )
425+ self .assertIsNone (resolve_auth_result (fn , None ))
426+
427+ def test_with_filter_returns_result (self ):
428+ from pypaimon .read .query_auth_split import resolve_auth_result
429+ fn = lambda select : TableQueryAuthResult ([_simple_filter_json ()], None )
430+ result = resolve_auth_result (fn , None )
431+ self .assertIsNotNone (result )
432+ self .assertTrue (result .has_restrictions )
433+
434+ def test_with_masking_returns_result (self ):
435+ from pypaimon .read .query_auth_split import resolve_auth_result
436+ fn = lambda select : TableQueryAuthResult (None , {"col" : '{"name":"NULL"}' })
437+ result = resolve_auth_result (fn , None )
438+ self .assertIsNotNone (result )
439+ self .assertTrue (result .has_restrictions )
440+
369441
370442class TestCoreOptionsQueryAuth (unittest .TestCase ):
371443
0 commit comments