Cross-language Query Contract
TeaQL generates idiomatic Q APIs for Java, Rust, TypeScript, Swift, Python, C#/.NET, and Go from one model. Method casing and asynchronous syntax differ, but all seven native runtimes support the same shared query profile described on this page. For a task-oriented introduction with aggregation and Facet examples in every language, start at Query, Mutation, Analytics, and Facets.
The current design and execution rows are published in Cross-language Conformance Status. That matrix is the changing status record; this page is the stable capability map.
What “supported” means
Keep three evidence dimensions separate:
- Native generated API: the language exposes the typed method family.
- Portable TFP profile: the operation is represented in the governed wire contract.
- Provider execution: a named runtime/provider/database combination retained executable evidence.
The complete profile below applies to the seven native generated APIs. TFP is a separate transport profile and is still partial for some relations, analytics, facets, and advanced pagination. A source method alone also does not prove every provider/database combination; use the dated provider matrix for that narrower claim.
Complete native query profile
| Area | Shared capability in Java, Rust, TypeScript, Swift, Python, .NET, and Go | Conformance rows |
|---|---|---|
| Scalar predicates | Equality/inequality, set and negative-set membership, ordered comparison, inclusive range, contains, starts/ends-with and negative forms, known/unknown, nullable Boolean, and provider-aware phonetic matching | QRY-P01–QRY-P09 |
| Relation predicates | Forward relation matching, modeled-constant predicates, and reverse relation matching | QRY-R01–QRY-R03 |
| Projection and ordering | Typed projection, deterministic multi-field ordering, and loaded/null/not-loaded preservation | QRY-S01 |
| Grouped analytics | Group by plus portable COUNT, SUM, AVG, MIN, and MAX aliases | QRY-S02 |
| Relation analytics | Relation counts and portable statistics attached to parent results | QRY-S03 |
| Deep relation embedding | Relation predicates can nest through typed child Requests; relation selection also accepts a typed child Request with its own filter, projection, order, and bounded limit | QRY-R01–QRY-R03 |
| Per-parent Top-N | Exact database-side partition/window selection for bounded children of each parent | QRY-X01 |
| Pagination | Ordinary page, continuous cursor pagination, and retained ID-set pagination | QRY-X02, QRY-X03 |
| Facets | Typed relation Facet API, include-all versus matched-only semantics, and facet results in the returned carrier | QRY-F01–QRY-F03 |
Some runtimes or providers expose additional aggregate functions. The portable
seven-runtime promise is deliberately limited to COUNT, SUM, AVG, MIN,
and MAX; extended variance, deviation, or bitwise functions must be qualified
against the selected runtime/provider.
Deep relation composition
“Deep embedding” does not mean one unbounded join or an implicit fetch of the whole object graph. It covers two explicit operations. Relation predicates can nest recursively because a typed child Request may itself contain another forward or reverse relation predicate. Relation-selection methods also accept a typed child Request, allowing each loaded level to carry its own filter, projection, order, and bound:
parent request
-> selected child request (filter + order + limit)
-> nested relation predicate or an explicitly loaded next level
Forward and reverse relations retain their modeled direction and cardinality.
Do not infer universal arbitrary-depth eager hydration in one serialized plan:
for example, the audited Swift RelationQueryPlan deliberately snapshots one
loaded relation level at a time. Deeper loaded graphs must follow the generated,
bounded composition path for that runtime version.
Per-parent limits use the runtime's exact Top-N plan instead of loading every
child and slicing in application memory. Context policy, depth ceilings, row
limits, and provider limits still apply at every level. A loaded null, an empty
loaded relation, and a relation that was not selected remain different states.
Analytics and facets
Analytics are part of the Request model rather than post-processing helpers:
- projection and grouping use generated fields;
- aggregate aliases travel with the typed result metadata;
- relation counts and statistics can be attached to parent rows;
- facets can include only matched values or the complete allowed relation domain;
- page rows, totals, aggregates, and facets must use the same normalized filter when they are intended to describe one result set.
SmartList is the shared result carrier. It preserves typed entities and may
also carry exact or qualified counts, aggregation values, facet results, and
pagination state. Providers must fail or expose a documented fallback when
they cannot preserve a requested semantic; they must not silently substitute a
different query.
Pagination profiles
| Profile | Primary use | Retained state |
|---|---|---|
| Ordinary page | Familiar bounded page navigation | Offset/page request and optional count |
| Continuous page | Sequential next/previous navigation | Boundary cursor |
| ID Set Pagination | Exact count and arbitrary jumps for an eligible bounded result | Complete ordered ID sequence |
ID Set Pagination is opt-in. It applies normal tenant, policy, predicate, join, and order rules before constructing the ID set. Overflow, unsupported shapes, or store failure use a visible fallback and must not change query results.
Intent and execution boundary
Every executable query must carry a non-empty operation comment and business
purpose before its execution terminal. They may appear in either order and do
not have to be adjacent; filters, projections, sorting, pagination, and relation
selection may be composed between them. The generated executable-state type and
runtime validation remain the authority for the selected language version.
Execution receives trusted context. Tenant, actor, permission, purpose policy,
provider selection, and safety ceilings come from that context rather than from
dynamic client input.
Dynamic input boundary
Dynamic JSON or protocol input is translated through an explicit entity, field, operator, relation, aggregate, and limit allowlist. Unknown or ambiguous input fails closed before generated Request construction. Trusted tenant, actor, permission, purpose policy, and execution ceilings remain server-owned.
Source audit
The shared profile was rechecked on 2026-09-28 after updating the runtime repositories. These are implementation anchors, not substitutes for provider execution evidence:
| Runtime | Audited revision | Representative source |
|---|---|---|
| Java | 43c135ab40a8 | BaseRequest.java |
| Rust | 54e9fb271bbf | query.rs |
| TypeScript | e0335734efb8 | ast.ts |
| Swift | f775c9a6c944 | Query.swift |
| Python | 8d221e924590 | query.py |
| C#/.NET | 65968cb6615d | SelectQuery.cs |
| Go | 241dc9670f94 | query.go |
The governing cross-language matrix is pinned to conformance revision
27f0999f8854.
Use each language guide for native spelling and the
provider matrix for dated execution
scope.