Skip to content

ADR-0024: Bounded scalar Contains with explicit equality semantics

Status: implemented; targeted unit/live acceptance passed locally, hosted gate tracked separately.

Support Enumerable/normalized Queryable membership over materialized arrays and exact List with one Cypher list parameter. Add a CypherIn syntax node and an explicit collection parameter binding flag. Snapshots apply existing built-in store conversion to each item before any driver session opens. Reject arbitrary enumerable/custom comparer semantics and more than 1,024 elements; do not add client predicate fallback or hidden chunking.

Cypher IN alone has three-valued null behavior. Combine a coalesced membership result with an explicit null-element check so missing graph properties match CLR collection nulls and negation remains correct. Restrict item types to string/int/long/bool/Guid/enum without explicit converters. Floating-point special values and arbitrary converted equality need separate semantics and are not inferred from successful storage conversion.

Queryable.Contains over a direct scalar node projection lowers to existing null-safe equality and server Any aggregation. Preserve the existing aggregate rejection for relationship identity/cardinality roots, and reject entity membership, pagination/Include compositions and correlated subqueries. The accepted subset is documented in CONTAINS_QUERIES.md.

EF 10.0.12 normalizes ICollection.Contains through Queryable.AsQueryable, which the predicate translator unwraps only around an otherwise supported parameter/constant. It does not execute a subquery. The existing EF query cache owns plan reuse; a live compilation-event assertion proves changing values/length reuses one async compilation. No new EF service or standalone query provider is introduced.

The first comparer-rejection test accidentally selected C# 14's span overload, which fails in EF parameter interpretation for a non-null comparer. The test now explicitly calls Enumerable.Contains to verify the provider rejection path. The separate earlier EF limitation is documented instead of claiming GraphBridge's exception controls every compiler-selected overload.