Summary
PriorityQueue fails to open against an existing database because initPriorityColumn unconditionally runs ALTER TABLE ... ADD COLUMN priority, producing duplicate column name: priority on the second open.
Root cause
priority_queue.go:36-56 checks for the column with:
var name string
err := pq.client.QueryRow(fmt.Sprintf("PRAGMA table_info(%s)", quoteIdent(pq.tableName))).
Scan(nil, &name, nil, nil, nil, nil)
if err != nil || name != "priority" {
// ALTER TABLE ... ADD COLUMN priority ...
}
PRAGMA table_info returns one row per column. QueryRow reads only the first row (the id column), so name is always "id" and the guard is always true. Every open runs ADD COLUMN, which has no IF NOT EXISTS in SQLite, so the second open of a persisted DB errors and NewPriorityQueue returns:
failed to initialize priority column: duplicate column name: priority
Reproduction
m1 := sqliteq.New("pq.db")
m1.NewPriorityQueue("pq") // ok
m1.Close()
m2 := sqliteq.New("pq.db")
_, err := m2.NewPriorityQueue("pq") // err: duplicate column name: priority
Confirmed via test — priority queues cannot survive a process restart, defeating the persistence guarantee.
Impact
High. Any priority queue on a persisted DB is broken after the first run.
Possible fix
Scan all pragma rows and only alter when the column is truly absent:
func (pq *PriorityQueue) initPriorityColumn() error {
rows, err := pq.client.Query(fmt.Sprintf("PRAGMA table_info(%s)", quoteIdent(pq.tableName)))
if err != nil {
return err
}
defer rows.Close()
hasPriority := false
for rows.Next() {
var cid int
var name, ctype string
var notnull, pk int
var dflt sql.NullString
if err := rows.Scan(&cid, &name, &ctype, ¬null, &dflt, &pk); err != nil {
return err
}
if name == "priority" {
hasPriority = true
}
}
if err := rows.Err(); err != nil {
return err
}
if hasPriority {
return nil
}
// ADD COLUMN + CREATE INDEX (index already uses IF NOT EXISTS)
...
}
Summary
PriorityQueuefails to open against an existing database becauseinitPriorityColumnunconditionally runsALTER TABLE ... ADD COLUMN priority, producingduplicate column name: priorityon the second open.Root cause
priority_queue.go:36-56checks for the column with:PRAGMA table_inforeturns one row per column.QueryRowreads only the first row (theidcolumn), sonameis always"id"and the guard is always true. Every open runsADD COLUMN, which has noIF NOT EXISTSin SQLite, so the second open of a persisted DB errors andNewPriorityQueuereturns:Reproduction
Confirmed via test — priority queues cannot survive a process restart, defeating the persistence guarantee.
Impact
High. Any priority queue on a persisted DB is broken after the first run.
Possible fix
Scan all pragma rows and only alter when the column is truly absent: