axiom-optimizer 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (345) hide show
  1. checksums.yaml +7 -0
  2. data/.gemtest +0 -0
  3. data/.gitignore +37 -0
  4. data/.rspec +4 -0
  5. data/.rvmrc +1 -0
  6. data/.travis.yml +35 -0
  7. data/CONTRIBUTING.md +11 -0
  8. data/Gemfile +10 -0
  9. data/Gemfile.devtools +57 -0
  10. data/Guardfile +23 -0
  11. data/LICENSE +20 -0
  12. data/README.md +111 -0
  13. data/Rakefile +5 -0
  14. data/TODO +144 -0
  15. data/axiom-optimizer.gemspec +25 -0
  16. data/config/flay.yml +3 -0
  17. data/config/flog.yml +2 -0
  18. data/config/mutant.yml +3 -0
  19. data/config/reek.yml +162 -0
  20. data/config/roodi.yml +16 -0
  21. data/config/yardstick.yml +2 -0
  22. data/lib/axiom-optimizer.rb +3 -0
  23. data/lib/axiom/optimizer.rb +168 -0
  24. data/lib/axiom/optimizer/aggregate.rb +16 -0
  25. data/lib/axiom/optimizer/aggregate/count.rb +17 -0
  26. data/lib/axiom/optimizer/aggregate/maximum.rb +17 -0
  27. data/lib/axiom/optimizer/aggregate/mean.rb +17 -0
  28. data/lib/axiom/optimizer/aggregate/minimum.rb +17 -0
  29. data/lib/axiom/optimizer/aggregate/standard_deviation.rb +17 -0
  30. data/lib/axiom/optimizer/aggregate/sum.rb +17 -0
  31. data/lib/axiom/optimizer/aggregate/variance.rb +17 -0
  32. data/lib/axiom/optimizer/algebra/difference.rb +68 -0
  33. data/lib/axiom/optimizer/algebra/extension.rb +97 -0
  34. data/lib/axiom/optimizer/algebra/intersection.rb +68 -0
  35. data/lib/axiom/optimizer/algebra/join.rb +184 -0
  36. data/lib/axiom/optimizer/algebra/product.rb +70 -0
  37. data/lib/axiom/optimizer/algebra/projection.rb +212 -0
  38. data/lib/axiom/optimizer/algebra/rename.rb +381 -0
  39. data/lib/axiom/optimizer/algebra/restriction.rb +373 -0
  40. data/lib/axiom/optimizer/algebra/summarization.rb +200 -0
  41. data/lib/axiom/optimizer/algebra/union.rb +68 -0
  42. data/lib/axiom/optimizer/function.rb +87 -0
  43. data/lib/axiom/optimizer/function/binary.rb +124 -0
  44. data/lib/axiom/optimizer/function/connective/binary.rb +245 -0
  45. data/lib/axiom/optimizer/function/connective/conjunction.rb +122 -0
  46. data/lib/axiom/optimizer/function/connective/disjunction.rb +122 -0
  47. data/lib/axiom/optimizer/function/connective/negation.rb +65 -0
  48. data/lib/axiom/optimizer/function/numeric.rb +34 -0
  49. data/lib/axiom/optimizer/function/numeric/absolute.rb +20 -0
  50. data/lib/axiom/optimizer/function/numeric/addition.rb +20 -0
  51. data/lib/axiom/optimizer/function/numeric/division.rb +20 -0
  52. data/lib/axiom/optimizer/function/numeric/exponentiation.rb +20 -0
  53. data/lib/axiom/optimizer/function/numeric/modulo.rb +20 -0
  54. data/lib/axiom/optimizer/function/numeric/multiplication.rb +20 -0
  55. data/lib/axiom/optimizer/function/numeric/square_root.rb +20 -0
  56. data/lib/axiom/optimizer/function/numeric/subtraction.rb +20 -0
  57. data/lib/axiom/optimizer/function/numeric/unary_minus.rb +20 -0
  58. data/lib/axiom/optimizer/function/numeric/unary_plus.rb +20 -0
  59. data/lib/axiom/optimizer/function/predicate.rb +61 -0
  60. data/lib/axiom/optimizer/function/predicate/comparable.rb +144 -0
  61. data/lib/axiom/optimizer/function/predicate/enumerable.rb +138 -0
  62. data/lib/axiom/optimizer/function/predicate/equality.rb +44 -0
  63. data/lib/axiom/optimizer/function/predicate/exclusion.rb +43 -0
  64. data/lib/axiom/optimizer/function/predicate/greater_than.rb +55 -0
  65. data/lib/axiom/optimizer/function/predicate/greater_than_or_equal_to.rb +55 -0
  66. data/lib/axiom/optimizer/function/predicate/inclusion.rb +43 -0
  67. data/lib/axiom/optimizer/function/predicate/inequality.rb +44 -0
  68. data/lib/axiom/optimizer/function/predicate/less_than.rb +55 -0
  69. data/lib/axiom/optimizer/function/predicate/less_than_or_equal_to.rb +55 -0
  70. data/lib/axiom/optimizer/function/predicate/match.rb +20 -0
  71. data/lib/axiom/optimizer/function/predicate/no_match.rb +20 -0
  72. data/lib/axiom/optimizer/function/string/length.rb +31 -0
  73. data/lib/axiom/optimizer/function/unary.rb +86 -0
  74. data/lib/axiom/optimizer/optimizable.rb +60 -0
  75. data/lib/axiom/optimizer/relation/materialized.rb +40 -0
  76. data/lib/axiom/optimizer/relation/operation/binary.rb +134 -0
  77. data/lib/axiom/optimizer/relation/operation/combination.rb +33 -0
  78. data/lib/axiom/optimizer/relation/operation/deletion.rb +20 -0
  79. data/lib/axiom/optimizer/relation/operation/insertion.rb +20 -0
  80. data/lib/axiom/optimizer/relation/operation/limit.rb +141 -0
  81. data/lib/axiom/optimizer/relation/operation/offset.rb +106 -0
  82. data/lib/axiom/optimizer/relation/operation/order.rb +85 -0
  83. data/lib/axiom/optimizer/relation/operation/reverse.rb +85 -0
  84. data/lib/axiom/optimizer/relation/operation/unary.rb +124 -0
  85. data/lib/axiom/optimizer/support/predicate_partition.rb +184 -0
  86. data/lib/axiom/optimizer/version.rb +10 -0
  87. data/spec/integration/axiom/algebra/difference/optimize_spec.rb +160 -0
  88. data/spec/integration/axiom/algebra/intersection/optimize_spec.rb +160 -0
  89. data/spec/integration/axiom/algebra/join/optimize_spec.rb +112 -0
  90. data/spec/integration/axiom/algebra/product/optimize_spec.rb +178 -0
  91. data/spec/integration/axiom/algebra/projection/optimize_spec.rb +250 -0
  92. data/spec/integration/axiom/algebra/rename/optimize_spec.rb +442 -0
  93. data/spec/integration/axiom/algebra/restriction/optimize_spec.rb +218 -0
  94. data/spec/integration/axiom/algebra/summarization/optimize_spec.rb +49 -0
  95. data/spec/integration/axiom/algebra/union/optimize_spec.rb +200 -0
  96. data/spec/integration/axiom/function/connective/conjunction/optimize_spec.rb +236 -0
  97. data/spec/integration/axiom/function/connective/disjunction/optimize_spec.rb +237 -0
  98. data/spec/integration/axiom/function/connective/negation/optimize_spec.rb +43 -0
  99. data/spec/integration/axiom/function/optimize_spec.rb +30 -0
  100. data/spec/integration/axiom/function/predicate/equality/optimize_spec.rb +92 -0
  101. data/spec/integration/axiom/function/predicate/exclusion/optimize_spec.rb +133 -0
  102. data/spec/integration/axiom/function/predicate/greater_than/optimize_spec.rb +102 -0
  103. data/spec/integration/axiom/function/predicate/greater_than_or_equal_to/optimize_spec.rb +102 -0
  104. data/spec/integration/axiom/function/predicate/inclusion/optimize_spec.rb +133 -0
  105. data/spec/integration/axiom/function/predicate/inequality/optimize_spec.rb +92 -0
  106. data/spec/integration/axiom/function/predicate/less_than/optimize_spec.rb +102 -0
  107. data/spec/integration/axiom/function/predicate/less_than_or_equal_to/optimize_spec.rb +102 -0
  108. data/spec/integration/axiom/relation/empty/optimize_spec.rb +13 -0
  109. data/spec/integration/axiom/relation/materialized/optimize_spec.rb +29 -0
  110. data/spec/integration/axiom/relation/operation/limit/optimize_spec.rb +142 -0
  111. data/spec/integration/axiom/relation/operation/offset/optimize_spec.rb +100 -0
  112. data/spec/integration/axiom/relation/operation/order/optimize_spec.rb +105 -0
  113. data/spec/integration/axiom/relation/operation/reverse/optimize_spec.rb +115 -0
  114. data/spec/integration/axiom/relation/optimize_spec.rb +23 -0
  115. data/spec/rcov.opts +7 -0
  116. data/spec/shared/function_connective_binary_optimize_behavior.rb +102 -0
  117. data/spec/shared/optimize_method_behavior.rb +16 -0
  118. data/spec/spec_helper.rb +38 -0
  119. data/spec/support/add_method_missing.rb +15 -0
  120. data/spec/support/config_alias.rb +3 -0
  121. data/spec/support/ice_nine_config.rb +6 -0
  122. data/spec/support/lazy_enumerable.rb +18 -0
  123. data/spec/unit/axiom/optimizer/algebra/difference/empty_left/optimize_spec.rb +19 -0
  124. data/spec/unit/axiom/optimizer/algebra/difference/empty_right/optimize_spec.rb +19 -0
  125. data/spec/unit/axiom/optimizer/algebra/difference/equal_operands/optimize_spec.rb +23 -0
  126. data/spec/unit/axiom/optimizer/algebra/extension/extensions_spec.rb +31 -0
  127. data/spec/unit/axiom/optimizer/algebra/extension/order_operand/optimizable_predicate_spec.rb +23 -0
  128. data/spec/unit/axiom/optimizer/algebra/extension/order_operand/optimize_spec.rb +22 -0
  129. data/spec/unit/axiom/optimizer/algebra/extension/unoptimized_operand/optimizable_predicate_spec.rb +37 -0
  130. data/spec/unit/axiom/optimizer/algebra/extension/unoptimized_operand/optimize_spec.rb +27 -0
  131. data/spec/unit/axiom/optimizer/algebra/intersection/empty_left/optimize_spec.rb +19 -0
  132. data/spec/unit/axiom/optimizer/algebra/intersection/empty_right/optimize_spec.rb +19 -0
  133. data/spec/unit/axiom/optimizer/algebra/intersection/equal_operands/optimize_spec.rb +19 -0
  134. data/spec/unit/axiom/optimizer/algebra/join/disjoint_headers/optimizable_predicate_spec.rb +29 -0
  135. data/spec/unit/axiom/optimizer/algebra/join/disjoint_headers/optimize_spec.rb +22 -0
  136. data/spec/unit/axiom/optimizer/algebra/join/equal_headers/optimizable_predicate_spec.rb +29 -0
  137. data/spec/unit/axiom/optimizer/algebra/join/equal_headers/optimize_spec.rb +23 -0
  138. data/spec/unit/axiom/optimizer/algebra/join/materialized_left/optimizable_predicate_spec.rb +42 -0
  139. data/spec/unit/axiom/optimizer/algebra/join/materialized_left/optimize_spec.rb +55 -0
  140. data/spec/unit/axiom/optimizer/algebra/join/materialized_right/optimizable_predicate_spec.rb +42 -0
  141. data/spec/unit/axiom/optimizer/algebra/join/materialized_right/optimize_spec.rb +55 -0
  142. data/spec/unit/axiom/optimizer/algebra/product/table_dee_left/optimizable_predicate_spec.rb +27 -0
  143. data/spec/unit/axiom/optimizer/algebra/product/table_dee_left/optimize_spec.rb +18 -0
  144. data/spec/unit/axiom/optimizer/algebra/product/table_dee_right/optimizable_predicate_spec.rb +27 -0
  145. data/spec/unit/axiom/optimizer/algebra/product/table_dee_right/optimize_spec.rb +18 -0
  146. data/spec/unit/axiom/optimizer/algebra/projection/empty_operand/optimizable_predicate_spec.rb +27 -0
  147. data/spec/unit/axiom/optimizer/algebra/projection/empty_operand/optimize_spec.rb +22 -0
  148. data/spec/unit/axiom/optimizer/algebra/projection/extension_operand/optimizable_predicate_spec.rb +35 -0
  149. data/spec/unit/axiom/optimizer/algebra/projection/extension_operand/optimize_spec.rb +22 -0
  150. data/spec/unit/axiom/optimizer/algebra/projection/projection_operand/optimizable_predicate_spec.rb +28 -0
  151. data/spec/unit/axiom/optimizer/algebra/projection/projection_operand/optimize_spec.rb +22 -0
  152. data/spec/unit/axiom/optimizer/algebra/projection/union_operand/optimizable_predicate_spec.rb +29 -0
  153. data/spec/unit/axiom/optimizer/algebra/projection/union_operand/optimize_spec.rb +25 -0
  154. data/spec/unit/axiom/optimizer/algebra/projection/unoptimized_operand/optimizable_predicate_spec.rb +28 -0
  155. data/spec/unit/axiom/optimizer/algebra/projection/unoptimized_operand/optimize_spec.rb +22 -0
  156. data/spec/unit/axiom/optimizer/algebra/rename/aliases_spec.rb +23 -0
  157. data/spec/unit/axiom/optimizer/algebra/rename/empty_operand/optimizable_predicate_spec.rb +27 -0
  158. data/spec/unit/axiom/optimizer/algebra/rename/empty_operand/optimize_spec.rb +21 -0
  159. data/spec/unit/axiom/optimizer/algebra/rename/limit_operand/optimizable_predicate_spec.rb +28 -0
  160. data/spec/unit/axiom/optimizer/algebra/rename/limit_operand/optimize_spec.rb +23 -0
  161. data/spec/unit/axiom/optimizer/algebra/rename/offset_operand/optimizable_predicate_spec.rb +28 -0
  162. data/spec/unit/axiom/optimizer/algebra/rename/offset_operand/optimize_spec.rb +23 -0
  163. data/spec/unit/axiom/optimizer/algebra/rename/order_operand/optimizable_predicate_spec.rb +28 -0
  164. data/spec/unit/axiom/optimizer/algebra/rename/order_operand/optimize_spec.rb +22 -0
  165. data/spec/unit/axiom/optimizer/algebra/rename/projection_operand/optimizable_predicate_spec.rb +43 -0
  166. data/spec/unit/axiom/optimizer/algebra/rename/projection_operand/optimize_spec.rb +22 -0
  167. data/spec/unit/axiom/optimizer/algebra/rename/rename_operand/optimizable_predicate_spec.rb +30 -0
  168. data/spec/unit/axiom/optimizer/algebra/rename/rename_operand/optimize_spec.rb +22 -0
  169. data/spec/unit/axiom/optimizer/algebra/rename/rename_operand_and_empty_aliases/optimizable_predicate_spec.rb +37 -0
  170. data/spec/unit/axiom/optimizer/algebra/rename/rename_operand_and_empty_aliases/optimize_spec.rb +18 -0
  171. data/spec/unit/axiom/optimizer/algebra/rename/restriction_operand/optimizable_predicate_spec.rb +29 -0
  172. data/spec/unit/axiom/optimizer/algebra/rename/restriction_operand/optimize_spec.rb +23 -0
  173. data/spec/unit/axiom/optimizer/algebra/rename/reverse_operand/optimizable_predicate_spec.rb +27 -0
  174. data/spec/unit/axiom/optimizer/algebra/rename/reverse_operand/optimize_spec.rb +23 -0
  175. data/spec/unit/axiom/optimizer/algebra/rename/set_operand/optimizable_predicate_spec.rb +29 -0
  176. data/spec/unit/axiom/optimizer/algebra/rename/set_operand/optimize_spec.rb +23 -0
  177. data/spec/unit/axiom/optimizer/algebra/rename/unoptimized_operand/optimizable_predicate_spec.rb +29 -0
  178. data/spec/unit/axiom/optimizer/algebra/rename/unoptimized_operand/optimize_spec.rb +23 -0
  179. data/spec/unit/axiom/optimizer/algebra/restriction/combination_operand/optimizable_predicate_spec.rb +41 -0
  180. data/spec/unit/axiom/optimizer/algebra/restriction/combination_operand/optimize_spec.rb +35 -0
  181. data/spec/unit/axiom/optimizer/algebra/restriction/contradiction/optimizable_predicate_spec.rb +46 -0
  182. data/spec/unit/axiom/optimizer/algebra/restriction/contradiction/optimize_spec.rb +23 -0
  183. data/spec/unit/axiom/optimizer/algebra/restriction/join_operand/optimizable_predicate_spec.rb +51 -0
  184. data/spec/unit/axiom/optimizer/algebra/restriction/join_operand/optimize_spec.rb +48 -0
  185. data/spec/unit/axiom/optimizer/algebra/restriction/order_operand/optimizable_predicate_spec.rb +28 -0
  186. data/spec/unit/axiom/optimizer/algebra/restriction/order_operand/optimize_spec.rb +22 -0
  187. data/spec/unit/axiom/optimizer/algebra/restriction/predicate_spec.rb +18 -0
  188. data/spec/unit/axiom/optimizer/algebra/restriction/product_operand/optimizable_predicate_spec.rb +44 -0
  189. data/spec/unit/axiom/optimizer/algebra/restriction/product_operand/optimize_spec.rb +48 -0
  190. data/spec/unit/axiom/optimizer/algebra/restriction/restriction_operand/optimizable_predicate_spec.rb +30 -0
  191. data/spec/unit/axiom/optimizer/algebra/restriction/restriction_operand/optimize_spec.rb +24 -0
  192. data/spec/unit/axiom/optimizer/algebra/restriction/set_operand/optimizable_predicate_spec.rb +30 -0
  193. data/spec/unit/axiom/optimizer/algebra/restriction/set_operand/optimize_spec.rb +24 -0
  194. data/spec/unit/axiom/optimizer/algebra/restriction/tautology/optimizable_predicate_spec.rb +33 -0
  195. data/spec/unit/axiom/optimizer/algebra/restriction/tautology/optimize_spec.rb +19 -0
  196. data/spec/unit/axiom/optimizer/algebra/restriction/unoptimized_operand/optimizable_predicate_spec.rb +44 -0
  197. data/spec/unit/axiom/optimizer/algebra/restriction/unoptimized_operand/optimize_spec.rb +24 -0
  198. data/spec/unit/axiom/optimizer/algebra/summarization/empty_operand/class_methods/extension_default_spec.rb +22 -0
  199. data/spec/unit/axiom/optimizer/algebra/summarization/empty_operand/optimizable_predicate_spec.rb +29 -0
  200. data/spec/unit/axiom/optimizer/algebra/summarization/empty_operand/optimize_spec.rb +47 -0
  201. data/spec/unit/axiom/optimizer/algebra/summarization/empty_summarize_per/optimizable_predicate_spec.rb +29 -0
  202. data/spec/unit/axiom/optimizer/algebra/summarization/empty_summarize_per/optimize_spec.rb +25 -0
  203. data/spec/unit/axiom/optimizer/algebra/summarization/order_operand/optimizable_predicate_spec.rb +23 -0
  204. data/spec/unit/axiom/optimizer/algebra/summarization/order_operand/optimize_spec.rb +22 -0
  205. data/spec/unit/axiom/optimizer/algebra/summarization/summarize_per_spec.rb +29 -0
  206. data/spec/unit/axiom/optimizer/algebra/summarization/summarizers_spec.rb +31 -0
  207. data/spec/unit/axiom/optimizer/algebra/summarization/unoptimized_operand/optimizable_predicate_spec.rb +49 -0
  208. data/spec/unit/axiom/optimizer/algebra/summarization/unoptimized_operand/optimize_spec.rb +30 -0
  209. data/spec/unit/axiom/optimizer/algebra/union/empty_left/optimize_spec.rb +19 -0
  210. data/spec/unit/axiom/optimizer/algebra/union/empty_right/optimize_spec.rb +19 -0
  211. data/spec/unit/axiom/optimizer/algebra/union/equal_operands/optimize_spec.rb +19 -0
  212. data/spec/unit/axiom/optimizer/class_methods/chain_spec.rb +56 -0
  213. data/spec/unit/axiom/optimizer/function/binary/constant_operands/optimizable_predicate_spec.rb +36 -0
  214. data/spec/unit/axiom/optimizer/function/binary/constant_operands/optimize_spec.rb +18 -0
  215. data/spec/unit/axiom/optimizer/function/binary/left_spec.rb +28 -0
  216. data/spec/unit/axiom/optimizer/function/binary/right_spec.rb +28 -0
  217. data/spec/unit/axiom/optimizer/function/binary/unoptimized_operands/optimizable_predicate_spec.rb +37 -0
  218. data/spec/unit/axiom/optimizer/function/binary/unoptimized_operands/optimize_spec.rb +23 -0
  219. data/spec/unit/axiom/optimizer/function/class_methods/optimize_functions_spec.rb +26 -0
  220. data/spec/unit/axiom/optimizer/function/class_methods/optimize_operand_spec.rb +22 -0
  221. data/spec/unit/axiom/optimizer/function/connective/binary/constant_operands/optimize_spec.rb +16 -0
  222. data/spec/unit/axiom/optimizer/function/connective/binary/equal_operands/optimizable_predicate_spec.rb +29 -0
  223. data/spec/unit/axiom/optimizer/function/connective/binary/equal_operands/optimize_spec.rb +19 -0
  224. data/spec/unit/axiom/optimizer/function/connective/binary/left_spec.rb +16 -0
  225. data/spec/unit/axiom/optimizer/function/connective/binary/redundant_left/optimizable_predicate_spec.rb +28 -0
  226. data/spec/unit/axiom/optimizer/function/connective/binary/redundant_left/optimize_spec.rb +23 -0
  227. data/spec/unit/axiom/optimizer/function/connective/binary/redundant_right/optimizable_predicate_spec.rb +28 -0
  228. data/spec/unit/axiom/optimizer/function/connective/binary/redundant_right/optimize_spec.rb +23 -0
  229. data/spec/unit/axiom/optimizer/function/connective/binary/right_spec.rb +16 -0
  230. data/spec/unit/axiom/optimizer/function/connective/conjunction/contradiction/optimizable_predicate_spec.rb +64 -0
  231. data/spec/unit/axiom/optimizer/function/connective/conjunction/contradiction/optimize_spec.rb +19 -0
  232. data/spec/unit/axiom/optimizer/function/connective/conjunction/optimizable_to_exclusion/optimizable_predicate_spec.rb +61 -0
  233. data/spec/unit/axiom/optimizer/function/connective/conjunction/optimizable_to_exclusion/optimize_spec.rb +76 -0
  234. data/spec/unit/axiom/optimizer/function/connective/conjunction/tautology_left/optimizable_predicate_spec.rb +29 -0
  235. data/spec/unit/axiom/optimizer/function/connective/conjunction/tautology_left/optimize_spec.rb +19 -0
  236. data/spec/unit/axiom/optimizer/function/connective/conjunction/tautology_right/optimizable_predicate_spec.rb +29 -0
  237. data/spec/unit/axiom/optimizer/function/connective/conjunction/tautology_right/optimize_spec.rb +19 -0
  238. data/spec/unit/axiom/optimizer/function/connective/disjunction/contradiction_left/optimizable_predicate_spec.rb +29 -0
  239. data/spec/unit/axiom/optimizer/function/connective/disjunction/contradiction_left/optimize_spec.rb +19 -0
  240. data/spec/unit/axiom/optimizer/function/connective/disjunction/contradiction_right/optimizable_predicate_spec.rb +29 -0
  241. data/spec/unit/axiom/optimizer/function/connective/disjunction/contradiction_right/optimize_spec.rb +19 -0
  242. data/spec/unit/axiom/optimizer/function/connective/disjunction/optimizable_to_inclusion/optimizable_predicate_spec.rb +61 -0
  243. data/spec/unit/axiom/optimizer/function/connective/disjunction/optimizable_to_inclusion/optimize_spec.rb +76 -0
  244. data/spec/unit/axiom/optimizer/function/connective/disjunction/tautology/optimizable_predicate_spec.rb +64 -0
  245. data/spec/unit/axiom/optimizer/function/connective/disjunction/tautology/optimize_spec.rb +19 -0
  246. data/spec/unit/axiom/optimizer/function/connective/negation/constant_operand/optimize_spec.rb +16 -0
  247. data/spec/unit/axiom/optimizer/function/connective/negation/invertible_operand/optimizable_predicate_spec.rb +28 -0
  248. data/spec/unit/axiom/optimizer/function/connective/negation/invertible_operand/optimize_spec.rb +22 -0
  249. data/spec/unit/axiom/optimizer/function/connective/negation/operand_spec.rb +14 -0
  250. data/spec/unit/axiom/optimizer/function/predicate/comparable/never_comparable/optimizable_predicate_spec.rb +74 -0
  251. data/spec/unit/axiom/optimizer/function/predicate/comparable/never_equivalent/optimizable_predicate_spec.rb +74 -0
  252. data/spec/unit/axiom/optimizer/function/predicate/comparable/normalizable_operands/optimizable_predicate_spec.rb +43 -0
  253. data/spec/unit/axiom/optimizer/function/predicate/comparable/normalizable_operands/optimize_spec.rb +21 -0
  254. data/spec/unit/axiom/optimizer/function/predicate/constant_operands/optimize_spec.rb +16 -0
  255. data/spec/unit/axiom/optimizer/function/predicate/contradiction/optimize_spec.rb +18 -0
  256. data/spec/unit/axiom/optimizer/function/predicate/enumerable/class_methods/sort_by_value_spec.rb +27 -0
  257. data/spec/unit/axiom/optimizer/function/predicate/enumerable/empty_right/optimizable_predicate_spec.rb +78 -0
  258. data/spec/unit/axiom/optimizer/function/predicate/enumerable/one_right/optimizable_predicate_spec.rb +78 -0
  259. data/spec/unit/axiom/optimizer/function/predicate/enumerable/unoptimized_operands/optimizable_predicate_spec.rb +51 -0
  260. data/spec/unit/axiom/optimizer/function/predicate/enumerable/unoptimized_operands/optimize_spec.rb +66 -0
  261. data/spec/unit/axiom/optimizer/function/predicate/equality/tautology/optimizable_predicate_spec.rb +29 -0
  262. data/spec/unit/axiom/optimizer/function/predicate/exclusion/empty_right/optimize_spec.rb +45 -0
  263. data/spec/unit/axiom/optimizer/function/predicate/exclusion/one_right/optimize_spec.rb +65 -0
  264. data/spec/unit/axiom/optimizer/function/predicate/greater_than/contradiction/optimizable_predicate_spec.rb +43 -0
  265. data/spec/unit/axiom/optimizer/function/predicate/greater_than/tautology/optimizable_predicate_spec.rb +28 -0
  266. data/spec/unit/axiom/optimizer/function/predicate/greater_than_or_equal_to/contradiction/optimizable_predicate_spec.rb +43 -0
  267. data/spec/unit/axiom/optimizer/function/predicate/greater_than_or_equal_to/tautology/optimizable_predicate_spec.rb +43 -0
  268. data/spec/unit/axiom/optimizer/function/predicate/inclusion/empty_right/optimize_spec.rb +45 -0
  269. data/spec/unit/axiom/optimizer/function/predicate/inclusion/one_right/optimize_spec.rb +66 -0
  270. data/spec/unit/axiom/optimizer/function/predicate/inequality/contradiction/optimizable_predicate_spec.rb +29 -0
  271. data/spec/unit/axiom/optimizer/function/predicate/less_than/contradiction/optimizable_predicate_spec.rb +43 -0
  272. data/spec/unit/axiom/optimizer/function/predicate/less_than/tautology/optimizable_predicate_spec.rb +28 -0
  273. data/spec/unit/axiom/optimizer/function/predicate/less_than_or_equal_to/contradiction/optimizable_predicate_spec.rb +43 -0
  274. data/spec/unit/axiom/optimizer/function/predicate/less_than_or_equal_to/tautology/optimizable_predicate_spec.rb +43 -0
  275. data/spec/unit/axiom/optimizer/function/predicate/tautology/optimize_spec.rb +18 -0
  276. data/spec/unit/axiom/optimizer/function/unary/constant_operand/optimizable_predicate_spec.rb +27 -0
  277. data/spec/unit/axiom/optimizer/function/unary/constant_operand/optimize_spec.rb +18 -0
  278. data/spec/unit/axiom/optimizer/function/unary/operand_spec.rb +27 -0
  279. data/spec/unit/axiom/optimizer/function/unary/unoptimized_operand/optimizable_predicate_spec.rb +27 -0
  280. data/spec/unit/axiom/optimizer/function/unary/unoptimized_operand/optimize_spec.rb +18 -0
  281. data/spec/unit/axiom/optimizer/function/util/class_methods/attribute_spec.rb +21 -0
  282. data/spec/unit/axiom/optimizer/function/util/class_methods/constant_spec.rb +27 -0
  283. data/spec/unit/axiom/optimizer/function/util/class_methods/max_spec.rb +27 -0
  284. data/spec/unit/axiom/optimizer/function/util/class_methods/min_spec.rb +27 -0
  285. data/spec/unit/axiom/optimizer/operation_spec.rb +13 -0
  286. data/spec/unit/axiom/optimizer/optimizable/class_methods/optimizer_spec.rb +34 -0
  287. data/spec/unit/axiom/optimizer/optimizable/optimize_spec.rb +38 -0
  288. data/spec/unit/axiom/optimizer/optimizable_predicate_spec.rb +17 -0
  289. data/spec/unit/axiom/optimizer/optimize_spec.rb +17 -0
  290. data/spec/unit/axiom/optimizer/predicate_partition/left_spec.rb +149 -0
  291. data/spec/unit/axiom/optimizer/predicate_partition/remainder_spec.rb +149 -0
  292. data/spec/unit/axiom/optimizer/predicate_partition/right_spec.rb +149 -0
  293. data/spec/unit/axiom/optimizer/relation/materialized/empty_operand/optimizable_predicate_spec.rb +22 -0
  294. data/spec/unit/axiom/optimizer/relation/materialized/empty_operand/optimize_spec.rb +21 -0
  295. data/spec/unit/axiom/optimizer/relation/operation/binary/empty_left/optimizable_predicate_spec.rb +28 -0
  296. data/spec/unit/axiom/optimizer/relation/operation/binary/empty_right/optimizable_predicate_spec.rb +28 -0
  297. data/spec/unit/axiom/optimizer/relation/operation/binary/equal_operands/optimizable_predicate_spec.rb +31 -0
  298. data/spec/unit/axiom/optimizer/relation/operation/binary/left_spec.rb +15 -0
  299. data/spec/unit/axiom/optimizer/relation/operation/binary/materialized_operands/optimizable_predicate_spec.rb +37 -0
  300. data/spec/unit/axiom/optimizer/relation/operation/binary/materialized_operands/optimize_spec.rb +22 -0
  301. data/spec/unit/axiom/optimizer/relation/operation/binary/order_left/optimizable_predicate_spec.rb +23 -0
  302. data/spec/unit/axiom/optimizer/relation/operation/binary/order_left/optimize_spec.rb +23 -0
  303. data/spec/unit/axiom/optimizer/relation/operation/binary/order_right/optimizable_predicate_spec.rb +23 -0
  304. data/spec/unit/axiom/optimizer/relation/operation/binary/order_right/optimize_spec.rb +23 -0
  305. data/spec/unit/axiom/optimizer/relation/operation/binary/right_spec.rb +15 -0
  306. data/spec/unit/axiom/optimizer/relation/operation/binary/unoptimized_operands/optimizable_predicate_spec.rb +40 -0
  307. data/spec/unit/axiom/optimizer/relation/operation/binary/unoptimized_operands/optimize_spec.rb +24 -0
  308. data/spec/unit/axiom/optimizer/relation/operation/combination/optimize_spec.rb +18 -0
  309. data/spec/unit/axiom/optimizer/relation/operation/limit/equal_limit_operand/optimizable_predicate_spec.rb +33 -0
  310. data/spec/unit/axiom/optimizer/relation/operation/limit/equal_limit_operand/optimize_spec.rb +18 -0
  311. data/spec/unit/axiom/optimizer/relation/operation/limit/limit_operand/optimizable_predicate_spec.rb +27 -0
  312. data/spec/unit/axiom/optimizer/relation/operation/limit/limit_operand/optimize_spec.rb +35 -0
  313. data/spec/unit/axiom/optimizer/relation/operation/limit/unoptimized_operand/optimizable_predicate_spec.rb +28 -0
  314. data/spec/unit/axiom/optimizer/relation/operation/limit/unoptimized_operand/optimize_spec.rb +22 -0
  315. data/spec/unit/axiom/optimizer/relation/operation/limit/zero_limit/optimizable_predicate_spec.rb +27 -0
  316. data/spec/unit/axiom/optimizer/relation/operation/limit/zero_limit/optimize_spec.rb +22 -0
  317. data/spec/unit/axiom/optimizer/relation/operation/offset/offset_operand/optimizable_predicate_spec.rb +27 -0
  318. data/spec/unit/axiom/optimizer/relation/operation/offset/offset_operand/optimize_spec.rb +21 -0
  319. data/spec/unit/axiom/optimizer/relation/operation/offset/unoptimized_operand/optimizable_predicate_spec.rb +28 -0
  320. data/spec/unit/axiom/optimizer/relation/operation/offset/unoptimized_operand/optimize_spec.rb +22 -0
  321. data/spec/unit/axiom/optimizer/relation/operation/offset/zero_offset/optimizable_predicate_spec.rb +27 -0
  322. data/spec/unit/axiom/optimizer/relation/operation/offset/zero_offset/optimize_spec.rb +17 -0
  323. data/spec/unit/axiom/optimizer/relation/operation/order/one_limit_operand/optimizable_predicate_spec.rb +33 -0
  324. data/spec/unit/axiom/optimizer/relation/operation/order/one_limit_operand/optimize_spec.rb +18 -0
  325. data/spec/unit/axiom/optimizer/relation/operation/order/order_operand/optimizable_predicate_spec.rb +27 -0
  326. data/spec/unit/axiom/optimizer/relation/operation/order/order_operand/optimize_spec.rb +22 -0
  327. data/spec/unit/axiom/optimizer/relation/operation/order/unoptimized_operand/optimizable_predicate_spec.rb +28 -0
  328. data/spec/unit/axiom/optimizer/relation/operation/order/unoptimized_operand/optimize_spec.rb +23 -0
  329. data/spec/unit/axiom/optimizer/relation/operation/reverse/order_operand/optimizable_predicate_spec.rb +27 -0
  330. data/spec/unit/axiom/optimizer/relation/operation/reverse/order_operand/optimize_spec.rb +22 -0
  331. data/spec/unit/axiom/optimizer/relation/operation/reverse/reverse_operand/optimizable_predicate_spec.rb +27 -0
  332. data/spec/unit/axiom/optimizer/relation/operation/reverse/reverse_operand/optimize_spec.rb +19 -0
  333. data/spec/unit/axiom/optimizer/relation/operation/reverse/unoptimized_operand/optimizable_predicate_spec.rb +27 -0
  334. data/spec/unit/axiom/optimizer/relation/operation/reverse/unoptimized_operand/optimize_spec.rb +24 -0
  335. data/spec/unit/axiom/optimizer/relation/operation/unary/empty_operand/optimizable_predicate_spec.rb +23 -0
  336. data/spec/unit/axiom/optimizer/relation/operation/unary/empty_operand/optimize_spec.rb +17 -0
  337. data/spec/unit/axiom/optimizer/relation/operation/unary/header_spec.rb +15 -0
  338. data/spec/unit/axiom/optimizer/relation/operation/unary/materialized_operand/optimizable_predicate_spec.rb +23 -0
  339. data/spec/unit/axiom/optimizer/relation/operation/unary/materialized_operand/optimize_spec.rb +20 -0
  340. data/spec/unit/axiom/optimizer/relation/operation/unary/operand_spec.rb +16 -0
  341. data/spec/unit/axiom/optimizer/relation/operation/unary/order_operand/optimizable_predicate_spec.rb +28 -0
  342. data/spec/unit/axiom/optimizer/relation/operation/unary/order_operand/optimize_spec.rb +27 -0
  343. data/spec/unit/axiom/optimizer/relation/operation/unary/unchanged_header/optimizable_predicate_spec.rb +24 -0
  344. data/spec/unit/axiom/optimizer/relation/operation/unary/unchanged_header/optimize_spec.rb +14 -0
  345. metadata +697 -0
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ class Optimizer
5
+ module Function
6
+ module String
7
+
8
+ # Abstract base class representing Length optimizations
9
+ class Length < Optimizer
10
+ include Unary
11
+
12
+ # Optimize when the operand is constant
13
+ class ConstantOperand < self
14
+ include Unary::ConstantOperand
15
+ end # class ConstantOperand
16
+
17
+ # Optimize when the operand is unoptimized
18
+ class UnoptimizedOperand < self
19
+ include Unary::UnoptimizedOperand
20
+ end # class UnoptimizedOperand
21
+
22
+ Axiom::Function::String::Length.optimizer = chain(
23
+ ConstantOperand,
24
+ UnoptimizedOperand
25
+ )
26
+
27
+ end # class Length
28
+ end # module String
29
+ end # module Function
30
+ end # class Optimizer
31
+ end # module Axiom
@@ -0,0 +1,86 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ class Optimizer
5
+ module Function
6
+
7
+ # Mixin for optimizations to Unary functions
8
+ module Unary
9
+
10
+ # The optimized operand
11
+ #
12
+ # @return [Relation]
13
+ #
14
+ # @api private
15
+ attr_reader :operand
16
+
17
+ # Initialize a Unary optimizer
18
+ #
19
+ # @return [undefined]
20
+ #
21
+ # @api private
22
+ def initialize(*)
23
+ super
24
+ @operand = optimize_operand
25
+ end
26
+
27
+ private
28
+
29
+ # Optimize the operand
30
+ #
31
+ # @return [Relation]
32
+ #
33
+ # @api private
34
+ def optimize_operand
35
+ Function.optimize_operand(operation.operand)
36
+ end
37
+
38
+ # Optimize when the operand is constant
39
+ module ConstantOperand
40
+
41
+ # Test if the operand is constant
42
+ #
43
+ # @return [Boolean]
44
+ #
45
+ # @api private
46
+ def optimizable?
47
+ Util.constant?(operand)
48
+ end
49
+
50
+ # Evaluate the operand and return the constant
51
+ #
52
+ # @return [Object]
53
+ #
54
+ # @api private
55
+ def optimize
56
+ operation.class.call(operand)
57
+ end
58
+
59
+ end # module ConstantOperand
60
+
61
+ # Optimize when the operand is unoptimized
62
+ module UnoptimizedOperand
63
+
64
+ # Test if the operand is unoptimized
65
+ #
66
+ # @return [Boolean]
67
+ #
68
+ # @api private
69
+ def optimizable?
70
+ ! operand.equal?(operation.operand)
71
+ end
72
+
73
+ # Return a Aggregate with an optimized operand
74
+ #
75
+ # @return [Aggregate]
76
+ #
77
+ # @api private
78
+ def optimize
79
+ operation.class.new(operand)
80
+ end
81
+
82
+ end # module UnoptimizedOperand
83
+ end # class Unary
84
+ end # module Function
85
+ end # class Optimizer
86
+ end # module Axiom
@@ -0,0 +1,60 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ class Optimizer
5
+
6
+ # Allow operations to be optimizable
7
+ module Optimizable
8
+ include Adamantium
9
+
10
+ # Hook called when module is included
11
+ #
12
+ # @param [Module] descendant
13
+ # the module or class including Optimizable
14
+ #
15
+ # @return [self]
16
+ #
17
+ # @api private
18
+ def self.included(descendant)
19
+ descendant.extend ClassMethods
20
+ self
21
+ end
22
+
23
+ # Optimize the operation
24
+ #
25
+ # @example
26
+ # optimized = operation.optimize
27
+ #
28
+ # @return [Optimizable]
29
+ # the optimized operation
30
+ #
31
+ # @api public
32
+ #
33
+ # @todo simplify by setting a default Identity optimizer for all relations
34
+ def optimize
35
+ optimizer = self.class.optimizer || Optimizer::Identity
36
+ optimized = optimizer.call(self)
37
+ equal?(optimized) ? self :
38
+ optimized.respond_to?(:optimize) ? optimized.optimize :
39
+ optimized
40
+ end
41
+
42
+ memoize :optimize
43
+
44
+ module ClassMethods
45
+
46
+ # The Optimizer for the operation
47
+ #
48
+ # @return [Optimizable]
49
+ #
50
+ # @api private
51
+ attr_accessor :optimizer
52
+
53
+ end # module ClassMethods
54
+ end # module Optimizable
55
+ end # class Optimizer
56
+ end # module Axiom
57
+
58
+ Axiom::Aggregate.class_eval { include Axiom::Optimizer::Optimizable }
59
+ Axiom::Function.class_eval { include Axiom::Optimizer::Optimizable }
60
+ Axiom::Relation.class_eval { include Axiom::Optimizer::Optimizable }
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ class Optimizer
5
+ module Relation
6
+
7
+ # Abstract base class representing Materialized optimizations
8
+ class Materialized < Optimizer
9
+
10
+ # Optimize when the operand is Empty
11
+ class EmptyOperand < self
12
+
13
+ # Test if the operand is empty
14
+ #
15
+ # @return [Boolean]
16
+ #
17
+ # @api private
18
+ def optimizable?
19
+ operation.empty?
20
+ end
21
+
22
+ # Return a new Empty relation with the operation's headers
23
+ #
24
+ # @return [Empty]
25
+ #
26
+ # @api private
27
+ def optimize
28
+ Axiom::Relation::Empty.new(operation.header, operation)
29
+ end
30
+
31
+ end # class EmptyOperand
32
+
33
+ Axiom::Relation::Materialized.optimizer = chain(
34
+ EmptyOperand
35
+ )
36
+
37
+ end # class Materialized
38
+ end # module Relation
39
+ end # class Optimizer
40
+ end # module Axiom
@@ -0,0 +1,134 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ class Optimizer
5
+ module Relation
6
+ module Operation
7
+
8
+ # Abstract base class representing Binary relation optimizations
9
+ class Binary < Optimizer
10
+ include Function::Binary
11
+
12
+ # Optimize when operands are equal
13
+ module EqualOperands
14
+
15
+ # Test if the operands are equal
16
+ #
17
+ # @return [Boolean]
18
+ #
19
+ # @todo do not materialize the operands to compare them
20
+ #
21
+ # @api private
22
+ def optimizable?
23
+ left.eql?(right)
24
+ end
25
+
26
+ end # module EqualOperands
27
+
28
+ # Optimize when the left operand is Empty
29
+ module EmptyLeft
30
+
31
+ # Test if the left operand is empty
32
+ #
33
+ # @return [Boolean]
34
+ #
35
+ # @api private
36
+ def optimizable?
37
+ left.kind_of?(Axiom::Relation::Empty)
38
+ end
39
+
40
+ end # module EmptyLeft
41
+
42
+ # Optimize when the right operand is Empty
43
+ module EmptyRight
44
+
45
+ # Test if the right operand is empty
46
+ #
47
+ # @return [Boolean]
48
+ #
49
+ # @api private
50
+ def optimizable?
51
+ right.kind_of?(Axiom::Relation::Empty)
52
+ end
53
+
54
+ end # module EmptyRight
55
+
56
+ # Optimize when the left operand is an Order
57
+ class OrderLeft < self
58
+
59
+ # Test if the left operand is an Order
60
+ #
61
+ # @return [Boolean]
62
+ #
63
+ # @api private
64
+ def optimizable?
65
+ left.kind_of?(Axiom::Relation::Operation::Order)
66
+ end
67
+
68
+ # Drop the Order and wrap the left operand
69
+ #
70
+ # @return [Binary]
71
+ #
72
+ # @api private
73
+ def optimize
74
+ operation.class.new(left.operand, right)
75
+ end
76
+
77
+ end # class OrderLeft
78
+
79
+ # Optimize when the right operand is an Order
80
+ class OrderRight < self
81
+
82
+ # Test if the right operand is an Order
83
+ #
84
+ # @return [Boolean]
85
+ #
86
+ # @api private
87
+ def optimizable?
88
+ right.kind_of?(Axiom::Relation::Operation::Order)
89
+ end
90
+
91
+ # Drop the Order and wrap the right operand
92
+ #
93
+ # @return [Binary]
94
+ #
95
+ # @api private
96
+ def optimize
97
+ operation.class.new(left, right.operand)
98
+ end
99
+
100
+ end # class OrderRight
101
+
102
+ # Optimize when the operands are Materialized
103
+ class MaterializedOperands < self
104
+
105
+ # Test if the operands are materialized
106
+ #
107
+ # @return [Boolean]
108
+ #
109
+ # @api private
110
+ def optimizable?
111
+ left.kind_of?(Axiom::Relation::Materialized) &&
112
+ right.kind_of?(Axiom::Relation::Materialized)
113
+ end
114
+
115
+ # Return the materialized operation
116
+ #
117
+ # @return [Relation::Materialized]
118
+ #
119
+ # @api private
120
+ def optimize
121
+ operation.materialize
122
+ end
123
+
124
+ end # class MaterializedOperand
125
+
126
+ # Optimize when the operands are unoptimized
127
+ class UnoptimizedOperands < self
128
+ include Function::Binary::UnoptimizedOperands
129
+ end # class UnoptimizedOperands
130
+ end # class Binary
131
+ end # module Operation
132
+ end # module Relation
133
+ end # class Optimizer
134
+ end # module Axiom
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ class Optimizer
5
+ module Relation
6
+ module Operation
7
+
8
+ # Abstract base class representing combinations of relations
9
+ class Combination < Binary
10
+
11
+ # Any relation combined with an empty relation is an empty relation
12
+ #
13
+ # @return [Relation::Empty]
14
+ #
15
+ # @api private
16
+ def optimize
17
+ Axiom::Relation::Empty.new(operation.header, operation)
18
+ end
19
+
20
+ # Optimize when the left operand is Empty
21
+ class EmptyLeft < self
22
+ include Binary::EmptyLeft
23
+ end # class EmptyLeft
24
+
25
+ # Optimize when the right operand is Empty
26
+ class EmptyRight < self
27
+ include Binary::EmptyRight
28
+ end # class EmptyRight
29
+ end # class Combination
30
+ end # module Operation
31
+ end # module Relation
32
+ end # class Optimizer
33
+ end # module Axiom
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ class Optimizer
5
+ module Relation
6
+ module Operation
7
+
8
+ # Abstract base class representing Difference optimizations
9
+ class Deletion < Relation::Operation::Binary
10
+
11
+ Axiom::Relation::Operation::Deletion.optimizer = chain(
12
+ MaterializedOperands,
13
+ UnoptimizedOperands
14
+ )
15
+
16
+ end # class Deletion
17
+ end # module Operation
18
+ end # module Relation
19
+ end # class Optimizer
20
+ end # module Axiom
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ class Optimizer
5
+ module Relation
6
+ module Operation
7
+
8
+ # Abstract base class representing Difference optimizations
9
+ class Insertion < Relation::Operation::Binary
10
+
11
+ Axiom::Relation::Operation::Insertion.optimizer = chain(
12
+ MaterializedOperands,
13
+ UnoptimizedOperands
14
+ )
15
+
16
+ end # class Insertion
17
+ end # module Operation
18
+ end # module Relation
19
+ end # class Optimizer
20
+ end # module Axiom
@@ -0,0 +1,141 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ class Optimizer
5
+ module Relation
6
+ module Operation
7
+
8
+ # Abstract base class representing Limit optimizations
9
+ class Limit < Unary
10
+
11
+ private
12
+
13
+ # Return the operation limit
14
+ #
15
+ # @return [Integer]
16
+ #
17
+ # @api private
18
+ def limit
19
+ operation.limit
20
+ end
21
+
22
+ # Optimize when the limit is zero
23
+ class ZeroLimit < self
24
+
25
+ # Test if the limit is zero
26
+ #
27
+ # @return [Boolean]
28
+ #
29
+ # @api private
30
+ def optimizable?
31
+ limit.zero?
32
+ end
33
+
34
+ # A Limit with a limit of zero is empty
35
+ #
36
+ # @return [Relation::Empty]
37
+ #
38
+ # @api private
39
+ def optimize
40
+ Axiom::Relation::Empty.new(operation.header, operation)
41
+ end
42
+
43
+ end # class ZeroLimit
44
+
45
+ # Optimize when the operand is a Limit and the limits are equal
46
+ class EqualLimitOperand < self
47
+
48
+ # Test if the operand is a Limit and the limits are equal
49
+ #
50
+ # @return [Boolean]
51
+ #
52
+ # @api private
53
+ def optimizable?
54
+ operand.kind_of?(operation.class) && equal_limit?
55
+ end
56
+
57
+ # Flatten equal Limit relations into a single relation
58
+ #
59
+ # @return [Projection]
60
+ #
61
+ # @api private
62
+ def optimize
63
+ operand
64
+ end
65
+
66
+ private
67
+
68
+ # Test if the operation and operand limits are equal
69
+ #
70
+ # @return [Boolean]
71
+ #
72
+ # @api private
73
+ def equal_limit?
74
+ limit == operand.limit
75
+ end
76
+
77
+ end # class EqualLimitOperand
78
+
79
+ # Optimize when the operand is a Limit
80
+ class LimitOperand < self
81
+
82
+ # Test if the operand is a Limit
83
+ #
84
+ # @return [Boolean]
85
+ #
86
+ # @api private
87
+ def optimizable?
88
+ operand.kind_of?(operation.class)
89
+ end
90
+
91
+ # Flatten Limit operations using the minimum limit
92
+ #
93
+ # @return [Boolean]
94
+ #
95
+ # @api private
96
+ def optimize
97
+ operand.operand.take(min_limit)
98
+ end
99
+
100
+ private
101
+
102
+ # Return the minimum limit between the operation and operand
103
+ #
104
+ # @return [Integer]
105
+ #
106
+ # @api private
107
+ def min_limit
108
+ [ limit, operand.limit ].min
109
+ end
110
+
111
+ end # class LimitOperand
112
+
113
+ # Optimize when operand is optimizable
114
+ class UnoptimizedOperand < self
115
+ include Function::Unary::UnoptimizedOperand
116
+
117
+ # Return a Limit with an optimized operand
118
+ #
119
+ # @return [Limit]
120
+ #
121
+ # @api private
122
+ def optimize
123
+ operand.take(limit)
124
+ end
125
+
126
+ end # class UnoptimizedOperand
127
+
128
+ Axiom::Relation::Operation::Limit.optimizer = chain(
129
+ ZeroLimit,
130
+ EqualLimitOperand,
131
+ LimitOperand,
132
+ EmptyOperand,
133
+ MaterializedOperand,
134
+ UnoptimizedOperand
135
+ )
136
+
137
+ end # class Limit
138
+ end # module Operation
139
+ end # module Relation
140
+ end # class Optimizer
141
+ end # module Axiom