Reject non-standard truthy numeric expressions in filters and document the parser as a supported subset of standard CEL syntax.
- remove legacy filter rewrites
- support standard equality in tag exists predicates
- add regression coverage for accepted and rejected expressions
Add migration scripts for existing instances without a storage setting
to explicitly preserve DATABASE as their storage type, ensuring backward
compatibility. Change the default for new installations to LOCAL to
improve out-of-the-box performance.
Fixes two bugs reported in #5603:
1. store/attachment.go: ignore os.ErrNotExist when removing a local
attachment file so that a missing file on disk (broken state from
failed uploads) no longer blocks deletion of the DB record, allowing
memos referencing corrupt attachments to be deleted normally.
2. memo_attachment_service.go: add nil guard on GetAttachment result
before dereferencing it in SetMemoAttachments, preventing a nil
pointer panic when an attachment UID no longer exists in the DB.
The PostgreSQL implementation returns 'PAT not found' when no rows match,
while SQLite/MySQL return 'sql: no rows in result set' from QueryRowContext.
Both behaviors are correct - the key fix is that PostgreSQL no longer
throws JSONB errors on missing/malformed data.
Changes:
- Update test assertions to accept either error type
- Fix comment punctuation for godot linter
- Maintain backward compatibility across all database drivers
Fixes#5612, #5611
Root cause: PostgreSQL's jsonb_array_elements() throws errors when the
'tokens' key is missing or malformed, while SQLite/MySQL return NULL
gracefully. This caused:
- 502 errors when creating admin after v0.25.3 → v0.26.0 upgrade
- Settings not persisting and users unable to stay logged in
Changes to store/db/postgres/user_setting.go:
- Remove strict JSONB operations from GetUserByPATHash query
- Fetch all PERSONAL_ACCESS_TOKENS rows and filter in Go
- Skip malformed/invalid JSON rows with continue (error recovery)
- Match SQLite/MySQL's forgiving error handling
New integration tests (store/test/user_setting_test.go):
- TestUserSettingGetUserByPATHashNoTokensKey
- TestUserSettingGetUserByPATHashEmptyTokensArray
- TestUserSettingGetUserByPATHashWithOtherUsers
New PostgreSQL-specific tests (store/db/postgres/user_setting_test.go):
- TestGetUserByPATHashWithMissingData (comprehensive edge cases)
- TestGetUserByPATHashPerformance (100+ users)
- TestUpsertUserSetting (basic upsert)
Test coverage:
✅ Missing PERSONAL_ACCESS_TOKENS key
✅ Empty/malformed JSON data
✅ Multiple users with mixed valid/invalid data
✅ Performance with 100+ users
✅ Error recovery without crashes
Benefits:
- No database migration required (TEXT column works fine)
- Backward compatible with v0.25.3 upgrades
- Handles missing/corrupt data gracefully
- Consistent behavior across all database drivers
Add custom memos_unicode_lower() SQLite function to enable proper
case-insensitive text search for non-English languages (Cyrillic,
Greek, CJK, etc.).
Previously, SQLite's LOWER() only worked for ASCII characters due to
modernc.org/sqlite lacking ICU extension. This caused searches for
non-English text to be case-sensitive (e.g., searching 'блины' wouldn't
find 'Блины').
Changes:
- Add store/db/sqlite/functions.go with Unicode case folding function
- Register custom function using golang.org/x/text/cases.Fold()
- Update filter renderer to use custom function for SQLite dialect
- Add test for Unicode case-insensitive search
- Make golang.org/x/text a direct dependency
Fixes#5559