feat(compiler): carry grouped predicates through shared passes
What does this MR do and why?
Grouped predicates need to keep their meaning through validation, planning, and SQL generation. This adds shared AND/NOT expression handling, including scope checks and null-aware membership.
Stack
This targets main. The GQL frontend follows in !2743 (closed). The empty-list prerequisites in !2730 (merged) are merged.
Relates to #1311 and #1258.
Testing
352 compiler tests, 226 local tests, and the full ClickHouse data-correctness suite passed after simplifying filter handling. Workspace Clippy and formatting passed.
Performance Analysis
Single-node groups narrow scans and retain latest-row rechecks. Cross-alias groups run after the required joins. Runtime performance has not been benchmarked.
Agent context: shared compiler contract
Ordinary filters stay in node and relationship maps. Shared iterators validate and authorize both maps and expression leaves. The shared tree keeps AND and NOT intact through each compiler pass. Property comparisons use those same leaves instead of a separate join-predicate list. Ordinary filters keep their existing scope and scan paths. Grouped predicates and cross-node comparisons use expressions. Enum coercion uses the same helper for both forms.
Plain and grouped edge filters use the existing table_column_type lookup, derived from logical field declarations.
Field spelling does not grant or deny access. There is no grouped-only rejection of names starting with _.
The catalogs already keep declared field types separate from storage columns. This reuses those maps.
Plain and native grouped tests accept an explicitly declared _declared_field and reject a storage-only field.
The declared-field scenarios check compilation because their ontology overlay does not alter the database schema.
Relationship filters with rhs_column are rejected, including native input that could otherwise read admin-only node fields.
Depth inspection is iterative. Existing compiler tests check depth and leaf limits.
Native security and rejection scenarios use expect.predicates in the data-correctness suite.
Plan-shape fixtures cover accepted plans. The JSON frontend does not expose the native expression tree.
The query runner limits its client-safe error assertion to native-predicate cases, so expected internal security failures remain testable.
GQL still reports undefined comparison variables at the frontend source span.
The query DSL pin is 12.1.15. Broader review of legacy comparison restrictions remains open. Changed design documents pass Vale and Markdown lint; repository-wide docs lint reports 14 unrelated Vale errors.