Fix too many SQL variables in DeleteItem for large batch deletes

The FixIncorrectOwnerIdRelationships migration deletes all duplicate
items in a single DeleteItemsUnsafeFast -> DeleteItem(ids) call. Inside
DeleteItem, the owned-extras lookup used a raw HashSet.Contains, which EF
inlines as one SQL variable per id and overflows SQLite's variable limit
on large libraries. Use WhereOneOrMany so the id set is bound as a single
json_each parameter, like the rest of the method, making bulk deletes
work for unlimited library sizes.
This commit is contained in:
Joshua M. Boniface
2026-06-21 22:49:46 -04:00
parent 4e80648fd3
commit 069eb40ebf

View File

@@ -65,8 +65,13 @@ public class ItemPersistenceService : IItemPersistenceService
descendantIds.Add(id);
}
// Use WhereOneOrMany instead of a raw HashSet.Contains so large id sets are bound as a
// single parameter (json_each) rather than one SQL variable per id, which would otherwise
// overflow SQLite's variable limit when deleting many items at once (e.g. migrations).
var ownerIds = descendantIds.ToArray();
var extraIds = context.BaseItems
.Where(e => e.OwnerId.HasValue && descendantIds.Contains(e.OwnerId.Value))
.Where(e => e.OwnerId.HasValue)
.WhereOneOrMany(ownerIds, e => e.OwnerId!.Value)
.Select(e => e.Id)
.ToArray();