Skip to content
Docs

Pivot queries (potential — not on the roadmap)

BifrostQL ships BifrostQL.Core.QueryModel.PivotSqlGenerator, a static helper that turns a PivotQueryConfig into parameterized cross-tab SQL. It supports SQL Server’s native PIVOT operator and a portable CASE WHEN fallback for every other dialect.

CapabilityState
PivotQueryConfig.Create validationshipped
SQL Server native PIVOT (... FOR ... IN (...))shipped, unit-tested
Engine-agnostic CASE WHEN cross-tabshipped, unit-tested
ISqlDialect.SupportsNativePivot dispatchshipped, unit-tested
PivotSqlGenerator.GeneratePivot(dialect, ...) entry pointshipped
GraphQL field that returns pivot resultsnot implemented
End-to-end tests against real DB enginesnot implemented

No _pivot(...) field is emitted by the schema generator. No resolver consumes the helper’s ParameterizedSql. No ReaderEnum branch shapes pivot rows into a GraphQL response. The two-pass flow (GenerateDistinctValuesSql to enumerate pivot columns, then GeneratePivot to project) has no orchestrator.

That gap is deliberate. Pivot is a wide, low-cardinality shape that doesn’t fit the per-row resolver pattern BifrostQL was built around, and the design questions — how does pivot interact with paging, filters, joins, security policies, the aggregate-value type — haven’t been answered.

Three viable paths in priority order:

  1. Use _agg(value: { joinTable: { column: ... } } operation: ...) — for the common “group X by Y and aggregate Z” case, the aggregate path already returns one row per group through a normal GraphQL resolver. See docs/research/agg-dialect-survey.md.
  2. Call PivotSqlGenerator from a custom resolver in your host — the helper is public; a module or middleware can build a ParameterizedSql and execute it against the IDbConnFactory. The output shape and contract are entirely yours.
  3. Pivot in the client — for low-cardinality pivots, pulling the long-form aggregate and pivoting in TypeScript/SQL keeps the GraphQL contract narrow.

If you want to drive pivot onto the roadmap

Section titled “If you want to drive pivot onto the roadmap”

The unblock work is captured in docs/research/pivot-dialect-survey.md. Open an issue with a concrete use case before opening a PR — the surface design needs to be settled first.