feat(spring-data): hierarchy operators (overlaps / ancestorOf / descendentOf)#249
Open
alexolivier wants to merge 1 commit into
Open
feat(spring-data): hierarchy operators (overlaps / ancestorOf / descendentOf)#249alexolivier wants to merge 1 commit into
alexolivier wants to merge 1 commit into
Conversation
alexolivier
added a commit
that referenced
this pull request
Jun 24, 2026
…ent MySQL LIKE escaping - Add a StatementInspector-backed integration test that runs the three-hop deep-nested-category-label policy (categories -> subCategories -> labels) and asserts the generated SQL has three nested correlated EXISTS subqueries and no cross join — a cartesian join would return rows but pair unrelated children. - README: document the MySQL/MariaDB LIKE backslash double-escaping gotcha and the NO_BACKSLASH_ESCAPES / OperatorFunction-override workarounds. Addresses the remaining #220 follow-ups (hierarchy operators handled in #249). Signed-off-by: Alex Olivier <alex@alexolivier.me>
7 tasks
…escendentOf) Port the hierarchy operators from the Prisma adapter. A hierarchy(...) operand resolves to a constant delimited path, a whole-column field, or a list(...) of constant/field segments; the operators translate to: - ancestorOf(A, B): A is a strict prefix of B - descendentOf(A, B): B is a strict prefix of A - overlaps(A, B): one is a prefix of the other mapped onto cb.equal / path.in(strictPrefixes) / LIKE 'prefix%' (with the same literal escaping as the string operators), collapsing constant-only cases to an always-true/false predicate. Tests: 11 unit tests (all type combinations + error contracts) and 3 integration tests against a real Cerbos PDP exercising the hierarchy-overlaps/-ancestor-of/ -descendent-of policy actions. Adds a 'scope' column to the test ResourceEntity. 186 tests pass (incl. 98 integration tests against a real PDP). Signed-off-by: Alex Olivier <alex@alexolivier.me>
fea6016 to
70e8d7f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #220 (base:
spring-data). Adds the hierarchy operators that were listed as a follow-up in #220, bringing the Spring Data adapter to parity with the Prisma adapter.What
A Cerbos hierarchy is a delimited path (e.g.
a:b:c). Each side of a hierarchy operator is wrapped in ahierarchy(...)expression resolving to one of:list(...)of segments, each a constant or a field.ancestorOf(A, B)B LIKE 'A.%'; field→constant:A IN (strictPrefixes(B))descendentOf(A, B)ancestorOfwith operands swappedoverlaps(A, B)field IN (prefixes) OR field = raw OR field LIKE 'raw.%'Constant-only operands collapse to an always-true (
cb.conjunction()) or always-false (cb.disjunction()) predicate. LIKE prefixes reuse the same_/%/\escaping as the string operators. Mirrors the Prisma adapter's algorithm so behaviour is consistent across adapters.Tests
SpringDataQueryPlanAdapterTest.HierarchyOperators) covering every constant/field/segmented combination, the always-true/false collapses, strict-prefixIN, and the error contracts (non-hierarchy operands, two field-reference hierarchies, unsatisfiable constants).SpringDataIntegrationTest.HierarchyOperators) against a real Cerbos PDP exercising thehierarchy-overlaps/hierarchy-ancestor-of/hierarchy-descendent-ofpolicy actions in/policies/resource.yaml— this validates that the operator names,hierarchy(...)/list(...)shapes,R.id, and principal-attribute substitution all match what the planner emits.scopecolumn to the testResourceEntityfor the ancestor/descendent fixtures.186 tests pass (incl. 98 integration tests against a real PDP), verified locally via the gradle Docker image with Testcontainers.
Once #220 merges, this can be retargeted to
main.