Put deleted_at in the event-tier indexes so SQLite uses them
check / check (push) Successful in 3m16s

GORM adds deleted_at IS NULL to these queries, and SQLite, which has no
table statistics here, preferred the deleted_at index to the new
single-column ones wherever a column is matched against several values
or compared with <. The event log's attempt load, retention's lookups
of expired events and their deliveries, and the queue-depth sampler
still read every live row. Each index now also covers deleted_at,
first in the events index because created_at is compared with <;
events keeps its created_at index for retention's final delete. A test
checks SQLite's plan for each statement as GORM builds it.

Model: opus-5-5
This commit is contained in:
2026-09-28 11:30:32 +00:00
parent 12e6c3bf3e
commit 49def467b1
5 changed files with 179 additions and 49 deletions
+12 -3
View File
@@ -1,5 +1,7 @@
package database
import "gorm.io/gorm"
// DeliveryStatus represents the status of a delivery
type DeliveryStatus string
@@ -29,12 +31,19 @@ func (s DeliveryStatus) Terminal() bool {
}
// Delivery represents a delivery attempt for an event to a target
//
//nolint:lll // a struct tag cannot wrap
type Delivery struct {
BaseModel
EventID string `gorm:"type:uuid;not null;index" json:"eventId"`
TargetID string `gorm:"type:uuid;not null" json:"targetId"`
Status DeliveryStatus `gorm:"not null;default:'pending';index" json:"status"`
EventID string `gorm:"type:uuid;not null;index:idx_deliveries_event_id,priority:1" json:"eventId"`
TargetID string `gorm:"type:uuid;not null" json:"targetId"`
Status DeliveryStatus `gorm:"not null;default:'pending';index:idx_deliveries_status,priority:1" json:"status"`
// DeletedAt repeats the BaseModel field only to be the second column
// of the event_id and status indexes, for the reason DeliveryResult
// gives.
DeletedAt gorm.DeletedAt `gorm:"index:idx_deliveries_event_id,priority:2;index:idx_deliveries_status,priority:2" json:"deletedAt,omitzero"`
// Relations
Event Event `json:"event,omitzero"`