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,373 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ class Optimizer
5
+ module Algebra
6
+
7
+ # Abstract base class representing Restriction optimizations
8
+ class Restriction < Relation::Operation::Unary
9
+
10
+ # The optimized predicate
11
+ #
12
+ # @return [Function]
13
+ #
14
+ # @api private
15
+ attr_reader :predicate
16
+
17
+ # Initialize an Restriction optimizer
18
+ #
19
+ # @return [undefined]
20
+ #
21
+ # @api private
22
+ def initialize(*)
23
+ super
24
+ @predicate = Function.optimize_operand(operation.predicate)
25
+ end
26
+
27
+ private
28
+
29
+ # Wrap the operand's operand in a Restriction
30
+ #
31
+ # @return [Restriction]
32
+ #
33
+ # @api private
34
+ def wrap_operand(operand = operand.operand)
35
+ operand.restrict(predicate)
36
+ end
37
+
38
+ # Return true if the predicate is a true value
39
+ #
40
+ # @return [Boolean]
41
+ #
42
+ # @api private
43
+ def constant_true_predicate?
44
+ predicate.equal?(true)
45
+ end
46
+
47
+ # Return true if the predicate is not callable, and not a true value
48
+ #
49
+ # In the system anything not a Tautology or true is false.
50
+ #
51
+ # @return [Boolean]
52
+ #
53
+ # @api private
54
+ def constant_false_predicate?
55
+ ! (predicate.respond_to?(:call) || constant_true_predicate?)
56
+ end
57
+
58
+ # Optimize when the predicate is a tautology
59
+ class Tautology < self
60
+
61
+ # Test if the predicate is a tautology
62
+ #
63
+ # @return [Boolean]
64
+ #
65
+ # @api private
66
+ def optimizable?
67
+ predicate.equal?(Axiom::Function::Proposition::Tautology.instance) ||
68
+ constant_true_predicate?
69
+ end
70
+
71
+ # A Restriction with a tautology is a noop
72
+ #
73
+ # @return [Relation]
74
+ #
75
+ # @api private
76
+ def optimize
77
+ operand
78
+ end
79
+
80
+ end # class Tautology
81
+
82
+ # Optimize when the predicate is a contradiction
83
+ class Contradiction < self
84
+
85
+ # Test if the predicate is a contradiction
86
+ #
87
+ # @return [Boolean]
88
+ #
89
+ # @api private
90
+ def optimizable?
91
+ predicate.equal?(Axiom::Function::Proposition::Contradiction.instance) ||
92
+ constant_false_predicate?
93
+ end
94
+
95
+ # A Restriction with a contradiction matches nothing
96
+ #
97
+ # @return [Relation]
98
+ #
99
+ # @api private
100
+ def optimize
101
+ Axiom::Relation::Empty.new(operation.header, operation)
102
+ end
103
+
104
+ end # class Contradiction
105
+
106
+ # Optimize when the operand is a Restriction
107
+ class RestrictionOperand < self
108
+
109
+ # Test if the operand is a Restriction
110
+ #
111
+ # @return [Boolean]
112
+ #
113
+ # @api private
114
+ def optimizable?
115
+ operand.kind_of?(operation.class)
116
+ end
117
+
118
+ # Flatten nested Restrictions into a single Restriction
119
+ #
120
+ # @return [Restriction]
121
+ #
122
+ # @api private
123
+ def optimize
124
+ wrap_operand
125
+ end
126
+
127
+ private
128
+
129
+ # Join the operand and operation predicates and optimize them
130
+ #
131
+ # @return [Function]
132
+ #
133
+ # @api private
134
+ def predicate
135
+ operand.predicate.and(super).optimize
136
+ end
137
+
138
+ end # class RestrictionOperand
139
+
140
+ # Optimize when the operand is a combine operation
141
+ class CombinationOperand < self
142
+
143
+ # Test if the restriction is commutative
144
+ #
145
+ # @return [Boolean]
146
+ #
147
+ # @api private
148
+ def optimizable?
149
+ restriction_commutative?
150
+ end
151
+
152
+ # Distribute the restriction across the operation and apply to the operands
153
+ #
154
+ # @return [Restriction]
155
+ #
156
+ # @api private
157
+ def optimize
158
+ left_restriction.send(relation_method, right_restriction).restrict(partition.remainder)
159
+ end
160
+
161
+ private
162
+
163
+ # Return a predicate partition for the restriction and operand headers
164
+ #
165
+ # @return [PredicatePartition]
166
+ #
167
+ # @api private
168
+ def partition
169
+ PredicatePartition.new(predicate, operand.left.header, operand.right.header)
170
+ end
171
+
172
+ # Test if the restriction can be distributed over the operation
173
+ #
174
+ # If the predicates for the left and right operands would match
175
+ # everything, there is no point in distributing the restriction
176
+ # across the operation, since it will not affect the result.
177
+ #
178
+ # @return [Boolean]
179
+ #
180
+ # @api private
181
+ def restriction_commutative?
182
+ ! (partition_left_tautology? && partition_right_tautology?)
183
+ end
184
+
185
+ # Test if the predicate for the left operand would match everything
186
+ #
187
+ # @return [Boolean]
188
+ #
189
+ # @api private
190
+ def partition_left_tautology?
191
+ partition.left.equal?(Axiom::Function::Proposition::Tautology.instance)
192
+ end
193
+
194
+ # Test if the predicate for the right operand would match everything
195
+ #
196
+ # @return [Boolean]
197
+ #
198
+ # @api private
199
+ def partition_right_tautology?
200
+ partition.right.equal?(Axiom::Function::Proposition::Tautology.instance)
201
+ end
202
+
203
+ # Abstract method to return the relation method name
204
+ #
205
+ # @raise [NotImplementedError]
206
+ # raised when the subclass does not implement the method
207
+ #
208
+ # @api private
209
+ def relation_method
210
+ raise NotImplementedError, "#{self.class}#relation_method must be implemented"
211
+ end
212
+
213
+ # Restrict the left operand with the left predicate partition
214
+ #
215
+ # @return [Restriction]
216
+ #
217
+ # @api private
218
+ def left_restriction
219
+ operand.left.restrict(partition.left)
220
+ end
221
+
222
+ # Restrict the right operand with the right predicate partition
223
+ #
224
+ # @return [Restriction]
225
+ #
226
+ # @api private
227
+ def right_restriction
228
+ operand.right.restrict(partition.right)
229
+ end
230
+
231
+ memoize :partition
232
+ end
233
+
234
+ # Optimize when the operand is a Join
235
+ class JoinOperand < CombinationOperand
236
+
237
+ # Test if the operand is a Join and the restriction is commutative
238
+ #
239
+ # @return [Boolean]
240
+ #
241
+ # @api private
242
+ def optimizable?
243
+ operand.kind_of?(Axiom::Algebra::Join) && super
244
+ end
245
+
246
+ private
247
+
248
+ # Return the relation method name for a Join operation
249
+ #
250
+ # @return [Symbol]
251
+ #
252
+ # @api private
253
+ def relation_method
254
+ :join
255
+ end
256
+
257
+ end # class JoinOperand
258
+
259
+ # Optimize when the operand is a Product
260
+ class ProductOperand < CombinationOperand
261
+
262
+ # Test if the operand is a Join and the restriction is commutative
263
+ #
264
+ # @return [Boolean]
265
+ #
266
+ # @api private
267
+ def optimizable?
268
+ operand.kind_of?(Axiom::Algebra::Product) && super
269
+ end
270
+
271
+ private
272
+
273
+ # Return the relation method name for a Product operation
274
+ #
275
+ # @return [Symbol]
276
+ #
277
+ # @api private
278
+
279
+ def relation_method
280
+ :product
281
+ end
282
+
283
+ end # class ProductOperand
284
+
285
+ # Optimize when the operand is a Set
286
+ class SetOperand < self
287
+
288
+ # Test if the operand is a Restriction
289
+ #
290
+ # @return [Boolean]
291
+ #
292
+ # @api private
293
+ def optimizable?
294
+ operand.kind_of?(Axiom::Relation::Operation::Set)
295
+ end
296
+
297
+ # Wrap each operand in the Set in a Restriction
298
+ #
299
+ # @return [Set]
300
+ #
301
+ # @api private
302
+ def optimize
303
+ operand.class.new(wrap_left, wrap_right)
304
+ end
305
+
306
+ private
307
+
308
+ # Utility method to wrap the left operand in a Restriction
309
+ #
310
+ # @return [Restriction]
311
+ #
312
+ # @api private
313
+ def wrap_left
314
+ wrap_operand(operand.left)
315
+ end
316
+
317
+ # Utility method to wrap the right operand in a Restriction
318
+ #
319
+ # @return [Restriction]
320
+ #
321
+ # @api private
322
+ def wrap_right
323
+ wrap_operand(operand.right)
324
+ end
325
+
326
+ end # class SetOperand
327
+
328
+ # Optimize when the operand is an Order
329
+ class OrderOperand < self
330
+ include Relation::Operation::Unary::OrderOperand
331
+ end # class OrderOperand
332
+
333
+ # Optimize when operand is optimizable
334
+ class UnoptimizedOperand < self
335
+ include Function::Unary::UnoptimizedOperand
336
+
337
+ # Test if the operand is unoptimized
338
+ #
339
+ # @return [Boolean]
340
+ #
341
+ # @api private
342
+ def optimizable?
343
+ super || ! predicate.equal?(operation.predicate)
344
+ end
345
+
346
+ # Return a Restriction with an optimized operand
347
+ #
348
+ # @return [Rename]
349
+ #
350
+ # @api private
351
+ def optimize
352
+ wrap_operand(operand)
353
+ end
354
+
355
+ end # class UnoptimizedOperand
356
+
357
+ Axiom::Algebra::Restriction.optimizer = chain(
358
+ Tautology,
359
+ Contradiction,
360
+ RestrictionOperand,
361
+ JoinOperand,
362
+ ProductOperand,
363
+ SetOperand,
364
+ OrderOperand,
365
+ EmptyOperand,
366
+ MaterializedOperand,
367
+ UnoptimizedOperand
368
+ )
369
+
370
+ end # class Restriction
371
+ end # module Algebra
372
+ end # class Optimizer
373
+ end # module Axiom
@@ -0,0 +1,200 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ class Optimizer
5
+ module Algebra
6
+
7
+ # Abstract base class representing Summarization optimizations
8
+ class Summarization < Relation::Operation::Unary
9
+
10
+ # The optimized summarize_per relation
11
+ #
12
+ # @return [Relation]
13
+ #
14
+ # @api private
15
+ attr_reader :summarize_per
16
+
17
+ # The optimized summarizers
18
+ #
19
+ # @return [Hash{Attribute => Function}]
20
+ #
21
+ # @api private
22
+ attr_reader :summarizers
23
+
24
+ # Initialize a Summarization optimizer
25
+ #
26
+ # @return [undefined]
27
+ #
28
+ # @api private
29
+ def initialize(*)
30
+ super
31
+ @summarize_per = optimize_summarize_per
32
+ @summarizers = optimize_summarizers
33
+ end
34
+
35
+ private
36
+
37
+ # Optimize the summarize per relation
38
+ #
39
+ # @return [Relation]
40
+ #
41
+ # @api private
42
+ def optimize_summarize_per
43
+ operation.summarize_per.optimize
44
+ end
45
+
46
+ # Optimize the summarizers
47
+ #
48
+ # @return [Hash{Attribute => Function}]
49
+ #
50
+ # @api private
51
+ def optimize_summarizers
52
+ Function.optimize_functions(operation.summarizers)
53
+ end
54
+
55
+ # Wrap the operand's operand in a Summarization
56
+ #
57
+ # @return [Summarization]
58
+ #
59
+ # @api private
60
+ def wrap_operand(operand = operand.operand)
61
+ operand.summarize(summarize_per, summarizers)
62
+ end
63
+
64
+ # Optimize when the operand is Empty
65
+ class EmptyOperand < self
66
+
67
+ # Return the default value for a function
68
+ #
69
+ # @param [Object] function
70
+ #
71
+ # @return [Object]
72
+ #
73
+ # @api private
74
+ def self.extension_default(function)
75
+ if function.respond_to?(:default)
76
+ function.finalize(function.default)
77
+ end
78
+ end
79
+
80
+ # Test if the operand is empty
81
+ #
82
+ # @return [Boolean]
83
+ #
84
+ # @api private
85
+ def optimizable?
86
+ operand.kind_of?(Axiom::Relation::Empty)
87
+ end
88
+
89
+ # Return an extended relation with the same headers
90
+ #
91
+ # @return [Extension]
92
+ #
93
+ # @api private
94
+ def optimize
95
+ summarize_per.extend(extensions)
96
+ end
97
+
98
+ private
99
+
100
+ # Return the extensions for the optimized relation
101
+ #
102
+ # @return [Hash{Attribute => #call}]
103
+ #
104
+ # @api private
105
+ def extensions
106
+ extensions = {}
107
+ operation.summarizers.each do |attribute, function|
108
+ extensions[attribute] = self.class.extension_default(function)
109
+ end
110
+ extensions
111
+ end
112
+
113
+ end # class EmptyOperand
114
+
115
+ # Optimize when the summarize_per is empty
116
+ class EmptySummarizePer < self
117
+
118
+ # Test if summarize_per is empty
119
+ #
120
+ # @return [Boolean]
121
+ #
122
+ # @api private
123
+ def optimizable?
124
+ summarize_per.kind_of?(Axiom::Relation::Empty)
125
+ end
126
+
127
+ # Return an empty relation if there is nothing to summarize over
128
+ #
129
+ # @return [Relation::Empty]
130
+ #
131
+ # @api private
132
+ def optimize
133
+ Axiom::Relation::Empty.new(operation.header, operation)
134
+ end
135
+
136
+ end # class EmptySummarizePer
137
+
138
+ # Optimize when the operand is an Order
139
+ class OrderOperand < self
140
+ include Relation::Operation::Unary::OrderOperand
141
+ end # class OrderOperand
142
+
143
+ # Optimize when operand is optimizable
144
+ class UnoptimizedOperand < self
145
+ include Function::Unary::UnoptimizedOperand
146
+
147
+ # Test if the operand is unoptimized
148
+ #
149
+ # @return [Boolean]
150
+ #
151
+ # @api private
152
+ def optimizable?
153
+ super ||
154
+ summarize_per_optimizable? ||
155
+ summarizers_optimizable?
156
+ end
157
+
158
+ # Return a Summarization with an optimized operand
159
+ #
160
+ # @return [Rename]
161
+ #
162
+ # @api private
163
+ def optimize
164
+ wrap_operand(operand)
165
+ end
166
+
167
+ private
168
+
169
+ # Test if the summarize_per relation is optimizable
170
+ #
171
+ # @return [Boolean]
172
+ #
173
+ # @api private
174
+ def summarize_per_optimizable?
175
+ ! summarize_per.equal?(operation.summarize_per)
176
+ end
177
+
178
+ # Test if the summarizers are optimizable
179
+ #
180
+ # @return [Boolean]
181
+ #
182
+ # @api private
183
+ def summarizers_optimizable?
184
+ ! summarizers.eql?(operation.summarizers)
185
+ end
186
+
187
+ end # class UnoptimizedOperand
188
+
189
+ Axiom::Algebra::Summarization.optimizer = chain(
190
+ EmptyOperand,
191
+ EmptySummarizePer,
192
+ OrderOperand,
193
+ MaterializedOperand,
194
+ UnoptimizedOperand
195
+ )
196
+
197
+ end # class Summarization
198
+ end # module Algebra
199
+ end # class Optimizer
200
+ end # module Axiom