Found while working #11161 (which repaired this method's error contract and its always-invalid PG query, deliberately without touching its per-dialect semantics). #11161 remains open on its own subject; this issue is not addressed by that PR.
What
SqlDriver.introspectUniqueConstraints returns a flat string[] of column names, which introspectSchema folds into a per-column isUnique flag. The three arms disagree about what that list means:
So for a table with UNIQUE (a, b): SQLite reports neither column as unique; PG and MySQL report both a and b with isUnique: true — which reads as "a alone is unique, and b alone is unique", a claim the constraint does not make.
Why it matters
Same consumer argument as the rest of the introspection family: the same table introspected through different dialects yields different isUnique flags, so cross-dialect snapshot comparison sees differences that are not differences, and a federated-object draft (ADR-0015) inherits whichever dialect's reading it was drafted from. A per-column flag is also structurally unable to represent a composite constraint — arguably the honest options are either the SQLite arm's "single-column uniques only" everywhere (making the flag truthful) or a real composite representation on the table shape (a uniqueConstraints: string[][]-like surface), which is a spec-contract question, not a driver patch.
Decision needed
Which meaning should isUnique carry? This is a contract question (the spec's IntrospectedColumn.isUnique semantics) and should be ruled once for all three dialects rather than patched per arm. Related: #11122 tracks other introspectSchema spec-contract divergences.
Found while working #11161 (which repaired this method's error contract and its always-invalid PG query, deliberately without touching its per-dialect semantics). #11161 remains open on its own subject; this issue is not addressed by that PR.
What
SqlDriver.introspectUniqueConstraintsreturns a flatstring[]of column names, whichintrospectSchemafolds into a per-columnisUniqueflag. The three arms disagree about what that list means:PRAGMA index_listand pushes a column only when the unique index has exactly one column (if (info.length === 1)) — members of composite unique indexes are excluded, deliberately or not.catch {}turned every call into[]):constraint_column_usagereturns every column of every UNIQUE constraint, composite included.KEY_COLUMN_USAGEforCONSTRAINT_TYPE = 'UNIQUE'— also every member of composite constraints.So for a table with
UNIQUE (a, b): SQLite reports neither column as unique; PG and MySQL report bothaandbwithisUnique: true— which reads as "a alone is unique, and b alone is unique", a claim the constraint does not make.Why it matters
Same consumer argument as the rest of the introspection family: the same table introspected through different dialects yields different
isUniqueflags, so cross-dialect snapshot comparison sees differences that are not differences, and a federated-object draft (ADR-0015) inherits whichever dialect's reading it was drafted from. A per-column flag is also structurally unable to represent a composite constraint — arguably the honest options are either the SQLite arm's "single-column uniques only" everywhere (making the flag truthful) or a real composite representation on the table shape (auniqueConstraints: string[][]-like surface), which is a spec-contract question, not a driver patch.Decision needed
Which meaning should
isUniquecarry? This is a contract question (the spec'sIntrospectedColumn.isUniquesemantics) and should be ruled once for all three dialects rather than patched per arm. Related: #11122 tracks otherintrospectSchemaspec-contract divergences.