Skip to content

Commit 2dcbdfa

Browse files
committed
fix: make mount point name compatible with sharding by switching it to the list of root ids
fix: make mount point name compatible with sharding by switching it to the list of root ids Signed-off-by: Robin Appelman <robin@icewind.nl> [skip ci]
1 parent 611713c commit 2dcbdfa

1 file changed

Lines changed: 51 additions & 2 deletions

File tree

‎lib/private/Files/Cache/QuerySearchHelper.php‎

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
use OCP\Files\IRootFolder;
1818
use OCP\Files\Mount\IMountPoint;
1919
use OCP\Files\Search\ISearchBinaryOperator;
20+
use OCP\Files\Search\ISearchComparison;
21+
use OCP\Files\Search\ISearchOperator;
2022
use OCP\Files\Search\ISearchQuery;
2123
use OCP\FilesMetadata\IFilesMetadataManager;
2224
use OCP\FilesMetadata\IMetadataQuery;
@@ -98,7 +100,7 @@ public function findUsedTagsInCaches(ISearchQuery $searchQuery, array $caches):
98100
protected function equipQueryForSystemTags(CacheQueryBuilder $query, IUser $user): void {
99101
$query->leftJoin('file', 'systemtag_object_mapping', 'systemtagmap', $query->expr()->andX(
100102
$query->expr()->eq('file.fileid', $query->expr()->castColumn('systemtagmap.objectid', IQueryBuilder::PARAM_INT)),
101-
$query->expr()->eq('systemtagmap.objecttype', $query->createNamedParameter('files'))
103+
$query->expr()->eq('systemtagmap.objecttype', $query->createNamedParameter('files')),
102104
));
103105
$on = $query->expr()->andX($query->expr()->eq('systemtag.id', 'systemtagmap.systemtagid'));
104106
if (!$this->groupManager->isAdmin($user->getUID())) {
@@ -113,7 +115,7 @@ protected function equipQueryForDavTags(CacheQueryBuilder $query, IUser $user):
113115
->leftJoin('tagmap', 'vcategory', 'tag', $query->expr()->andX(
114116
$query->expr()->eq('tagmap.categoryid', 'tag.id'),
115117
$query->expr()->eq('tag.type', $query->createNamedParameter('files')),
116-
$query->expr()->eq('tag.uid', $query->createNamedParameter($user->getUID()))
118+
$query->expr()->eq('tag.uid', $query->createNamedParameter($user->getUID())),
117119
));
118120
}
119121

@@ -148,6 +150,8 @@ public function searchInCaches(ISearchQuery $searchQuery, array $caches): array
148150
// while the resulting rows don't have a way to tell what storage they came from (multiple storages/caches can share storage_id)
149151
// we can just ask every cache if the row belongs to them and give them the cache to do any post processing on the result.
150152

153+
$searchQuery = $this->preProcessQuery($searchQuery);
154+
151155
$builder = $this->getQueryBuilder();
152156

153157
$requestedFields = array_merge(
@@ -249,4 +253,49 @@ public function getCachesAndMountPointsForSearch(IRootFolder $root, string $path
249253

250254
return [$caches, $mountByMountPoint];
251255
}
256+
257+
private function preProcessQuery(ISearchQuery $searchQuery): ISearchQuery {
258+
// when sharding is enabled, we can't join on the mounts table
259+
// so instead we need to fetch the matching mount root ids and filter on those
260+
if ($this->connection->getShardDefinition('filecache') !== null) {
261+
$operation = $this->replaceMountNameWithRootIds($searchQuery->getSearchOperation());
262+
return new SearchQuery(
263+
$operation,
264+
$searchQuery->getLimit(),
265+
$searchQuery->getOffset(),
266+
$searchQuery->getOrder(),
267+
$searchQuery->getUser(),
268+
$searchQuery->limitToHome(),
269+
$searchQuery->getSelectFields(),
270+
);
271+
} else {
272+
return $searchQuery;
273+
}
274+
}
275+
276+
private function replaceMountNameWithRootIds(ISearchOperator $searchOperator): ISearchOperator {
277+
if ($searchOperator instanceof ISearchBinaryOperator) {
278+
return new SearchBinaryOperator(
279+
$searchOperator->getType(),
280+
array_map($this->replaceMountNameWithRootIds(...), $searchOperator->getArguments())
281+
);
282+
} elseif ($searchOperator instanceof ISearchComparison && $searchOperator->getField() === 'mount_point_name') {
283+
if (!in_array($searchOperator->getType(), [
284+
ISearchComparison::COMPARE_LIKE,
285+
ISearchComparison::COMPARE_EQUAL,
286+
ISearchComparison::COMPARE_IN,
287+
], true)) {
288+
throw new \InvalidArgumentException('Filtering mount name with ' . $searchOperator->getType() . ' is not supported');
289+
}
290+
291+
$query = $this->connection->getQueryBuilder();
292+
$query->select('root_id')
293+
->from('mounts', 'm')
294+
->where($this->searchBuilder->searchOperatorToDBExpr($query, $searchOperator));
295+
$rootIds = $query->executeQuery()->fetchAll(\PDO::FETCH_COLUMN);
296+
return new SearchComparison(ISearchComparison::COMPARE_IN, 'fileid', $rootIds);
297+
} else {
298+
return $searchOperator;
299+
}
300+
}
252301
}

0 commit comments

Comments
 (0)