relationExistsQuery<TParent, TChild> function

MssqlQuery relationExistsQuery<TParent, TChild>(
  1. MssqlRelation<TParent, TChild> relation, {
  2. required MssqlTableBinding<TParent> parent,
  3. required MssqlSession session,
  4. required MssqlDialect dialect,
  5. MssqlExpression? projection,
})

Builds a correlated EXISTS / NOT EXISTS subquery for relation.

The parent table is not joined, so a matching child cannot multiply parent rows. The same scopes, filters and through/morph shape the include loader uses are applied here, so whereHas and include of one handle mean the same set of children.

Implementation

MssqlQuery relationExistsQuery<TParent, TChild>(
  MssqlRelation<TParent, TChild> relation, {
  required MssqlTableBinding<TParent> parent,
  required MssqlSession session,
  required MssqlDialect dialect,
  MssqlExpression? projection,
}) {
  final selected = projection ?? raw('1');
  if (relation.through != null) {
    return _throughExists(relation, parent, session, dialect, selected);
  }
  if (relation.kind == MssqlRelationKind.morphTo) {
    throw StateError(
      'whereHas("${relation.name}") cannot use morphTo: the counterpart '
      'table depends on a per-row discriminator, so a single EXISTS has '
      'no table to name. Filter the type column yourself, then whereHas '
      'each concrete target.',
    );
  }
  final child = relation.targetBinding;
  final context = MssqlQueryContext<TChild>(
    session: session,
    binding: child,
    dialect: dialect,
  );
  var query = context.scopedQuery(relation.scope).select(<MssqlExpression>[
    selected,
  ]);
  query = query.where(_correlate(parent, relation));
  final extra = _extra(relation);
  if (extra != null) query = query.where(extra);
  return _withNested(query, relation, session, dialect);
}