You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(H001): add decision support fields and recommendations for invalid indexes
Extends H001 check with data to support the decision flowchart for invalid
index remediation:
- Add SQL fields: is_unique_constraint, is_primary_key, table_row_estimate,
has_valid_covering_index
- Add recommendation object with action (drop/recreate/uncertain), reason, and SQL
- Decision logic:
1. If valid index on same columns exists → DROP (duplicate)
2. If backs UNIQUE/PK constraint → REINDEX INDEX CONCURRENTLY
3. If table < 10K rows → DROP INDEX CONCURRENTLY and monitor
4. Otherwise → uncertain (needs RCA to check query patterns)
- All SQL commands use CONCURRENTLY to avoid blocking
- Updates both express (TypeScript CLI) and full (Python reporter) paths
reason: `This index backs a ${constraintType} constraint and must be recreated to restore constraint enforcement.`,
623
+
sql: `REINDEX INDEX CONCURRENTLY ${qualifiedName};`,
624
+
};
625
+
}
626
+
627
+
// 3. Small table (< 10K rows) → DROP and monitor
628
+
if(tableRowEstimate<10000){
629
+
return{
630
+
action: "drop",
631
+
reason: `The table has only ~${tableRowEstimate.toLocaleString()} rows. For small tables, it's safe to drop the invalid index and monitor query performance. If needed, recreate with REINDEX INDEX CONCURRENTLY.`,
632
+
sql: `DROP INDEX CONCURRENTLY ${qualifiedName};`,
633
+
};
634
+
}
635
+
636
+
// 4. Large table, no constraint → UNCERTAIN (need to investigate query patterns)
637
+
return{
638
+
action: "uncertain",
639
+
reason: `The table has ~${tableRowEstimate.toLocaleString()} rows. Additional investigation is needed to determine if queries filter on the indexed column(s). If queries depend on this index, use REINDEX INDEX CONCURRENTLY to recreate it. Otherwise, DROP INDEX CONCURRENTLY and monitor.`,
640
+
};
641
+
}
642
+
565
643
/**
566
644
* Get invalid indexes from the database (H001).
567
645
* Invalid indexes are indexes that failed to build (e.g., due to CONCURRENTLY failure).
568
646
*
569
647
* @param client - Connected PostgreSQL client
570
648
* @param pgMajorVersion - PostgreSQL major version (default: 16)
571
-
* @returns Array of invalid index entries with size and FK support info
649
+
* @returns Array of invalid index entries with size, FK support info, and remediation recommendation
"reason": f"This index backs a {constraint_type} constraint and must be recreated to restore constraint enforcement.",
633
+
"sql": f"REINDEX INDEX CONCURRENTLY {qualified_name};"
634
+
}
635
+
636
+
# 3. Small table (< 10K rows) → DROP and monitor
637
+
iftable_row_estimate<10000:
638
+
return {
639
+
"action": "drop",
640
+
"reason": f"The table has only ~{table_row_estimate:,} rows. For small tables, it's safe to drop the invalid index and monitor query performance. If needed, recreate with REINDEX INDEX CONCURRENTLY.",
641
+
"sql": f"DROP INDEX CONCURRENTLY {qualified_name};"
642
+
}
643
+
644
+
# 4. Large table, no constraint → UNCERTAIN (need to investigate query patterns)
645
+
return {
646
+
"action": "uncertain",
647
+
"reason": f"The table has ~{table_row_estimate:,} rows. Additional investigation is needed to determine if queries filter on the indexed column(s). If queries depend on this index, use REINDEX INDEX CONCURRENTLY to recreate it. Otherwise, DROP INDEX CONCURRENTLY and monitor."
0 commit comments