ensureStableOrder method
S
ensureStableOrder()
page / chunk / cursorPage: used when the caller gave none, and as a
tie-breaker when they gave some.
A keyless table cannot invent an order — the generic builder will not guess a unique key it does not have.
Implementation
S ensureStableOrder() {
if (!binding.hasPrimaryKey) {
if (state.orderBy.isEmpty) {
throw StateError(
'${binding.qualifiedName} has no primary key, so a page needs an '
'explicit unique orderBy. The generic builder will not guess one.',
);
}
return _self;
}
if (state.orderBy.isEmpty) {
return rebuild(
state.withOrderBy(<MssqlOrder>[
for (final name in binding.primaryKey) Col(name).asc(),
]),
);
}
// Append only the key columns the caller's ordering does not already
// name. `orderBy((o) => [o.id.desc()])` must not become
// `ORDER BY [Id] DESC, [Id] ASC`: the second term is unreachable, so the
// ordering would claim a tie-break it does not have, and cursorPage
// builds its keyset predicate from this list term by term — the same
// column twice with opposite directions gives `[Id] < @a AND … [Id] >
// @a`, which matches no row at all.
return rebuild(
state.withOrderBy(
mssqlWithKeyTieBreak(state.orderBy, binding.primaryKey),
),
);
}