From c34dc3274be7453ebb3141c12feaf3bc7ab5f026 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 12 Dec 2024 17:44:54 +0100 Subject: [PATCH] fix: hint table for columns where needed for sharded queries Signed-off-by: Robin Appelman --- lib/ACL/RuleManager.php | 41 +++++++++++++------------ lib/Folder/FolderManager.php | 59 ++++++++++++++++++------------------ 2 files changed, 51 insertions(+), 49 deletions(-) diff --git a/lib/ACL/RuleManager.php b/lib/ACL/RuleManager.php index e31aeda41..bae739b3f 100644 --- a/lib/ACL/RuleManager.php +++ b/lib/ACL/RuleManager.php @@ -91,11 +91,11 @@ public function getRulesForFilesByPath(IUser $user, int $storageId, array $fileP $rows = []; foreach (array_chunk($hashes, 1000) as $chunk) { $query = $this->connection->getQueryBuilder(); - $query->select(['f.fileid', 'mapping_type', 'mapping_id', 'mask', 'a.permissions', 'path']) + $query->select(['f.fileid', 'mapping_type', 'mapping_id', 'mask', 'a.permissions', 'f.path']) ->from('group_folders_acl', 'a') ->innerJoin('a', 'filecache', 'f', $query->expr()->eq('f.fileid', 'a.fileid')) - ->where($query->expr()->in('path_hash', $query->createNamedParameter($chunk, IQueryBuilder::PARAM_STR_ARRAY))) - ->andWhere($query->expr()->eq('storage', $query->createNamedParameter($storageId, IQueryBuilder::PARAM_INT))) + ->where($query->expr()->in('f.path_hash', $query->createNamedParameter($chunk, IQueryBuilder::PARAM_STR_ARRAY))) + ->andWhere($query->expr()->eq('f.storage', $query->createNamedParameter($storageId, IQueryBuilder::PARAM_INT))) ->andWhere($query->expr()->orX(...array_map(function (IUserMapping $userMapping) use ($query) { return $query->expr()->andX( $query->expr()->eq('mapping_type', $query->createNamedParameter($userMapping->getType())), @@ -129,20 +129,21 @@ public function getRulesForFilesByParent(IUser $user, int $storageId, string $pa } $query = $this->connection->getQueryBuilder(); - $query->select(['f.fileid', 'mapping_type', 'mapping_id', 'mask', 'a.permissions', 'path']) + $query->select(['f.fileid', 'a.mapping_type', 'a.mapping_id', 'a.mask', 'a.permissions', 'f.path']) ->from('filecache', 'f') ->leftJoin('f', 'group_folders_acl', 'a', $query->expr()->eq('f.fileid', 'a.fileid')) - ->andWhere($query->expr()->eq('parent', $query->createNamedParameter($parentId, IQueryBuilder::PARAM_INT))) + ->andWhere($query->expr()->eq('f.parent', $query->createNamedParameter($parentId, IQueryBuilder::PARAM_INT))) + ->andWhere($query->expr()->eq('f.storage', $query->createNamedParameter($storageId, IQueryBuilder::PARAM_INT))) ->andWhere( $query->expr()->orX( $query->expr()->andX( - $query->expr()->isNull('mapping_type'), - $query->expr()->isNull('mapping_id') + $query->expr()->isNull('a.mapping_type'), + $query->expr()->isNull('a.mapping_id') ), ...array_map(function (IUserMapping $userMapping) use ($query) { return $query->expr()->andX( - $query->expr()->eq('mapping_type', $query->createNamedParameter($userMapping->getType())), - $query->expr()->eq('mapping_id', $query->createNamedParameter($userMapping->getId())) + $query->expr()->eq('a.mapping_type', $query->createNamedParameter($userMapping->getType())), + $query->expr()->eq('a.mapping_id', $query->createNamedParameter($userMapping->getId())) ); }, $userMappings) ) @@ -185,11 +186,11 @@ public function getAllRulesForPaths(int $storageId, array $filePaths): array { return md5(trim($path, '/')); }, $filePaths); $query = $this->connection->getQueryBuilder(); - $query->select(['f.fileid', 'mapping_type', 'mapping_id', 'mask', 'a.permissions', 'path']) + $query->select(['f.fileid', 'mapping_type', 'mapping_id', 'mask', 'a.permissions', 'f.path']) ->from('group_folders_acl', 'a') ->innerJoin('a', 'filecache', 'f', $query->expr()->eq('f.fileid', 'a.fileid')) - ->where($query->expr()->in('path_hash', $query->createNamedParameter($hashes, IQueryBuilder::PARAM_STR_ARRAY))) - ->andWhere($query->expr()->eq('storage', $query->createNamedParameter($storageId, IQueryBuilder::PARAM_INT))); + ->where($query->expr()->in('f.path_hash', $query->createNamedParameter($hashes, IQueryBuilder::PARAM_STR_ARRAY))) + ->andWhere($query->expr()->eq('f.storage', $query->createNamedParameter($storageId, IQueryBuilder::PARAM_INT))); $rows = $query->executeQuery()->fetchAll(); @@ -219,14 +220,14 @@ private function rulesByPath(array $rows, array $result = []): array { */ public function getAllRulesForPrefix(int $storageId, string $prefix): array { $query = $this->connection->getQueryBuilder(); - $query->select(['f.fileid', 'mapping_type', 'mapping_id', 'mask', 'a.permissions', 'path']) + $query->select(['f.fileid', 'mapping_type', 'mapping_id', 'mask', 'a.permissions', 'f.path']) ->from('group_folders_acl', 'a') ->innerJoin('a', 'filecache', 'f', $query->expr()->eq('f.fileid', 'a.fileid')) ->where($query->expr()->orX( - $query->expr()->like('path', $query->createNamedParameter($this->connection->escapeLikeParameter($prefix) . '/%')), - $query->expr()->eq('path_hash', $query->createNamedParameter(md5($prefix))) + $query->expr()->like('f.path', $query->createNamedParameter($this->connection->escapeLikeParameter($prefix) . '/%')), + $query->expr()->eq('f.path_hash', $query->createNamedParameter(md5($prefix))) )) - ->andWhere($query->expr()->eq('storage', $query->createNamedParameter($storageId, IQueryBuilder::PARAM_INT))); + ->andWhere($query->expr()->eq('f.storage', $query->createNamedParameter($storageId, IQueryBuilder::PARAM_INT))); $rows = $query->executeQuery()->fetchAll(); @@ -243,14 +244,14 @@ public function getRulesForPrefix(IUser $user, int $storageId, string $prefix): $userMappings = $this->userMappingManager->getMappingsForUser($user); $query = $this->connection->getQueryBuilder(); - $query->select(['f.fileid', 'mapping_type', 'mapping_id', 'mask', 'a.permissions', 'path']) + $query->select(['f.fileid', 'mapping_type', 'mapping_id', 'mask', 'a.permissions', 'f.path']) ->from('group_folders_acl', 'a') ->innerJoin('a', 'filecache', 'f', $query->expr()->eq('f.fileid', 'a.fileid')) ->where($query->expr()->orX( - $query->expr()->like('path', $query->createNamedParameter($this->connection->escapeLikeParameter($prefix) . '/%')), - $query->expr()->eq('path_hash', $query->createNamedParameter(md5($prefix))) + $query->expr()->like('f.path', $query->createNamedParameter($this->connection->escapeLikeParameter($prefix) . '/%')), + $query->expr()->eq('f.path_hash', $query->createNamedParameter(md5($prefix))) )) - ->andWhere($query->expr()->eq('storage', $query->createNamedParameter($storageId, IQueryBuilder::PARAM_INT))) + ->andWhere($query->expr()->eq('f.storage', $query->createNamedParameter($storageId, IQueryBuilder::PARAM_INT))) ->andWhere($query->expr()->orX(...array_map(function (IUserMapping $userMapping) use ($query) { return $query->expr()->andX( $query->expr()->eq('mapping_type', $query->createNamedParameter($userMapping->getType())), diff --git a/lib/Folder/FolderManager.php b/lib/Folder/FolderManager.php index fe7294c1b..ce9c5bff2 100644 --- a/lib/Folder/FolderManager.php +++ b/lib/Folder/FolderManager.php @@ -123,8 +123,9 @@ private function getGroupFolderRootId(int $rootStorageId): int { private function joinQueryWithFileCache(IQueryBuilder $query, int $rootStorageId): void { $query->leftJoin('f', 'filecache', 'c', $query->expr()->andX( // concat with empty string to work around missing cast to string - $query->expr()->eq('c.name', $query->func()->concat('f.folder_id', $query->expr()->literal(""))), - $query->expr()->eq('c.parent', $query->createNamedParameter($this->getGroupFolderRootId($rootStorageId))) + $query->expr()->eq('c.name', $query->func()->concat('f.folder_id', $query->expr()->literal(''))), + $query->expr()->eq('c.parent', $query->createNamedParameter($this->getGroupFolderRootId($rootStorageId))), + $query->expr()->eq('c.storage', $query->createNamedParameter($rootStorageId)), )); } @@ -137,7 +138,7 @@ public function getAllFoldersWithSize(int $rootStorageId): array { $query = $this->connection->getQueryBuilder(); - $query->select('folder_id', 'mount_point', 'quota', 'size', 'acl') + $query->select('folder_id', 'mount_point', 'quota', 'c.size', 'acl') ->from('group_folders', 'f'); $this->joinQueryWithFileCache($query, $rootStorageId); @@ -173,7 +174,7 @@ public function getAllFoldersForUserWithSize(int $rootStorageId, IUser $user): a $query = $this->connection->getQueryBuilder(); - $query->select('f.folder_id', 'mount_point', 'quota', 'size', 'acl') + $query->select('f.folder_id', 'mount_point', 'quota', 'c.size', 'acl') ->from('group_folders', 'f') ->innerJoin( 'f', @@ -283,7 +284,7 @@ public function getFolder(int $id, int $rootStorageId = 0) { $query = $this->connection->getQueryBuilder(); - $query->select('folder_id', 'mount_point', 'quota', 'size', 'acl') + $query->select('folder_id', 'mount_point', 'quota', 'c.size', 'acl') ->from('group_folders', 'f') ->where($query->expr()->eq('folder_id', $query->createNamedParameter($id, IQueryBuilder::PARAM_INT))); $this->joinQueryWithFileCache($query, $rootStorageId); @@ -496,18 +497,18 @@ public function getFoldersForGroup(string $groupId, int $rootStorageId = 0): arr 'mount_point', 'quota', 'acl', - 'fileid', - 'storage', - 'path', - 'name', - 'mimetype', - 'mimepart', - 'size', - 'mtime', - 'storage_mtime', - 'etag', - 'encrypted', - 'parent' + 'c.fileid', + 'c.storage', + 'c.path', + 'c.name', + 'c.mimetype', + 'c.mimepart', + 'c.size', + 'c.mtime', + 'c.storage_mtime', + 'c.etag', + 'c.encrypted', + 'c.parent' ) ->selectAlias('a.permissions', 'group_permissions') ->selectAlias('c.permissions', 'permissions') @@ -547,18 +548,18 @@ public function getFoldersForGroups(array $groupIds, int $rootStorageId = 0): ar 'mount_point', 'quota', 'acl', - 'fileid', - 'storage', - 'path', - 'name', - 'mimetype', - 'mimepart', - 'size', - 'mtime', - 'storage_mtime', - 'etag', - 'encrypted', - 'parent' + 'c.fileid', + 'c.storage', + 'c.path', + 'c.name', + 'c.mimetype', + 'c.mimepart', + 'c.size', + 'c.mtime', + 'c.storage_mtime', + 'c.etag', + 'c.encrypted', + 'c.parent' ) ->selectAlias('a.permissions', 'group_permissions') ->selectAlias('c.permissions', 'permissions')