From 62bff06aeba369cd05d41cca7b1d563c3f7976de Mon Sep 17 00:00:00 2001 From: Marcel Klehr Date: Thu, 18 Sep 2025 11:43:08 +0200 Subject: [PATCH] fix(FileAccess): Chunk parent query Signed-off-by: Marcel Klehr --- lib/private/Files/Cache/FileAccess.php | 46 ++++++++++++++++++-------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/lib/private/Files/Cache/FileAccess.php b/lib/private/Files/Cache/FileAccess.php index 3274af976b2..8054f486e02 100644 --- a/lib/private/Files/Cache/FileAccess.php +++ b/lib/private/Files/Cache/FileAccess.php @@ -146,26 +146,44 @@ class FileAccess implements IFileAccess { $qb->orderBy('f.fileid', 'ASC'); $files = $qb->executeQuery(); - while ( - /** @var array */ - $row = $files->fetch() - ) { - if (!$endToEndEncrypted && $this->connection->getShardDefinition('filecache') !== null) { - // End to end encrypted files are descendants of a folder with encrypted=1 - // If the filecache table is sharded we need to check individually if the parent is encrypted + if (!$endToEndEncrypted && $this->connection->getShardDefinition('filecache') !== null) { + // End to end encrypted files are descendants of a folder with encrypted=1 + // If the filecache table is sharded we need to check with a separate query if the parent is encrypted + $rows = []; + $i = 0; + do { + while (($rows[] = $files->fetch()) && $i < 1000) { + $i++; + } + $parents = array_map(function ($row) { + return $row['parent']; + }, $rows); + $parentQuery = $this->getQuery(); - $parentQuery->select('encrypted')->from('filecache'); - $parentQuery->whereFileId($row['parent']); + $parentQuery->select('fileid', 'encrypted')->from('filecache'); + $parentQuery->where($parentQuery->expr()->in('fileid', $parentQuery->createNamedParameter($parents, IQueryBuilder::PARAM_INT_ARRAY))); $parentQuery->hintShardKey('storage', $storageId); - $parentQuery->setMaxResults(1); $result = $parentQuery->executeQuery(); - $encrypted = $result->fetchOne(); + $parentRows = $result->fetchAll(); $result->closeCursor(); - if ($encrypted === 1) { - continue; + + $parentEncryptedByFileId = array_column($parentRows, 'encrypted', 'fileid'); + foreach ($rows as $row) { + if ($parentEncryptedByFileId[$row['fileid']] === 1) { + continue; + } + yield Cache::cacheEntryFromData($row, $this->mimeTypeLoader); } + $rows = []; + $i = 1; + } while ($rows[] = $files->fetch()); + } else { + while ( + /** @var array */ + $row = $files->fetch() + ) { + yield Cache::cacheEntryFromData($row, $this->mimeTypeLoader); } - yield Cache::cacheEntryFromData($row, $this->mimeTypeLoader); } $files->closeCursor();