1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- <?php
- /**
- * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
- * SPDX-License-Identifier: AGPL-3.0-or-later
- */
- namespace OC\Files\Search\QueryOptimizer;
- use OC\Files\Search\SearchBinaryOperator;
- use OC\Files\Search\SearchComparison;
- use OCP\Files\Search\ISearchBinaryOperator;
- use OCP\Files\Search\ISearchComparison;
- use OCP\Files\Search\ISearchOperator;
- /**
- * transform (field == A OR field == B ...) into field IN (A, B, ...)
- */
- class OrEqualsToIn extends ReplacingOptimizerStep {
- public function processOperator(ISearchOperator &$operator): bool {
- if (
- $operator instanceof ISearchBinaryOperator &&
- $operator->getType() === ISearchBinaryOperator::OPERATOR_OR
- ) {
- $groups = $this->groupEqualsComparisonsByField($operator->getArguments());
- $newParts = array_map(function (array $group) {
- if (count($group) > 1) {
- // because of the logic from `groupEqualsComparisonsByField` we now that group is all comparisons on the same field
- /** @var ISearchComparison[] $group */
- $field = $group[0]->getField();
- $values = array_map(function (ISearchComparison $comparison) {
- /** @var string|integer|bool|\DateTime $value */
- $value = $comparison->getValue();
- return $value;
- }, $group);
- $in = new SearchComparison(ISearchComparison::COMPARE_IN, $field, $values);
- $pathEqHash = array_reduce($group, function ($pathEqHash, ISearchComparison $comparison) {
- return $comparison->getQueryHint(ISearchComparison::HINT_PATH_EQ_HASH, true) && $pathEqHash;
- }, true);
- $in->setQueryHint(ISearchComparison::HINT_PATH_EQ_HASH, $pathEqHash);
- return $in;
- } else {
- return $group[0];
- }
- }, $groups);
- if (count($newParts) === 1) {
- $operator = $newParts[0];
- } else {
- $operator = new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, $newParts);
- }
- parent::processOperator($operator);
- return true;
- }
- parent::processOperator($operator);
- return false;
- }
- /**
- * Non-equals operators are put in a separate group for each
- *
- * @param ISearchOperator[] $operators
- * @return ISearchOperator[][]
- */
- private function groupEqualsComparisonsByField(array $operators): array {
- $result = [];
- foreach ($operators as $operator) {
- if ($operator instanceof ISearchComparison && $operator->getType() === ISearchComparison::COMPARE_EQUAL) {
- $result[$operator->getField()][] = $operator;
- } else {
- $result[] = [$operator];
- }
- }
- return array_values($result);
- }
- }
|