MergeDistributiveOperationsTest.php 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-License-Identifier: AGPL-3.0-or-later
  5. */
  6. namespace Test\Files\Search\QueryOptimizer;
  7. use OC\Files\Search\QueryOptimizer\FlattenSingleArgumentBinaryOperation;
  8. use OC\Files\Search\QueryOptimizer\MergeDistributiveOperations;
  9. use OC\Files\Search\SearchBinaryOperator;
  10. use OC\Files\Search\SearchComparison;
  11. use OCP\Files\Search\ISearchBinaryOperator;
  12. use OCP\Files\Search\ISearchComparison;
  13. use Test\TestCase;
  14. class MergeDistributiveOperationsTest extends TestCase {
  15. private $optimizer;
  16. private $simplifier;
  17. protected function setUp(): void {
  18. parent::setUp();
  19. $this->optimizer = new MergeDistributiveOperations();
  20. $this->simplifier = new FlattenSingleArgumentBinaryOperation();
  21. }
  22. public function testBasicOrOfAnds(): void {
  23. $operator = new SearchBinaryOperator(
  24. ISearchBinaryOperator::OPERATOR_OR,
  25. [
  26. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  27. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 1),
  28. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', 'foo'),
  29. ]),
  30. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  31. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 1),
  32. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', 'bar'),
  33. ]),
  34. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  35. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 1),
  36. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', 'asd'),
  37. ])
  38. ]
  39. );
  40. $this->assertEquals('((storage eq 1 and path eq "foo") or (storage eq 1 and path eq "bar") or (storage eq 1 and path eq "asd"))', $operator->__toString());
  41. $this->optimizer->processOperator($operator);
  42. $this->simplifier->processOperator($operator);
  43. $this->assertEquals('(storage eq 1 and (path eq "foo" or path eq "bar" or path eq "asd"))', $operator->__toString());
  44. }
  45. public function testDontTouchIfNotSame(): void {
  46. $operator = new SearchBinaryOperator(
  47. ISearchBinaryOperator::OPERATOR_OR,
  48. [
  49. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  50. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 1),
  51. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', 'foo'),
  52. ]),
  53. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  54. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 2),
  55. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', 'bar'),
  56. ]),
  57. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  58. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 3),
  59. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', 'asd'),
  60. ])
  61. ]
  62. );
  63. $this->assertEquals('((storage eq 1 and path eq "foo") or (storage eq 2 and path eq "bar") or (storage eq 3 and path eq "asd"))', $operator->__toString());
  64. $this->optimizer->processOperator($operator);
  65. $this->simplifier->processOperator($operator);
  66. $this->assertEquals('((storage eq 1 and path eq "foo") or (storage eq 2 and path eq "bar") or (storage eq 3 and path eq "asd"))', $operator->__toString());
  67. }
  68. public function testMergePartial(): void {
  69. $operator = new SearchBinaryOperator(
  70. ISearchBinaryOperator::OPERATOR_OR,
  71. [
  72. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  73. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 1),
  74. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', 'foo'),
  75. ]),
  76. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  77. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 1),
  78. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', 'bar'),
  79. ]),
  80. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  81. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 2),
  82. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', 'asd'),
  83. ])
  84. ]
  85. );
  86. $this->assertEquals('((storage eq 1 and path eq "foo") or (storage eq 1 and path eq "bar") or (storage eq 2 and path eq "asd"))', $operator->__toString());
  87. $this->optimizer->processOperator($operator);
  88. $this->simplifier->processOperator($operator);
  89. $this->assertEquals('((storage eq 1 and (path eq "foo" or path eq "bar")) or (storage eq 2 and path eq "asd"))', $operator->__toString());
  90. }
  91. public function testOptimizeInside(): void {
  92. $operator = new SearchBinaryOperator(
  93. ISearchBinaryOperator::OPERATOR_AND,
  94. [
  95. new SearchBinaryOperator(
  96. ISearchBinaryOperator::OPERATOR_OR,
  97. [
  98. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  99. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 1),
  100. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', 'foo'),
  101. ]),
  102. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  103. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 1),
  104. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', 'bar'),
  105. ]),
  106. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  107. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 1),
  108. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', 'asd'),
  109. ])
  110. ]
  111. ),
  112. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mimetype', 'text')
  113. ]
  114. );
  115. $this->assertEquals('(((storage eq 1 and path eq "foo") or (storage eq 1 and path eq "bar") or (storage eq 1 and path eq "asd")) and mimetype eq "text")', $operator->__toString());
  116. $this->optimizer->processOperator($operator);
  117. $this->simplifier->processOperator($operator);
  118. $this->assertEquals('((storage eq 1 and (path eq "foo" or path eq "bar" or path eq "asd")) and mimetype eq "text")', $operator->__toString());
  119. }
  120. public function testMoveInnerOperations(): void {
  121. $operator = new SearchBinaryOperator(
  122. ISearchBinaryOperator::OPERATOR_OR,
  123. [
  124. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  125. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 1),
  126. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', 'foo'),
  127. ]),
  128. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  129. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 1),
  130. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', 'bar'),
  131. ]),
  132. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  133. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 1),
  134. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', 'asd'),
  135. new SearchComparison(ISearchComparison::COMPARE_GREATER_THAN, 'size', '100'),
  136. ])
  137. ]
  138. );
  139. $this->assertEquals('((storage eq 1 and path eq "foo") or (storage eq 1 and path eq "bar") or (storage eq 1 and path eq "asd" and size gt "100"))', $operator->__toString());
  140. $this->optimizer->processOperator($operator);
  141. $this->simplifier->processOperator($operator);
  142. $this->assertEquals('(storage eq 1 and (path eq "foo" or path eq "bar" or (path eq "asd" and size gt "100")))', $operator->__toString());
  143. }
  144. }