Repository navigation
feat(auth): apply query-auth masks to non-BLOB columns - #1077
Conversation
a8a2091 to
3c1d459
Compare
3c1d459 to
4bd05f2
Compare
JingsongLi
left a comment
There was a problem hiding this comment.
Found one compatibility regression; the verified reproduction and suggested fix are inline.
| if partition_keys.is_empty() || table.schema().core_options().query_auth_enabled() { | ||
| (None, filter.split_and()) |
There was a problem hiding this comment.
[P2] Preserve partition-only filters when enabling chunk shuffle
With query-auth.enabled=true, this branch leaves even a pure partition predicate in data_predicates. TableScan::with_chunk_shuffle() still rejects any nonempty data_predicates, so a REST-loaded append table with an unrestricted grant now fails on builder.with_filter(partition_predicate).new_scan().with_chunk_shuffle(7, 2) with chunk_shuffle only supports partition predicates, before authorization can restore partition pruning. Python's with_chunk_shuffle is affected as well.
I verified that the same test using real Parquet files and a mock REST catalog passes on base d8205a0 (including planning and reading) and fails on head 4bd05f26. Please check shuffle compatibility after authorization has separated the safe partition predicates, or distinguish partition-only residuals from actual data predicates, so unmasked partition filters remain supported.
There was a problem hiding this comment.
Fixed and added regression tests for append and data-evolution tables.
5e6faa4 to
f9769f7
Compare
Purpose
#513 applies the server's row filter but still refuses users with column masks. This adds masking for non-BLOB columns. BLOB column masks remain explicitly unsupported and will be handled separately.
Brief change log
The grant also carries the masks, parsed as Java does: a mask on an unknown column, one that reads another masked column, or one that changes the column type or can make a NOT NULL column null fails closed, and a mask on a system column is inert. A
CASTmask is accepted only where Arrow and Java convert alike, including exact signed integer widening into a compatible target column.Planning excludes masked-column predicates from file, bucket and partition pruning. Those predicates are evaluated after masking, including partition-key predicates, and limits are not pushed past them. DataFusion treats query-auth filters as inexact at the provider boundary.
to_arrowmasks after filtering on stored values, applies the caller's predicates to masked values, and projects back.Chunk shuffle continues to accept unmasked partition filters on authorized tables. Predicates on masked columns are refused after the catalog grant is known.
Tables containing BLOB columns can use masks on their ordinary columns. Safe ordinary predicates run after authorization and before masking; existing BLOB payload resolution stays after row authorization.
String masks borrow inputs and build concatenated output directly in Arrow buffers. ASCII case conversion operates on the column buffer; Unicode conversion preserves context-sensitive casing.
Tests
Unit tests cover mask transforms, refused casts, integer bounds, nulls, Unicode and sliced arrays. Mock-server tests cover masked predicates, bucket and partition keys, merged primary-key rows, a row filter and mask sharing a column, and source-column retention across overlapping partial files. Chunk-shuffle tests cover append and data-evolution tables, both planning APIs, and unrestricted and restricted grants. BLOB masks are rejected even when the masked column is not projected. DataFusion queries verify that
WHEREand aggregates see masked values.API and Format
No API or format change.
Documentation
The Query Authorization section in
docs/src/sql.mdcovers masks.