From 2b30866eb4298512910545603acb8a4afde7c562 Mon Sep 17 00:00:00 2001 From: LAKSHAN MURUGANANDAM <95610803+lakshanmuruganandam@users.noreply.github.com> Date: Tue, 11 Aug 2026 18:17:44 +0400 Subject: [PATCH 1/2] refactor(db): introduce ORACLE_MAX_CHUNK_SIZE constant for array_chunk query limits Fixes #5214 --- lib/Db/MessageMapper.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/Db/MessageMapper.php b/lib/Db/MessageMapper.php index 1d80e55049..cd561b8e69 100644 --- a/lib/Db/MessageMapper.php +++ b/lib/Db/MessageMapper.php @@ -50,6 +50,8 @@ class MessageMapper extends QBMapper { use TTransactional; + public const ORACLE_MAX_CHUNK_SIZE = 1000; + /** @var ITimeFactory */ private $timeFactory; @@ -1136,7 +1138,7 @@ public function findIdsGloballyByQuery(IUser $user, SearchQuery $query, ?int $li return array_flat_map(function (array $chunk) use ($select) { $select->setParameter('uids', $chunk, IQueryBuilder::PARAM_INT_ARRAY); return array_map(static fn (Message $message) => $message->getId(), $this->findEntities($select)); - }, array_chunk($uids, 1000)); + }, array_chunk($uids, self::ORACLE_MAX_CHUNK_SIZE)); } return array_map(static fn (Message $message) => $message->getId(), $this->findEntities($select)); From 4f09ce22490708d2930cb238c0f8cebff3ea4fc7 Mon Sep 17 00:00:00 2001 From: LAKSHAN MURUGANANDAM <95610803+lakshanmuruganandam@users.noreply.github.com> Date: Tue, 11 Aug 2026 18:22:28 +0400 Subject: [PATCH 2/2] refactor(db): introduce ORACLE_MAX_CHUNK_SIZE constant for array_chunk query limits Replace hardcoded 1000 array_chunk sizes across MessageMapper with self::ORACLE_MAX_CHUNK_SIZE constant to document and centralize the Oracle IN (...) query limit. Fixes #5214 Signed-off-by: LAKSHAN MURUGANANDAM <95610803+lakshanmuruganandam@users.noreply.github.com> Assisted-by: LAKSHAN MURUGANANDAM <95610803+lakshanmuruganandam@users.noreply.github.com> --- lib/Db/MessageMapper.php | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/Db/MessageMapper.php b/lib/Db/MessageMapper.php index cd561b8e69..6dd1fda24d 100644 --- a/lib/Db/MessageMapper.php +++ b/lib/Db/MessageMapper.php @@ -184,7 +184,7 @@ public function findUidsForIds(Mailbox $mailbox, array $ids) { return array_flat_map(function (array $chunk) use ($query) { $query->setParameter('ids', $chunk, IQueryBuilder::PARAM_INT_ARRAY); return $this->findUids($query); - }, array_chunk($ids, 1000)); + }, array_chunk($ids, self::ORACLE_MAX_CHUNK_SIZE)); } /** @@ -483,7 +483,7 @@ public function updateBulk(Account $account, bool $permflagsEnabled, Message ... $queryTrue->expr()->eq('mailbox_id', $queryTrue->createNamedParameter($mailboxId, IQueryBuilder::PARAM_INT)), $queryTrue->expr()->eq($flag, $queryTrue->createNamedParameter(0, IQueryBuilder::PARAM_INT)) )); - foreach (array_chunk($updateData[$flag . '_true'], 1000) as $chunk) { + foreach (array_chunk($updateData[$flag . '_true'], self::ORACLE_MAX_CHUNK_SIZE) as $chunk) { $queryTrue->setParameter('uids', $chunk, IQueryBuilder::PARAM_INT_ARRAY); $queryTrue->executeStatement(); } @@ -497,7 +497,7 @@ public function updateBulk(Account $account, bool $permflagsEnabled, Message ... $queryFalse->expr()->eq('mailbox_id', $queryFalse->createNamedParameter($mailboxId, IQueryBuilder::PARAM_INT)), $queryFalse->expr()->eq($flag, $queryFalse->createNamedParameter(1, IQueryBuilder::PARAM_INT)) )); - foreach (array_chunk($updateData[$flag . '_false'], 1000) as $chunk) { + foreach (array_chunk($updateData[$flag . '_false'], self::ORACLE_MAX_CHUNK_SIZE) as $chunk) { $queryFalse->setParameter('uids', $chunk, IQueryBuilder::PARAM_INT_ARRAY); $queryFalse->executeStatement(); } @@ -697,7 +697,7 @@ public function deleteAll(Mailbox $mailbox): void { $deleteRecipientsQuery->delete('mail_recipients') ->where($deleteRecipientsQuery->expr()->in('message_id', $deleteRecipientsQuery->createParameter('ids'))); - foreach (array_chunk($messageIds, 1000) as $chunk) { + foreach (array_chunk($messageIds, self::ORACLE_MAX_CHUNK_SIZE) as $chunk) { // delete all related recipient entries $deleteRecipientsQuery->setParameter('ids', $chunk, IQueryBuilder::PARAM_INT_ARRAY); $deleteRecipientsQuery->executeStatement(); @@ -731,7 +731,7 @@ public function deleteByUid(Mailbox $mailbox, int ...$uids): void { $deleteMessagesQuery->expr()->in('id', $deleteMessagesQuery->createParameter('ids')), ); - foreach (array_chunk($uids, 1000) as $chunk) { + foreach (array_chunk($uids, self::ORACLE_MAX_CHUNK_SIZE) as $chunk) { $this->atomic(function () use ($selectMessageIdsQuery, $deleteRecipientsQuery, $deleteMessagesQuery, $chunk) { $selectMessageIdsQuery->setParameter('uids', $chunk, IQueryBuilder::PARAM_INT_ARRAY); $selectResult = $selectMessageIdsQuery->executeQuery(); @@ -999,7 +999,7 @@ public function findIdsByQuery(Mailbox $mailbox, SearchQuery $query, string $sor return array_flat_map(function (array $chunk) use ($qb, $select) { $qb->setParameter('uids', $chunk, IQueryBuilder::PARAM_INT_ARRAY); return array_map(static fn (Message $message) => $message->getId(), $this->findEntities($select)); - }, array_chunk($uids, 1000)); + }, array_chunk($uids, self::ORACLE_MAX_CHUNK_SIZE)); } $result = array_map(static fn (Message $message) => $message->getId(), $this->findEntities($select)); @@ -1246,7 +1246,7 @@ public function findByMailboxAndIds(Mailbox $mailbox, string $userId, array $ids ->orderBy('sent_at', 'desc'); $results = []; - foreach (array_chunk($ids, 1000) as $chunk) { + foreach (array_chunk($ids, self::ORACLE_MAX_CHUNK_SIZE) as $chunk) { $qb->setParameter('ids', $chunk, IQueryBuilder::PARAM_INT_ARRAY); $results[] = $this->findRelatedData($this->findEntities($qb), $userId); } @@ -1273,7 +1273,7 @@ public function findByIds(string $userId, array $ids, string $sortOrder, string ->orderBy($orderBy, $sortOrder); $results = []; - foreach (array_chunk($ids, 1000) as $chunk) { + foreach (array_chunk($ids, self::ORACLE_MAX_CHUNK_SIZE) as $chunk) { $qb->setParameter('ids', $chunk, IQueryBuilder::PARAM_INT_ARRAY); $results[] = $this->findRelatedData($this->findEntities($qb), $userId); } @@ -1298,7 +1298,7 @@ private function findRecipients(array $messages): array { ->where($qb2->expr()->in('message_id', $qb2->createParameter('ids'), IQueryBuilder::PARAM_INT_ARRAY)); $recipientsResults = []; - foreach (array_chunk(array_keys($indexedMessages), 1000) as $chunk) { + foreach (array_chunk(array_keys($indexedMessages), self::ORACLE_MAX_CHUNK_SIZE) as $chunk) { $qb2->setParameter('ids', $chunk, IQueryBuilder::PARAM_INT_ARRAY); $result = $qb2->executeQuery(); $recipientsResults[] = $result->fetchAll(); @@ -1412,7 +1412,7 @@ public function findNewIds(Mailbox $mailbox, array $ids, ?int $lastMessageTimest ->orderBy('m.sent_at', $sortOrder === IMailSearch::ORDER_NEWEST_FIRST ? 'desc' : 'asc'); $results = []; - foreach (array_chunk($ids, 1000) as $chunk) { + foreach (array_chunk($ids, self::ORACLE_MAX_CHUNK_SIZE) as $chunk) { $select->setParameter('ids', $chunk, IQueryBuilder::PARAM_INT_ARRAY); $results[] = $this->findIds($select); } @@ -1474,7 +1474,7 @@ public function deleteOrphans(): void { $query = $qb2 ->delete($this->getTableName()) ->where($qb2->expr()->in('id', $qb2->createParameter('ids'), IQueryBuilder::PARAM_INT_ARRAY)); - foreach (array_chunk($ids, 1000) as $chunk) { + foreach (array_chunk($ids, self::ORACLE_MAX_CHUNK_SIZE) as $chunk) { $query->setParameter('ids', $chunk, IQueryBuilder::PARAM_INT_ARRAY); $query->executeStatement(); } @@ -1496,7 +1496,7 @@ public function deleteOrphans(): void { $recipientsQuery = $qb4 ->delete('mail_recipients') ->where($qb4->expr()->in('id', $qb4->createParameter('ids'), IQueryBuilder::PARAM_INT_ARRAY)); - foreach (array_chunk($ids, 1000) as $chunk) { + foreach (array_chunk($ids, self::ORACLE_MAX_CHUNK_SIZE) as $chunk) { $recipientsQuery->setParameter('ids', $chunk, IQueryBuilder::PARAM_INT_ARRAY); $recipientsQuery->executeStatement(); }