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,70 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ class Optimizer
5
+ module Algebra
6
+
7
+ # Abstract base class representing Product optimizations
8
+ class Product < Relation::Operation::Combination
9
+
10
+ # Optimize when left operand is a TABLE DEE
11
+ class TableDeeLeft < self
12
+
13
+ # Test if the left operand is a TABLE DEE
14
+ #
15
+ # @return [Boolean]
16
+ #
17
+ # @api private
18
+ def optimizable?
19
+ left.header.empty? && ! left.kind_of?(Axiom::Relation::Empty)
20
+ end
21
+
22
+ # A Product with a left TABLE DEE is equivalent to the right operand
23
+ #
24
+ # @return [Relation]
25
+ #
26
+ # @api private
27
+ def optimize
28
+ right
29
+ end
30
+
31
+ end # class TableDeeLeft
32
+
33
+ # Optimize when right operand is a TABLE DEE
34
+ class TableDeeRight < self
35
+
36
+ # Test if the right operand is a TABLE DEE
37
+ #
38
+ # @return [Boolean]
39
+ #
40
+ # @api private
41
+ def optimizable?
42
+ right.header.empty? && ! right.kind_of?(Axiom::Relation::Empty)
43
+ end
44
+
45
+ # A Product with a right TABLE DEE is equivalent to the left operand
46
+ #
47
+ # @return [Relation]
48
+ #
49
+ # @api private
50
+ def optimize
51
+ left
52
+ end
53
+
54
+ end # class TableDeeRight
55
+
56
+ Axiom::Algebra::Product.optimizer = chain(
57
+ TableDeeLeft,
58
+ TableDeeRight,
59
+ EmptyLeft,
60
+ EmptyRight,
61
+ OrderLeft,
62
+ OrderRight,
63
+ MaterializedOperands,
64
+ UnoptimizedOperands
65
+ )
66
+
67
+ end # class Product
68
+ end # module Algebra
69
+ end # class Optimizer
70
+ end # module Axiom
@@ -0,0 +1,212 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ class Optimizer
5
+ module Algebra
6
+
7
+ # Abstract base class representing Projection optimizations
8
+ class Projection < Relation::Operation::Unary
9
+
10
+ private
11
+
12
+ # Wrap the operand's operand in a Projection
13
+ #
14
+ # @return [Projection]
15
+ #
16
+ # @api private
17
+ def wrap_operand(operand = operand.operand)
18
+ operand.project(header)
19
+ end
20
+
21
+ # Optimize when the operand is a Projection
22
+ class ProjectionOperand < self
23
+
24
+ # Test if the operand is a Projection
25
+ #
26
+ # @return [Boolean]
27
+ #
28
+ # @api private
29
+ def optimizable?
30
+ operand.kind_of?(operation.class)
31
+ end
32
+
33
+ # Flatten nested Projections into a single Projection
34
+ #
35
+ # @return [Projection]
36
+ #
37
+ # @api private
38
+ def optimize
39
+ wrap_operand
40
+ end
41
+
42
+ end # class ProjectionOperand
43
+
44
+ # Optimize when the operand is an Extension
45
+ class ExtensionOperand < self
46
+
47
+ # Test if the operand is an Extension
48
+ #
49
+ # @return [Boolean]
50
+ #
51
+ # @api private
52
+ def optimizable?
53
+ operand.kind_of?(Axiom::Algebra::Extension) &&
54
+ operand.extensions != new_extensions
55
+ end
56
+
57
+ # Extend the operand with the attributes not projected away
58
+ #
59
+ # This avoid performing an extension when the new attributes are
60
+ # immediately removed.
61
+ #
62
+ # @return [Projection]
63
+ #
64
+ # @api private
65
+ def optimize
66
+ extend_operand.project(operation.header)
67
+ end
68
+
69
+ private
70
+
71
+ # Extend the operand with only the new extensions
72
+ #
73
+ # @return [Extension]
74
+ #
75
+ # @api private
76
+ def extend_operand
77
+ unwrap_operand.extend(new_extensions)
78
+ end
79
+
80
+ # Unwrap the operand from the Extension
81
+ #
82
+ # @return [Relation]
83
+ #
84
+ # @api private
85
+ def unwrap_operand
86
+ operand.operand
87
+ end
88
+
89
+ # Extensions minus the removed attributes
90
+ #
91
+ # @return [Hash{Attribute => Function}]
92
+ #
93
+ # @api private
94
+ def new_extensions
95
+ extensions = operand.extensions
96
+ attributes = extensions.keys - removed_attributes
97
+ Hash[attributes.zip(extensions.values_at(*attributes))]
98
+ end
99
+
100
+ # Attributes removed by the projection
101
+ #
102
+ # @return [Header]
103
+ #
104
+ # @api private
105
+ def removed_attributes
106
+ operand.header - operation.header
107
+ end
108
+
109
+ memoize :new_extensions, :removed_attributes
110
+ end
111
+
112
+ # Optimize when the operand is a Union
113
+ class UnionOperand < self
114
+
115
+ # Test if the operand is a Union
116
+ #
117
+ # @return [Boolean]
118
+ #
119
+ # @api private
120
+ def optimizable?
121
+ operand.kind_of?(Axiom::Algebra::Union)
122
+ end
123
+
124
+ # Wrap each operand in the Union in a Projection
125
+ #
126
+ # @return [Set]
127
+ #
128
+ # @api private
129
+ def optimize
130
+ wrap_left.union(wrap_right)
131
+ end
132
+
133
+ private
134
+
135
+ # Utility method to wrap the left operand in a Projection
136
+ #
137
+ # @return [Projection]
138
+ #
139
+ # @api private
140
+ def wrap_left
141
+ wrap_operand(operand.left)
142
+ end
143
+
144
+ # Utility method to wrap the right operand in a Projection
145
+ #
146
+ # @return [Projection]
147
+ #
148
+ # @api private
149
+ def wrap_right
150
+ wrap_operand(operand.right)
151
+ end
152
+
153
+ end # class UnionOperand
154
+
155
+ # Optimize when the operand is an Order
156
+ class OrderOperand < self
157
+ include Relation::Operation::Unary::OrderOperand
158
+ end # class OrderOperand
159
+
160
+ # Optimize when the operand is Empty
161
+ class EmptyOperand < self
162
+
163
+ # Test if the operand is empty
164
+ #
165
+ # @return [Boolean]
166
+ #
167
+ # @api private
168
+ def optimizable?
169
+ operand.kind_of?(Axiom::Relation::Empty)
170
+ end
171
+
172
+ # Return a new Empty relation with the operation's headers
173
+ #
174
+ # @return [Empty]
175
+ #
176
+ # @api private
177
+ def optimize
178
+ Axiom::Relation::Empty.new(header, operation)
179
+ end
180
+
181
+ end # class EmptyOperand
182
+
183
+ # Optimize when operand is optimizable
184
+ class UnoptimizedOperand < self
185
+ include Function::Unary::UnoptimizedOperand
186
+
187
+ # Return a Projection with an optimized operand
188
+ #
189
+ # @return [Projection]
190
+ #
191
+ # @api private
192
+ def optimize
193
+ wrap_operand(operand)
194
+ end
195
+
196
+ end # class UnoptimizedOperand
197
+
198
+ Axiom::Algebra::Projection.optimizer = chain(
199
+ UnchangedHeader,
200
+ ProjectionOperand,
201
+ ExtensionOperand,
202
+ UnionOperand,
203
+ OrderOperand,
204
+ EmptyOperand,
205
+ MaterializedOperand,
206
+ UnoptimizedOperand
207
+ )
208
+
209
+ end # class Projection
210
+ end # module Algebra
211
+ end # class Optimizer
212
+ end # module Axiom
@@ -0,0 +1,381 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ class Optimizer
5
+ module Algebra
6
+
7
+ # Abstract base class representing Rename optimizations
8
+ class Rename < Relation::Operation::Unary
9
+
10
+ # The optimized aliases
11
+ #
12
+ # @return [Rename::Aliases]
13
+ #
14
+ # @api private
15
+ attr_reader :aliases
16
+
17
+ # Initialize an Rename optimizer
18
+ #
19
+ # @param [Relation] operation
20
+ #
21
+ # @return [undefined]
22
+ #
23
+ # @api private
24
+ def initialize(operation)
25
+ super
26
+ @aliases = operation.aliases
27
+ end
28
+
29
+ private
30
+
31
+ # Wrap the operand's operand in a Rename
32
+ #
33
+ # @return [Rename]
34
+ #
35
+ # @api private
36
+ def wrap_operand(operand = operand.operand)
37
+ operand.rename(aliases)
38
+ end
39
+
40
+ # Optimize when the operand is a Rename
41
+ class RenameOperand < self
42
+
43
+ # Test if the operand is a Rename
44
+ #
45
+ # @return [Boolean]
46
+ #
47
+ # @api private
48
+ def optimizable?
49
+ operand.kind_of?(operation.class)
50
+ end
51
+
52
+ # Flatten nested Renames into a single Rename
53
+ #
54
+ # @return [Projection]
55
+ #
56
+ # @api private
57
+ def optimize
58
+ wrap_operand
59
+ end
60
+
61
+ private
62
+
63
+ # The optimized aliases
64
+ #
65
+ # @return [Rename::Aliases]
66
+ #
67
+ # @api private
68
+ def aliases
69
+ super.union(operand.aliases)
70
+ end
71
+
72
+ end # class RenameOperand
73
+
74
+ # Optimize when the operand is a Rename with aliases that cancel out
75
+ class RenameOperandAndEmptyAliases < RenameOperand
76
+
77
+ # Test if the operand is a Rename with aliases that cancel out
78
+ #
79
+ # @return [Boolean]
80
+ #
81
+ # @api private
82
+ def optimizable?
83
+ super && aliases.empty?
84
+ end
85
+
86
+ # A Rename wrapping a Rename with aliases that cancel out is a noop
87
+ #
88
+ # @return [Relation]
89
+ #
90
+ # @api private
91
+ def optimize
92
+ operand.operand
93
+ end
94
+
95
+ end # class RenameOperandAndEmptyAliases
96
+
97
+ # Optimize when the operand is a Projection
98
+ class ProjectionOperand < self
99
+
100
+ # Test if the operand is a Projection
101
+ #
102
+ # @return [Boolean]
103
+ #
104
+ # @api private
105
+ def optimizable?
106
+ operand.kind_of?(Axiom::Algebra::Projection) && distributive?
107
+ end
108
+
109
+ # Wrap the Rename in a Projection
110
+ #
111
+ # @return [Projection]
112
+ #
113
+ # @api private
114
+ def optimize
115
+ wrap_operand.project(header)
116
+ end
117
+
118
+ private
119
+
120
+ # Test if the rename can be distributed over the projection
121
+ #
122
+ # @return [Boolean]
123
+ #
124
+ # @api private
125
+ def distributive?
126
+ names = alias_names
127
+ removed_attributes.none? do |attribute|
128
+ names.include?(attribute.name)
129
+ end
130
+ end
131
+
132
+ # Return the aliases as an inverted Hash
133
+ #
134
+ # @return [Hash]
135
+ #
136
+ # @api private
137
+ def alias_names
138
+ aliases.to_hash.values.map { |attribute| attribute.name }
139
+ end
140
+
141
+ # Returns the attributes removed from the projection
142
+ #
143
+ # @return [#all?]
144
+ #
145
+ # @api private
146
+ def removed_attributes
147
+ operand.operand.header - operand.header
148
+ end
149
+
150
+ end # class ProjectionOperand
151
+
152
+ # Optimize when the operand is a Restriction
153
+ class RestrictionOperand < self
154
+
155
+ # Test if the operand is a Restriction
156
+ #
157
+ # @return [Boolean]
158
+ #
159
+ # @api private
160
+ def optimizable?
161
+ operand.kind_of?(Axiom::Algebra::Restriction)
162
+ end
163
+
164
+ # Wrap the Rename in a Restriction
165
+ #
166
+ # @return [Restriction]
167
+ #
168
+ # @api private
169
+ def optimize
170
+ wrap_operand.restrict(rename_predicate)
171
+ end
172
+
173
+ private
174
+
175
+ # Rename the operand predicate
176
+ #
177
+ # @return [Function]
178
+ #
179
+ # @api private
180
+ def rename_predicate
181
+ operand.predicate.rename(aliases)
182
+ end
183
+
184
+ end # class RestrictionOperand
185
+
186
+ # Optimize when the operand is a Set
187
+ class SetOperand < self
188
+
189
+ # Test if the operand is a Set
190
+ #
191
+ # @return [Boolean]
192
+ #
193
+ # @api private
194
+ def optimizable?
195
+ operand.kind_of?(Axiom::Relation::Operation::Set)
196
+ end
197
+
198
+ # Wrap each operand in the Set in a Rename
199
+ #
200
+ # @return [Set]
201
+ #
202
+ # @api private
203
+ def optimize
204
+ operand.class.new(wrap_left, wrap_right)
205
+ end
206
+
207
+ private
208
+
209
+ # Utility method to wrap the left operand in a Rename
210
+ #
211
+ # @return [Rename]
212
+ #
213
+ # @api private
214
+ def wrap_left
215
+ wrap_operand(operand.left)
216
+ end
217
+
218
+ # Utility method to wrap the right operand in a Rename
219
+ #
220
+ # @return [Rename]
221
+ #
222
+ # @api private
223
+ def wrap_right
224
+ wrap_operand(operand.right)
225
+ end
226
+
227
+ end # class SetOperand
228
+
229
+ # Optimize when the operand is a Reverse
230
+ class ReverseOperand < self
231
+
232
+ # Test if the operand is a Reverse
233
+ #
234
+ # @return [Boolean]
235
+ #
236
+ # @api private
237
+ def optimizable?
238
+ operand.kind_of?(Axiom::Relation::Operation::Reverse)
239
+ end
240
+
241
+ # Wrap the Rename in a Reverse
242
+ #
243
+ # @return [Reverse]
244
+ #
245
+ # @api private
246
+ def optimize
247
+ wrap_operand.reverse
248
+ end
249
+
250
+ end # class ReverseOperand
251
+
252
+ # Optimize when the operand is an Order
253
+ class OrderOperand < self
254
+ include Relation::Operation::Unary::OrderOperand
255
+
256
+ # Wrap the Rename in an Order
257
+ #
258
+ # @return [Order]
259
+ #
260
+ # @api private
261
+ def optimize
262
+ wrap_operand.sort_by { directions }
263
+ end
264
+
265
+ private
266
+
267
+ # Return the renamed directions
268
+ #
269
+ # @return [Relation::Operation::Order::DirectionSet]
270
+ #
271
+ # @api private
272
+ def directions
273
+ operand.directions.rename(aliases)
274
+ end
275
+
276
+ end # class OrderOperand
277
+
278
+ # Optimize when the operand is a Limit
279
+ class LimitOperand < self
280
+
281
+ # Test if the operand is a Limit
282
+ #
283
+ # @return [Boolean]
284
+ #
285
+ # @api private
286
+ def optimizable?
287
+ operand.kind_of?(Axiom::Relation::Operation::Limit)
288
+ end
289
+
290
+ # Wrap the Rename in a Limit
291
+ #
292
+ # @return [Limit]
293
+ #
294
+ # @api private
295
+ def optimize
296
+ wrap_operand.take(operand.limit)
297
+ end
298
+
299
+ end # class LimitOperand
300
+
301
+ # Optimize when the operand is an Offset
302
+ class OffsetOperand < self
303
+
304
+ # Test if the operand is an Offset
305
+ #
306
+ # @return [Boolean]
307
+ #
308
+ # @api private
309
+ def optimizable?
310
+ operand.kind_of?(Axiom::Relation::Operation::Offset)
311
+ end
312
+
313
+ # Wrap the Rename in an Offset
314
+ #
315
+ # @return [Offset]
316
+ #
317
+ # @api private
318
+ def optimize
319
+ wrap_operand.drop(operand.offset)
320
+ end
321
+
322
+ end # class OffsetOperand
323
+
324
+ # Optimize when the operand is Empty
325
+ class EmptyOperand < self
326
+
327
+ # Test if the operand is empty
328
+ #
329
+ # @return [Boolean]
330
+ #
331
+ # @api private
332
+ def optimizable?
333
+ operand.kind_of?(Axiom::Relation::Empty)
334
+ end
335
+
336
+ # Return a new Empty relation with the operation's headers
337
+ #
338
+ # @return [Empty]
339
+ #
340
+ # @api private
341
+ def optimize
342
+ Axiom::Relation::Empty.new(header, operation)
343
+ end
344
+
345
+ end # class EmptyOperand
346
+
347
+ # Optimize when operand is optimizable
348
+ class UnoptimizedOperand < self
349
+ include Function::Unary::UnoptimizedOperand
350
+
351
+ # Return a Rename with an optimized operand
352
+ #
353
+ # @return [Rename]
354
+ #
355
+ # @api private
356
+ def optimize
357
+ wrap_operand(operand)
358
+ end
359
+
360
+ end # class UnoptimizedOperand
361
+
362
+ Axiom::Algebra::Rename.optimizer = chain(
363
+ UnchangedHeader,
364
+ RenameOperandAndEmptyAliases,
365
+ RenameOperand,
366
+ ProjectionOperand,
367
+ RestrictionOperand,
368
+ SetOperand,
369
+ ReverseOperand,
370
+ OrderOperand,
371
+ LimitOperand,
372
+ OffsetOperand,
373
+ EmptyOperand,
374
+ MaterializedOperand,
375
+ UnoptimizedOperand
376
+ )
377
+
378
+ end # class Rename
379
+ end # module Algebra
380
+ end # class Optimizer
381
+ end # module Axiom