CombinedTests.php 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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\QueryOptimizer;
  8. use OC\Files\Search\SearchBinaryOperator;
  9. use OC\Files\Search\SearchComparison;
  10. use OCP\Files\Search\ISearchBinaryOperator;
  11. use OCP\Files\Search\ISearchComparison;
  12. use Test\TestCase;
  13. class CombinedTests extends TestCase {
  14. private QueryOptimizer $optimizer;
  15. protected function setUp(): void {
  16. parent::setUp();
  17. $this->optimizer = new QueryOptimizer();
  18. }
  19. public function testBasicOrOfAnds(): void {
  20. $operator = new SearchBinaryOperator(
  21. ISearchBinaryOperator::OPERATOR_OR,
  22. [
  23. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  24. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 1),
  25. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', 'foo'),
  26. ]),
  27. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  28. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 1),
  29. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', 'bar'),
  30. ]),
  31. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  32. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 1),
  33. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', 'asd'),
  34. ])
  35. ]
  36. );
  37. $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());
  38. $this->optimizer->processOperator($operator);
  39. $this->assertEquals('(storage eq 1 and path in ["foo","bar","asd"])', $operator->__toString());
  40. }
  41. public function testComplexSearchPattern1(): void {
  42. $operator = new SearchBinaryOperator(
  43. ISearchBinaryOperator::OPERATOR_OR,
  44. [
  45. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  46. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 1),
  47. ]),
  48. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  49. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 2),
  50. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, [
  51. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', '201'),
  52. new SearchComparison(ISearchComparison::COMPARE_LIKE, 'path', '201/%'),
  53. ]),
  54. ]),
  55. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  56. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 3),
  57. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', '301'),
  58. ]),
  59. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  60. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 4),
  61. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', '401'),
  62. ]),
  63. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  64. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 3),
  65. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', '302'),
  66. ]),
  67. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  68. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 4),
  69. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', '402'),
  70. ]),
  71. ]
  72. );
  73. $this->assertEquals('((storage eq 1) or (storage eq 2 and (path eq "201" or path like "201\/%")) or (storage eq 3 and path eq "301") or (storage eq 4 and path eq "401") or (storage eq 3 and path eq "302") or (storage eq 4 and path eq "402"))', $operator->__toString());
  74. $this->optimizer->processOperator($operator);
  75. $this->assertEquals('(storage eq 1 or (storage eq 2 and (path eq "201" or path like "201\/%")) or (storage eq 3 and path in ["301","302"]) or (storage eq 4 and path in ["401","402"]))', $operator->__toString());
  76. }
  77. public function testComplexSearchPattern2(): void {
  78. $operator = new SearchBinaryOperator(
  79. ISearchBinaryOperator::OPERATOR_OR,
  80. [
  81. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 1),
  82. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  83. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 2),
  84. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, [
  85. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', '201'),
  86. new SearchComparison(ISearchComparison::COMPARE_LIKE, 'path', '201/%'),
  87. ]),
  88. ]),
  89. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  90. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 3),
  91. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', '301'),
  92. ]),
  93. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  94. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 4),
  95. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', '401'),
  96. ]),
  97. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  98. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 3),
  99. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', '302'),
  100. ]),
  101. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  102. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 4),
  103. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', '402'),
  104. ]),
  105. ]
  106. );
  107. $this->assertEquals('(storage eq 1 or (storage eq 2 and (path eq "201" or path like "201\/%")) or (storage eq 3 and path eq "301") or (storage eq 4 and path eq "401") or (storage eq 3 and path eq "302") or (storage eq 4 and path eq "402"))', $operator->__toString());
  108. $this->optimizer->processOperator($operator);
  109. $this->assertEquals('(storage eq 1 or (storage eq 2 and (path eq "201" or path like "201\/%")) or (storage eq 3 and path in ["301","302"]) or (storage eq 4 and path in ["401","402"]))', $operator->__toString());
  110. }
  111. public function testApplySearchConstraints1(): void {
  112. $operator = new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  113. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  114. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, [
  115. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mimetype', 'image/png'),
  116. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mimetype', 'image/jpeg'),
  117. ]),
  118. ]),
  119. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, [
  120. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  121. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 1),
  122. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, [
  123. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', 'files'),
  124. new SearchComparison(ISearchComparison::COMPARE_LIKE, 'path', 'files/%'),
  125. ]),
  126. ]),
  127. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 2),
  128. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  129. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 3),
  130. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', 'files/301'),
  131. ]),
  132. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  133. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 3),
  134. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', 'files/302'),
  135. ]),
  136. ]),
  137. ]);
  138. $this->assertEquals('(((mimetype eq "image\/png" or mimetype eq "image\/jpeg")) and ((storage eq 1 and (path eq "files" or path like "files\/%")) or storage eq 2 or (storage eq 3 and path eq "files\/301") or (storage eq 3 and path eq "files\/302")))', $operator->__toString());
  139. $this->optimizer->processOperator($operator);
  140. $this->assertEquals('(mimetype in ["image\/png","image\/jpeg"] and ((storage eq 1 and (path eq "files" or path like "files\/%")) or storage eq 2 or (storage eq 3 and path in ["files\/301","files\/302"])))', $operator->__toString());
  141. }
  142. public function testApplySearchConstraints2(): void {
  143. $operator = new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  144. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  145. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, [
  146. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mimetype', 'image/png'),
  147. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mimetype', 'image/jpeg'),
  148. ]),
  149. ]),
  150. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, [
  151. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  152. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 1),
  153. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, [
  154. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', 'files'),
  155. new SearchComparison(ISearchComparison::COMPARE_LIKE, 'path', 'files/%'),
  156. ]),
  157. ]),
  158. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  159. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 2),
  160. ]),
  161. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  162. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 3),
  163. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', 'files/301'),
  164. ]),
  165. new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  166. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'storage', 3),
  167. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', 'files/302'),
  168. ]),
  169. ]),
  170. ]);
  171. $this->assertEquals('(((mimetype eq "image\/png" or mimetype eq "image\/jpeg")) and ((storage eq 1 and (path eq "files" or path like "files\/%")) or (storage eq 2) or (storage eq 3 and path eq "files\/301") or (storage eq 3 and path eq "files\/302")))', $operator->__toString());
  172. $this->optimizer->processOperator($operator);
  173. $this->assertEquals('(mimetype in ["image\/png","image\/jpeg"] and ((storage eq 1 and (path eq "files" or path like "files\/%")) or storage eq 2 or (storage eq 3 and path in ["files\/301","files\/302"])))', $operator->__toString());
  174. }
  175. }