///|
fn classify_index_constraint(words : ArrayView[String]) -> Command {
let mut i = 0
let primary_key = match words.get(i) {
Some("UNIQUE") => {
i += 1
false
}
Some("PRIMARY") if words.get(i + 1) == Some("KEY") => {
i += 2
true
}
_ => return Unsupported
}
if words.get(i) != Some("USING") ||
words.get(i + 1) != Some("INDEX") ||
i + 2 >= words.length() ||
!index_identifier(words[i + 2]) {
return Unsupported
}
match constraint_timing(words[i + 3:]) {
Some(deferrable) => AddIndexConstraint(primary_key~, deferrable~)
None => Unsupported
}
}
///|
fn index_constraint_findings(
primary_key : Bool,
deferrable : Bool,
span : Span,
diagnostics : Array[Diagnostic],
) -> Unit {
diagnostics.push(
finding(
"ML190",
Warning,
span,
"Attaching an index as a constraint requires ACCESS EXCLUSIVE on the table",
"Concurrent index creation does not remove the final table-lock requirement. Budget acquisition waits and hold the transaction briefly; lock_timeout is not a total-operation time budget.",
),
)
diagnostics.push(
finding(
"ML191",
Warning,
span,
"Index-backed constraints require catalog checks and take ownership of the index",
"Verify an eligible existing UNIQUE b-tree index with default ordering, no expressions or predicate, and a non-partitioned target. A named constraint renames the index; dropping the constraint also drops its owned index. Existence, validity, ownership and name collisions are not inferred.",
),
)
if primary_key {
diagnostics.push(
finding(
"ML192",
Warning,
span,
"PRIMARY KEY attachment can require NOT NULL checks and table scans",
"If indexed columns are not already marked NOT NULL, PostgreSQL attempts SET NOT NULL. Check existing nulls and scan-elision prerequisites before scheduling the ACCESS EXCLUSIVE phase; index uniqueness alone does not establish nullability.",
),
)
}
if deferrable {
diagnostics.push(
finding(
"ML193",
Warning,
span,
"DEFERRABLE changes when the attached constraint can be checked",
"Review INITIALLY IMMEDIATE/DEFERRED behavior and downstream expectations. This review does not model SET CONSTRAINTS or prove that a transaction's final data satisfies the constraint.",
),
)
}
}