[bug] search misses IGA/Metro items stored with non-canonical postal code (H0H 0H0 vs H0H0H0) #1
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Bug:
circulaires searchsilently misses IGA/Metro items stored with non-canonical postal codeSummary
A subset of IGA and Metro flyers in the cache are stored with
postal_code = 'H0H 0H0'(with a space) instead of the canonicalH0H0H0. BecausebuildCurrentFlyersSQLdoes an exact-matchWHERE postal_code = ?, those flyers (and all their items) are invisible to thesearchcommand. Direct SQL queries against the same DB see the items, confirming the data is there.This makes the search command appear to return almost nothing for IGA and Metro, even though the cache holds hundreds of priced items for those merchants.
Reproduction (H0H 0H0, today 2026-06-06)
After a fresh
circulaires fetch, the DB holds:But
circulaires search "" --merchants IGA,Metro,Maxi --min-price 1returns only 19 matches — the IGA items that happen to come from the smalldisplay_type=5"Irrésistible" banner flyer (which is the only IGA/Metro entry stored with the canonical postal code), plus 1 Maxi item that doesn't have a meat keyword. Almost all of the 637 priced IGA+Metro items are missing.A
circulaires search "poulet" --merchants Metro --flatreturns 0 matches even though the DB containsPOULETS ENTIERS FRAIS EXCELDOR — 2,99 $and 11 other Metro chicken items.Root cause
internal/db/repo.go::buildCurrentFlyersSQLqueries:The parameter is the canonical postal (no space, from
config.PostalCode), but the DB has rows withpostal_code = 'H0H 0H0'(with a space). Lexicographic comparison misses them. TheV1.1commite939f45("Addsearchcommand for offline cache queries") shipped with this latent bug — older fetches stored the un-normalized form, and the search layer never normalized the comparison.Verified by hand with sqlite3 against the same DB:
So two flyers (IGA id=1, Metro id=3) are invisible to the search. The Maxi and Super C flyers were all stored with the canonical form and are unaffected.
Suggested fix (one of)
internal/db/repo.go::UpsertFlyer, run the incomingpostal_codethrough the samenormalizePostalCodehelper thatinternal/flipp/postal.goexposes, and store the canonical form. This is the right fix and prevents the next round of legacy data from accumulating.buildCurrentFlyersSQL, change the predicate toREPLACE(postal_code, ' ', '') = REPLACE(?, ' ', '')(orTRIM+ strip non-alnum). Smaller diff, doesn't fix the underlying dirty data.postal_codevalues to the canonical form, then add a CHECK constraint.I'd recommend (1) + (3) together. (1) is the actual fix; (3) cleans up the existing dirty rows so users with old caches get correct results immediately.
Workaround for affected users (until fixed)
The
circulaires searchcommand can't see these items. Direct SQL still works:Environment
circulairesV1.2 (commit30663be), main branch, 2026-06-06H0H 0H0searchis a primary user-facing command (V1.1 milestone), and the bug is silent (no error, just wrong results). Users with older caches that include non-canonical postal rows are affected.[bug] search misses IGA/Metro items stored with non-canonical postal code (J5V 1A5 vs J5V1A5)to [bug] search misses IGA/Metro items stored with non-canonical postal code (H0H 0H0 vs H0H0H0)