diff --git a/ts/sql/migrations/50-fix-messages-unread-index.ts b/ts/sql/migrations/50-fix-messages-unread-index.ts new file mode 100644 index 000000000..d1fc05a81 --- /dev/null +++ b/ts/sql/migrations/50-fix-messages-unread-index.ts @@ -0,0 +1,32 @@ +// Copyright 2021 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +import type { Database } from 'better-sqlite3'; + +import type { LoggerType } from '../../types/Logging'; + +export default function updateToSchemaVersion50( + currentVersion: number, + db: Database, + logger: LoggerType +): void { + if (currentVersion >= 50) { + return; + } + + db.transaction(() => { + db.exec( + ` + DROP INDEX messages_unread; + + -- Note: here we move to the modern isStory/storyId fields and add received_at/sent_at. + CREATE INDEX messages_unread ON messages + (conversationId, readStatus, isStory, storyId, received_at, sent_at) WHERE readStatus IS NOT NULL; + ` + ); + + db.pragma('user_version = 50'); + })(); + + logger.info('updateToSchemaVersion50: success!'); +} diff --git a/ts/sql/migrations/index.ts b/ts/sql/migrations/index.ts index 0cad9e2e0..f0a03c4f2 100644 --- a/ts/sql/migrations/index.ts +++ b/ts/sql/migrations/index.ts @@ -25,6 +25,7 @@ import updateToSchemaVersion46 from './46-optimize-stories'; import updateToSchemaVersion47 from './47-further-optimize'; import updateToSchemaVersion48 from './48-fix-user-initiated-index'; import updateToSchemaVersion49 from './49-fix-preview-index'; +import updateToSchemaVersion50 from './50-fix-messages-unread-index'; function updateToSchemaVersion1( currentVersion: number, @@ -1913,6 +1914,7 @@ export const SCHEMA_VERSIONS = [ updateToSchemaVersion47, updateToSchemaVersion48, updateToSchemaVersion49, + updateToSchemaVersion50, ]; export function updateSchema(db: Database, logger: LoggerType): void { diff --git a/ts/test-node/sql_migrations_test.ts b/ts/test-node/sql_migrations_test.ts index a47dec04c..c2b67bc95 100644 --- a/ts/test-node/sql_migrations_test.ts +++ b/ts/test-node/sql_migrations_test.ts @@ -1324,4 +1324,31 @@ describe('SQL migrations test', () => { assert.notInclude(details, 'SCAN'); }); }); + + describe('updateToSchemaVersion49', () => { + it('creates usable index for messages_unread', () => { + updateToVersion(50); + + const details = db + .prepare( + ` + EXPLAIN QUERY PLAN + SELECT * FROM messages WHERE + conversationId = 'conversation' AND + readStatus = 'something' AND + isStory IS 0 AND + storyId IS NULL + ORDER BY received_at ASC, sent_at ASC + LIMIT 1; + ` + ) + .all() + .map(({ detail }) => detail) + .join('\n'); + + assert.include(details, 'USING INDEX messages_unread'); + assert.notInclude(details, 'TEMP B-TREE'); + assert.notInclude(details, 'SCAN'); + }); + }); });