veritas-optimizer 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (349) hide show
  1. data/.gemtest +0 -0
  2. data/.rvmrc +1 -0
  3. data/.travis.yml +8 -0
  4. data/Gemfile +20 -10
  5. data/Guardfile +22 -0
  6. data/README.rdoc +2 -0
  7. data/Rakefile +4 -2
  8. data/TODO +43 -2
  9. data/config/flay.yml +2 -2
  10. data/config/flog.yml +1 -1
  11. data/config/roodi.yml +4 -4
  12. data/lib/veritas/optimizer/aggregate/count.rb +17 -0
  13. data/lib/veritas/optimizer/aggregate/maximum.rb +17 -0
  14. data/lib/veritas/optimizer/aggregate/mean.rb +17 -0
  15. data/lib/veritas/optimizer/aggregate/minimum.rb +17 -0
  16. data/lib/veritas/optimizer/aggregate/standard_deviation.rb +17 -0
  17. data/lib/veritas/optimizer/aggregate/sum.rb +17 -0
  18. data/lib/veritas/optimizer/aggregate/variance.rb +17 -0
  19. data/lib/veritas/optimizer/aggregate.rb +16 -0
  20. data/lib/veritas/optimizer/algebra/difference.rb +3 -1
  21. data/lib/veritas/optimizer/algebra/extension.rb +58 -3
  22. data/lib/veritas/optimizer/algebra/intersection.rb +3 -1
  23. data/lib/veritas/optimizer/algebra/join.rb +6 -4
  24. data/lib/veritas/optimizer/algebra/product.rb +3 -1
  25. data/lib/veritas/optimizer/algebra/projection.rb +23 -54
  26. data/lib/veritas/optimizer/algebra/rename.rb +55 -80
  27. data/lib/veritas/optimizer/algebra/restriction.rb +33 -66
  28. data/lib/veritas/optimizer/algebra/summarization.rb +161 -3
  29. data/lib/veritas/optimizer/algebra/union.rb +3 -1
  30. data/lib/veritas/optimizer/function/binary.rb +124 -0
  31. data/lib/veritas/optimizer/{logic → function}/connective/binary.rb +48 -102
  32. data/lib/veritas/optimizer/{logic → function}/connective/conjunction.rb +12 -11
  33. data/lib/veritas/optimizer/{logic → function}/connective/disjunction.rb +15 -14
  34. data/lib/veritas/optimizer/function/connective/negation.rb +65 -0
  35. data/lib/veritas/optimizer/function/numeric/absolute.rb +20 -0
  36. data/lib/veritas/optimizer/function/numeric/addition.rb +20 -0
  37. data/lib/veritas/optimizer/function/numeric/division.rb +20 -0
  38. data/lib/veritas/optimizer/function/numeric/exponentiation.rb +20 -0
  39. data/lib/veritas/optimizer/function/numeric/modulo.rb +20 -0
  40. data/lib/veritas/optimizer/function/numeric/multiplication.rb +20 -0
  41. data/lib/veritas/optimizer/function/numeric/square_root.rb +20 -0
  42. data/lib/veritas/optimizer/function/numeric/subtraction.rb +20 -0
  43. data/lib/veritas/optimizer/function/numeric/unary_minus.rb +20 -0
  44. data/lib/veritas/optimizer/function/numeric/unary_plus.rb +20 -0
  45. data/lib/veritas/optimizer/function/numeric.rb +34 -0
  46. data/lib/veritas/optimizer/{logic → function}/predicate/comparable.rb +6 -4
  47. data/lib/veritas/optimizer/{logic → function}/predicate/enumerable.rb +24 -26
  48. data/lib/veritas/optimizer/{logic → function}/predicate/equality.rb +6 -6
  49. data/lib/veritas/optimizer/{logic → function}/predicate/exclusion.rb +6 -16
  50. data/lib/veritas/optimizer/{logic → function}/predicate/greater_than.rb +6 -5
  51. data/lib/veritas/optimizer/{logic → function}/predicate/greater_than_or_equal_to.rb +6 -6
  52. data/lib/veritas/optimizer/{logic → function}/predicate/inclusion.rb +6 -16
  53. data/lib/veritas/optimizer/{logic → function}/predicate/inequality.rb +6 -6
  54. data/lib/veritas/optimizer/{logic → function}/predicate/less_than.rb +6 -5
  55. data/lib/veritas/optimizer/{logic → function}/predicate/less_than_or_equal_to.rb +6 -6
  56. data/lib/veritas/optimizer/{logic → function}/predicate/match.rb +5 -4
  57. data/lib/veritas/optimizer/{logic → function}/predicate/no_match.rb +5 -4
  58. data/lib/veritas/optimizer/function/predicate.rb +61 -0
  59. data/lib/veritas/optimizer/function/string/length.rb +31 -0
  60. data/lib/veritas/optimizer/function/unary.rb +86 -0
  61. data/lib/veritas/optimizer/function.rb +87 -0
  62. data/lib/veritas/optimizer/optimizable.rb +6 -3
  63. data/lib/veritas/optimizer/relation/operation/binary.rb +36 -70
  64. data/lib/veritas/optimizer/relation/operation/limit.rb +1 -9
  65. data/lib/veritas/optimizer/relation/operation/offset.rb +1 -9
  66. data/lib/veritas/optimizer/relation/operation/order.rb +1 -9
  67. data/lib/veritas/optimizer/relation/operation/reverse.rb +1 -9
  68. data/lib/veritas/optimizer/relation/operation/unary.rb +50 -13
  69. data/lib/veritas/optimizer/version.rb +1 -1
  70. data/lib/veritas/optimizer.rb +43 -16
  71. data/spec/integration/veritas/algebra/difference/optimize_spec.rb +6 -4
  72. data/spec/integration/veritas/algebra/intersection/optimize_spec.rb +6 -4
  73. data/spec/integration/veritas/algebra/join/optimize_spec.rb +4 -2
  74. data/spec/integration/veritas/algebra/product/optimize_spec.rb +2 -0
  75. data/spec/integration/veritas/algebra/projection/optimize_spec.rb +6 -4
  76. data/spec/integration/veritas/algebra/rename/optimize_spec.rb +2 -0
  77. data/spec/integration/veritas/algebra/restriction/optimize_spec.rb +9 -7
  78. data/spec/integration/veritas/algebra/summarization/optimize_spec.rb +49 -0
  79. data/spec/integration/veritas/algebra/union/optimize_spec.rb +6 -4
  80. data/spec/integration/veritas/{logic → function}/connective/conjunction/optimize_spec.rb +33 -31
  81. data/spec/integration/veritas/{logic → function}/connective/disjunction/optimize_spec.rb +30 -28
  82. data/spec/integration/veritas/{logic → function}/connective/negation/optimize_spec.rb +7 -5
  83. data/spec/integration/veritas/{logic/expression → function}/optimize_spec.rb +5 -3
  84. data/spec/integration/veritas/{logic → function}/predicate/equality/optimize_spec.rb +9 -7
  85. data/spec/integration/veritas/{logic → function}/predicate/exclusion/optimize_spec.rb +13 -11
  86. data/spec/integration/veritas/{logic → function}/predicate/greater_than/optimize_spec.rb +17 -15
  87. data/spec/integration/veritas/{logic → function}/predicate/greater_than_or_equal_to/optimize_spec.rb +17 -15
  88. data/spec/integration/veritas/{logic → function}/predicate/inclusion/optimize_spec.rb +13 -11
  89. data/spec/integration/veritas/{logic → function}/predicate/inequality/optimize_spec.rb +9 -7
  90. data/spec/integration/veritas/{logic → function}/predicate/less_than/optimize_spec.rb +17 -15
  91. data/spec/integration/veritas/{logic → function}/predicate/less_than_or_equal_to/optimize_spec.rb +17 -15
  92. data/spec/integration/veritas/relation/empty/optimize_spec.rb +2 -0
  93. data/spec/integration/veritas/relation/materialized/optimize_spec.rb +2 -0
  94. data/spec/integration/veritas/relation/operation/limit/optimize_spec.rb +3 -1
  95. data/spec/integration/veritas/relation/operation/offset/optimize_spec.rb +3 -1
  96. data/spec/integration/veritas/relation/operation/order/optimize_spec.rb +4 -2
  97. data/spec/integration/veritas/relation/operation/reverse/optimize_spec.rb +4 -2
  98. data/spec/integration/veritas/relation/optimize_spec.rb +2 -0
  99. data/spec/shared/{logic_connective_binary_optimize_behavior.rb → function_connective_binary_optimize_behavior.rb} +14 -12
  100. data/spec/shared/idempotent_method_behavior.rb +2 -0
  101. data/spec/shared/optimize_method_behavior.rb +2 -0
  102. data/spec/support/add_method_missing.rb +2 -0
  103. data/spec/unit/veritas/optimizer/algebra/difference/empty_left/optimize_spec.rb +2 -0
  104. data/spec/unit/veritas/optimizer/algebra/difference/empty_right/optimize_spec.rb +2 -0
  105. data/spec/unit/veritas/optimizer/algebra/difference/equal_operands/optimize_spec.rb +2 -0
  106. data/spec/unit/veritas/optimizer/algebra/extension/extensions_spec.rb +31 -0
  107. data/spec/unit/veritas/optimizer/algebra/extension/order_operand/optimizable_spec.rb +23 -0
  108. data/spec/unit/veritas/optimizer/algebra/extension/order_operand/optimize_spec.rb +22 -0
  109. data/spec/unit/veritas/optimizer/algebra/extension/unoptimized_operand/optimizable_spec.rb +18 -8
  110. data/spec/unit/veritas/optimizer/algebra/extension/unoptimized_operand/optimize_spec.rb +4 -2
  111. data/spec/unit/veritas/optimizer/algebra/intersection/empty_left/optimize_spec.rb +2 -0
  112. data/spec/unit/veritas/optimizer/algebra/intersection/empty_right/optimize_spec.rb +2 -0
  113. data/spec/unit/veritas/optimizer/algebra/intersection/equal_operands/optimize_spec.rb +2 -0
  114. data/spec/unit/veritas/optimizer/algebra/join/equal_headers/optimizable_spec.rb +2 -0
  115. data/spec/unit/veritas/optimizer/algebra/join/equal_headers/optimize_spec.rb +2 -0
  116. data/spec/unit/veritas/optimizer/algebra/product/table_dee_left/optimizable_spec.rb +2 -0
  117. data/spec/unit/veritas/optimizer/algebra/product/table_dee_left/optimize_spec.rb +2 -0
  118. data/spec/unit/veritas/optimizer/algebra/product/table_dee_right/optimizable_spec.rb +2 -0
  119. data/spec/unit/veritas/optimizer/algebra/product/table_dee_right/optimize_spec.rb +2 -0
  120. data/spec/unit/veritas/optimizer/algebra/projection/empty_operand/optimizable_spec.rb +2 -0
  121. data/spec/unit/veritas/optimizer/algebra/projection/empty_operand/optimize_spec.rb +2 -0
  122. data/spec/unit/veritas/optimizer/algebra/projection/projection_operand/optimizable_spec.rb +2 -0
  123. data/spec/unit/veritas/optimizer/algebra/projection/projection_operand/optimize_spec.rb +2 -0
  124. data/spec/unit/veritas/optimizer/algebra/projection/{set_operand → union_operand}/optimizable_spec.rb +3 -1
  125. data/spec/unit/veritas/optimizer/algebra/projection/{set_operand → union_operand}/optimize_spec.rb +4 -2
  126. data/spec/unit/veritas/optimizer/algebra/projection/unoptimized_operand/optimizable_spec.rb +3 -1
  127. data/spec/unit/veritas/optimizer/algebra/projection/unoptimized_operand/optimize_spec.rb +6 -4
  128. data/spec/unit/veritas/optimizer/algebra/rename/aliases_spec.rb +5 -13
  129. data/spec/unit/veritas/optimizer/algebra/rename/empty_operand/optimizable_spec.rb +2 -0
  130. data/spec/unit/veritas/optimizer/algebra/rename/empty_operand/optimize_spec.rb +2 -0
  131. data/spec/unit/veritas/optimizer/algebra/rename/limit_operand/optimizable_spec.rb +2 -0
  132. data/spec/unit/veritas/optimizer/algebra/rename/limit_operand/optimize_spec.rb +2 -0
  133. data/spec/unit/veritas/optimizer/algebra/rename/offset_operand/optimizable_spec.rb +2 -0
  134. data/spec/unit/veritas/optimizer/algebra/rename/offset_operand/optimize_spec.rb +2 -0
  135. data/spec/unit/veritas/optimizer/algebra/rename/order_operand/optimizable_spec.rb +2 -0
  136. data/spec/unit/veritas/optimizer/algebra/rename/order_operand/optimize_spec.rb +2 -0
  137. data/spec/unit/veritas/optimizer/algebra/rename/projection_operand/optimizable_spec.rb +17 -7
  138. data/spec/unit/veritas/optimizer/algebra/rename/projection_operand/optimize_spec.rb +2 -0
  139. data/spec/unit/veritas/optimizer/algebra/rename/rename_operand/optimizable_spec.rb +2 -0
  140. data/spec/unit/veritas/optimizer/algebra/rename/rename_operand/optimize_spec.rb +2 -0
  141. data/spec/unit/veritas/optimizer/algebra/rename/rename_operand_and_empty_aliases/optimizable_spec.rb +2 -0
  142. data/spec/unit/veritas/optimizer/algebra/rename/rename_operand_and_empty_aliases/optimize_spec.rb +2 -0
  143. data/spec/unit/veritas/optimizer/algebra/rename/restriction_operand/optimizable_spec.rb +3 -1
  144. data/spec/unit/veritas/optimizer/algebra/rename/restriction_operand/optimize_spec.rb +7 -5
  145. data/spec/unit/veritas/optimizer/algebra/rename/reverse_operand/optimizable_spec.rb +2 -0
  146. data/spec/unit/veritas/optimizer/algebra/rename/reverse_operand/optimize_spec.rb +2 -0
  147. data/spec/unit/veritas/optimizer/algebra/rename/set_operand/optimizable_spec.rb +2 -0
  148. data/spec/unit/veritas/optimizer/algebra/rename/set_operand/optimize_spec.rb +2 -0
  149. data/spec/unit/veritas/optimizer/algebra/rename/unoptimized_operand/optimizable_spec.rb +7 -20
  150. data/spec/unit/veritas/optimizer/algebra/rename/unoptimized_operand/optimize_spec.rb +2 -0
  151. data/spec/unit/veritas/optimizer/algebra/restriction/contradiction/optimizable_spec.rb +23 -3
  152. data/spec/unit/veritas/optimizer/algebra/restriction/contradiction/optimize_spec.rb +7 -5
  153. data/spec/unit/veritas/optimizer/algebra/restriction/order_operand/optimizable_spec.rb +3 -1
  154. data/spec/unit/veritas/optimizer/algebra/restriction/order_operand/optimize_spec.rb +7 -3
  155. data/spec/unit/veritas/optimizer/algebra/restriction/predicate_spec.rb +3 -1
  156. data/spec/unit/veritas/optimizer/algebra/restriction/restriction_operand/optimizable_spec.rb +5 -3
  157. data/spec/unit/veritas/optimizer/algebra/restriction/restriction_operand/optimize_spec.rb +8 -6
  158. data/spec/unit/veritas/optimizer/algebra/restriction/set_operand/optimizable_spec.rb +3 -1
  159. data/spec/unit/veritas/optimizer/algebra/restriction/set_operand/optimize_spec.rb +5 -3
  160. data/spec/unit/veritas/optimizer/algebra/restriction/tautology/optimizable_spec.rb +11 -3
  161. data/spec/unit/veritas/optimizer/algebra/restriction/tautology/optimize_spec.rb +4 -2
  162. data/spec/unit/veritas/optimizer/algebra/restriction/unoptimized_operand/optimizable_spec.rb +7 -5
  163. data/spec/unit/veritas/optimizer/algebra/restriction/unoptimized_operand/optimize_spec.rb +2 -0
  164. data/spec/unit/veritas/optimizer/algebra/summarization/empty_operand/class_methods/extension_default_spec.rb +22 -0
  165. data/spec/unit/veritas/optimizer/algebra/summarization/empty_operand/optimizable_spec.rb +29 -0
  166. data/spec/unit/veritas/optimizer/algebra/summarization/empty_operand/optimize_spec.rb +47 -0
  167. data/spec/unit/veritas/optimizer/algebra/summarization/empty_summarize_per/optimizable_spec.rb +29 -0
  168. data/spec/unit/veritas/optimizer/algebra/summarization/empty_summarize_per/optimize_spec.rb +23 -0
  169. data/spec/unit/veritas/optimizer/algebra/summarization/order_operand/optimizable_spec.rb +23 -0
  170. data/spec/unit/veritas/optimizer/algebra/summarization/order_operand/optimize_spec.rb +22 -0
  171. data/spec/unit/veritas/optimizer/algebra/summarization/summarize_per_spec.rb +29 -0
  172. data/spec/unit/veritas/optimizer/algebra/summarization/summarizers_spec.rb +31 -0
  173. data/spec/unit/veritas/optimizer/algebra/summarization/unoptimized_operand/optimizable_spec.rb +30 -8
  174. data/spec/unit/veritas/optimizer/algebra/summarization/unoptimized_operand/optimize_spec.rb +12 -9
  175. data/spec/unit/veritas/optimizer/algebra/union/empty_left/optimize_spec.rb +2 -0
  176. data/spec/unit/veritas/optimizer/algebra/union/empty_right/optimize_spec.rb +2 -0
  177. data/spec/unit/veritas/optimizer/algebra/union/equal_operands/optimize_spec.rb +2 -0
  178. data/spec/unit/veritas/optimizer/class_methods/chain_spec.rb +2 -0
  179. data/spec/unit/veritas/optimizer/function/binary/constant_operands/optimizable_spec.rb +36 -0
  180. data/spec/unit/veritas/optimizer/function/binary/constant_operands/optimize_spec.rb +18 -0
  181. data/spec/unit/veritas/optimizer/function/binary/left_spec.rb +28 -0
  182. data/spec/unit/veritas/optimizer/function/binary/right_spec.rb +28 -0
  183. data/spec/unit/veritas/optimizer/function/binary/unoptimized_operands/optimizable_spec.rb +37 -0
  184. data/spec/unit/veritas/optimizer/function/binary/unoptimized_operands/optimize_spec.rb +23 -0
  185. data/spec/unit/veritas/optimizer/function/class_methods/optimize_functions_spec.rb +26 -0
  186. data/spec/unit/veritas/optimizer/function/class_methods/optimize_operand_spec.rb +22 -0
  187. data/spec/unit/veritas/optimizer/function/connective/binary/constant_operands/optimize_spec.rb +16 -0
  188. data/spec/unit/veritas/optimizer/{logic → function}/connective/binary/equal_operands/optimizable_spec.rb +4 -2
  189. data/spec/unit/veritas/optimizer/{logic → function}/connective/binary/equal_operands/optimize_spec.rb +3 -1
  190. data/spec/unit/veritas/optimizer/{logic → function}/connective/binary/left_spec.rb +3 -1
  191. data/spec/unit/veritas/optimizer/{logic → function}/connective/binary/redundant_left_operand/optimizable_spec.rb +4 -2
  192. data/spec/unit/veritas/optimizer/{logic → function}/connective/binary/redundant_left_operand/optimize_spec.rb +4 -2
  193. data/spec/unit/veritas/optimizer/{logic → function}/connective/binary/redundant_right_operand/optimizable_spec.rb +4 -2
  194. data/spec/unit/veritas/optimizer/{logic → function}/connective/binary/redundant_right_operand/optimize_spec.rb +4 -2
  195. data/spec/unit/veritas/optimizer/{logic → function}/connective/binary/right_spec.rb +3 -1
  196. data/spec/unit/veritas/optimizer/function/connective/conjunction/contradiction/optimizable_spec.rb +64 -0
  197. data/spec/unit/veritas/optimizer/function/connective/conjunction/contradiction/optimize_spec.rb +19 -0
  198. data/spec/unit/veritas/optimizer/{logic/connective/disjunction/contradiction_left_operand → function/connective/conjunction/left_operand_tautology}/optimizable_spec.rb +9 -7
  199. data/spec/unit/veritas/optimizer/{logic → function}/connective/conjunction/left_operand_tautology/optimize_spec.rb +8 -6
  200. data/spec/unit/veritas/optimizer/{logic → function}/connective/conjunction/optimizable_to_exclusion/optimizable_spec.rb +4 -2
  201. data/spec/unit/veritas/optimizer/{logic → function}/connective/conjunction/optimizable_to_exclusion/optimize_spec.rb +5 -3
  202. data/spec/unit/veritas/optimizer/{logic → function}/connective/conjunction/right_operand_tautology/optimizable_spec.rb +6 -4
  203. data/spec/unit/veritas/optimizer/function/connective/conjunction/right_operand_tautology/optimize_spec.rb +19 -0
  204. data/spec/unit/veritas/optimizer/{logic/connective/conjunction/left_operand_tautology → function/connective/disjunction/contradiction_left_operand}/optimizable_spec.rb +9 -7
  205. data/spec/unit/veritas/optimizer/{logic → function}/connective/disjunction/contradiction_left_operand/optimize_spec.rb +8 -6
  206. data/spec/unit/veritas/optimizer/{logic → function}/connective/disjunction/contradiction_right_operand/optimizable_spec.rb +6 -4
  207. data/spec/unit/veritas/optimizer/{logic → function}/connective/disjunction/contradiction_right_operand/optimize_spec.rb +8 -6
  208. data/spec/unit/veritas/optimizer/{logic → function}/connective/disjunction/optimizable_to_inclusion/optimizable_spec.rb +4 -2
  209. data/spec/unit/veritas/optimizer/{logic → function}/connective/disjunction/optimizable_to_inclusion/optimize_spec.rb +5 -3
  210. data/spec/unit/veritas/optimizer/function/connective/disjunction/tautology/optimizable_spec.rb +64 -0
  211. data/spec/unit/veritas/optimizer/function/connective/disjunction/tautology/optimize_spec.rb +19 -0
  212. data/spec/unit/veritas/optimizer/function/connective/negation/constant_operand/optimize_spec.rb +16 -0
  213. data/spec/unit/veritas/optimizer/function/connective/negation/invertible_operand/optimizable_spec.rb +28 -0
  214. data/spec/unit/veritas/optimizer/function/connective/negation/invertible_operand/optimize_spec.rb +22 -0
  215. data/spec/unit/veritas/optimizer/{logic → function}/connective/negation/operand_spec.rb +3 -1
  216. data/spec/unit/veritas/optimizer/{logic → function}/predicate/comparable/never_comparable/optimizable_spec.rb +23 -7
  217. data/spec/unit/veritas/optimizer/{logic → function}/predicate/comparable/never_equivalent/optimizable_spec.rb +23 -7
  218. data/spec/unit/veritas/optimizer/{logic → function}/predicate/comparable/normalizable_operands/optimizable_spec.rb +7 -5
  219. data/spec/unit/veritas/optimizer/{logic → function}/predicate/comparable/normalizable_operands/optimize_spec.rb +7 -5
  220. data/spec/unit/veritas/optimizer/function/predicate/constant_operands/optimize_spec.rb +16 -0
  221. data/spec/unit/veritas/optimizer/function/predicate/contradiction/optimize_spec.rb +18 -0
  222. data/spec/unit/veritas/optimizer/function/predicate/enumerable/class_methods/sort_by_value_spec.rb +27 -0
  223. data/spec/unit/veritas/optimizer/{logic → function}/predicate/enumerable/empty_right_operand/optimizable_spec.rb +6 -4
  224. data/spec/unit/veritas/optimizer/{logic → function}/predicate/enumerable/one_right_operand/optimizable_spec.rb +9 -7
  225. data/spec/unit/veritas/optimizer/{logic/predicate/enumerable/unoptimized_operand → function/predicate/enumerable/unoptimized_operands}/optimizable_spec.rb +4 -2
  226. data/spec/unit/veritas/optimizer/{logic/predicate/enumerable/unoptimized_operand → function/predicate/enumerable/unoptimized_operands}/optimize_spec.rb +18 -5
  227. data/spec/unit/veritas/optimizer/{logic → function}/predicate/equality/tautology/optimizable_spec.rb +4 -2
  228. data/spec/unit/veritas/optimizer/{logic → function}/predicate/exclusion/empty_right_operand/optimize_spec.rb +8 -6
  229. data/spec/unit/veritas/optimizer/{logic → function}/predicate/exclusion/one_right_operand/optimize_spec.rb +8 -6
  230. data/spec/unit/veritas/optimizer/{logic → function}/predicate/greater_than/contradiction/optimizable_spec.rb +4 -2
  231. data/spec/unit/veritas/optimizer/{logic → function}/predicate/greater_than/tautology/optimizable_spec.rb +4 -2
  232. data/spec/unit/veritas/optimizer/{logic → function}/predicate/greater_than_or_equal_to/contradiction/optimizable_spec.rb +4 -2
  233. data/spec/unit/veritas/optimizer/{logic → function}/predicate/greater_than_or_equal_to/tautology/optimizable_spec.rb +4 -2
  234. data/spec/unit/veritas/optimizer/{logic → function}/predicate/inclusion/empty_right_operand/optimize_spec.rb +8 -6
  235. data/spec/unit/veritas/optimizer/{logic → function}/predicate/inclusion/one_right_operand/optimize_spec.rb +8 -6
  236. data/spec/unit/veritas/optimizer/{logic → function}/predicate/inequality/contradiction/optimizable_spec.rb +4 -2
  237. data/spec/unit/veritas/optimizer/{logic → function}/predicate/less_than/contradiction/optimizable_spec.rb +4 -2
  238. data/spec/unit/veritas/optimizer/{logic → function}/predicate/less_than/tautology/optimizable_spec.rb +4 -2
  239. data/spec/unit/veritas/optimizer/{logic → function}/predicate/less_than_or_equal_to/contradiction/optimizable_spec.rb +4 -2
  240. data/spec/unit/veritas/optimizer/{logic → function}/predicate/less_than_or_equal_to/tautology/optimizable_spec.rb +4 -2
  241. data/spec/unit/veritas/optimizer/function/predicate/tautology/optimize_spec.rb +18 -0
  242. data/spec/unit/veritas/optimizer/function/unary/constant_operand/optimizable_spec.rb +27 -0
  243. data/spec/unit/veritas/optimizer/function/unary/constant_operand/optimize_spec.rb +18 -0
  244. data/spec/unit/veritas/optimizer/function/unary/operand_spec.rb +27 -0
  245. data/spec/unit/veritas/optimizer/function/unary/unoptimized_operand/optimizable_spec.rb +27 -0
  246. data/spec/unit/veritas/optimizer/function/unary/unoptimized_operand/optimize_spec.rb +18 -0
  247. data/spec/unit/veritas/optimizer/{logic/predicate → function}/util/class_methods/attribute_spec.rb +4 -2
  248. data/spec/unit/veritas/optimizer/{logic/predicate → function}/util/class_methods/constant_spec.rb +13 -5
  249. data/spec/unit/veritas/optimizer/function/util/class_methods/max_spec.rb +27 -0
  250. data/spec/unit/veritas/optimizer/function/util/class_methods/min_spec.rb +27 -0
  251. data/spec/unit/veritas/optimizer/operation_spec.rb +2 -0
  252. data/spec/unit/veritas/optimizer/optimizable/class_methods/optimizer_spec.rb +2 -0
  253. data/spec/unit/veritas/optimizer/optimizable/optimize_spec.rb +3 -1
  254. data/spec/unit/veritas/optimizer/optimizable_spec.rb +2 -0
  255. data/spec/unit/veritas/optimizer/optimize_spec.rb +2 -0
  256. data/spec/unit/veritas/optimizer/relation/materialized/empty_operand/optimizable_spec.rb +2 -0
  257. data/spec/unit/veritas/optimizer/relation/materialized/empty_operand/optimize_spec.rb +2 -0
  258. data/spec/unit/veritas/optimizer/relation/operation/binary/empty_left/optimizable_spec.rb +2 -4
  259. data/spec/unit/veritas/optimizer/relation/operation/binary/empty_right/optimizable_spec.rb +2 -4
  260. data/spec/unit/veritas/optimizer/relation/operation/binary/equal_operands/optimizable_spec.rb +2 -5
  261. data/spec/unit/veritas/optimizer/relation/operation/binary/left_order_operand/optimizable_spec.rb +23 -0
  262. data/spec/unit/veritas/optimizer/relation/operation/binary/left_order_operand/optimize_spec.rb +23 -0
  263. data/spec/unit/veritas/optimizer/relation/operation/binary/left_spec.rb +2 -4
  264. data/spec/unit/veritas/optimizer/relation/operation/binary/materialized_operand/optimizable_spec.rb +2 -0
  265. data/spec/unit/veritas/optimizer/relation/operation/binary/materialized_operand/optimize_spec.rb +2 -0
  266. data/spec/unit/veritas/optimizer/relation/operation/binary/right_order_operand/optimizable_spec.rb +23 -0
  267. data/spec/unit/veritas/optimizer/relation/operation/binary/right_order_operand/optimize_spec.rb +23 -0
  268. data/spec/unit/veritas/optimizer/relation/operation/binary/right_spec.rb +2 -4
  269. data/spec/unit/veritas/optimizer/relation/operation/binary/{unoptimized_operand → unoptimized_operands}/optimizable_spec.rb +3 -1
  270. data/spec/unit/veritas/optimizer/relation/operation/binary/{unoptimized_operand → unoptimized_operands}/optimize_spec.rb +3 -1
  271. data/spec/unit/veritas/optimizer/relation/operation/combination/optimize_spec.rb +2 -0
  272. data/spec/unit/veritas/optimizer/relation/operation/limit/equal_limit_operand/optimizable_spec.rb +2 -0
  273. data/spec/unit/veritas/optimizer/relation/operation/limit/equal_limit_operand/optimize_spec.rb +2 -0
  274. data/spec/unit/veritas/optimizer/relation/operation/limit/limit_operand/optimizable_spec.rb +2 -0
  275. data/spec/unit/veritas/optimizer/relation/operation/limit/limit_operand/optimize_spec.rb +2 -0
  276. data/spec/unit/veritas/optimizer/relation/operation/limit/unoptimized_operand/optimizable_spec.rb +2 -0
  277. data/spec/unit/veritas/optimizer/relation/operation/limit/unoptimized_operand/optimize_spec.rb +2 -0
  278. data/spec/unit/veritas/optimizer/relation/operation/limit/zero_limit/optimizable_spec.rb +2 -0
  279. data/spec/unit/veritas/optimizer/relation/operation/limit/zero_limit/optimize_spec.rb +2 -0
  280. data/spec/unit/veritas/optimizer/relation/operation/offset/offset_operand/optimizable_spec.rb +2 -0
  281. data/spec/unit/veritas/optimizer/relation/operation/offset/offset_operand/optimize_spec.rb +2 -0
  282. data/spec/unit/veritas/optimizer/relation/operation/offset/unoptimized_operand/optimizable_spec.rb +2 -0
  283. data/spec/unit/veritas/optimizer/relation/operation/offset/unoptimized_operand/optimize_spec.rb +2 -0
  284. data/spec/unit/veritas/optimizer/relation/operation/offset/zero_offset/optimizable_spec.rb +2 -0
  285. data/spec/unit/veritas/optimizer/relation/operation/offset/zero_offset/optimize_spec.rb +2 -0
  286. data/spec/unit/veritas/optimizer/relation/operation/order/one_limit_operand/optimizable_spec.rb +2 -0
  287. data/spec/unit/veritas/optimizer/relation/operation/order/one_limit_operand/optimize_spec.rb +2 -0
  288. data/spec/unit/veritas/optimizer/relation/operation/order/order_operand/optimizable_spec.rb +2 -0
  289. data/spec/unit/veritas/optimizer/relation/operation/order/order_operand/optimize_spec.rb +3 -1
  290. data/spec/unit/veritas/optimizer/relation/operation/order/unoptimized_operand/optimizable_spec.rb +2 -0
  291. data/spec/unit/veritas/optimizer/relation/operation/order/unoptimized_operand/optimize_spec.rb +2 -0
  292. data/spec/unit/veritas/optimizer/relation/operation/reverse/order_operand/optimizable_spec.rb +2 -0
  293. data/spec/unit/veritas/optimizer/relation/operation/reverse/order_operand/optimize_spec.rb +2 -0
  294. data/spec/unit/veritas/optimizer/relation/operation/reverse/reverse_operand/optimizable_spec.rb +2 -0
  295. data/spec/unit/veritas/optimizer/relation/operation/reverse/reverse_operand/optimize_spec.rb +2 -0
  296. data/spec/unit/veritas/optimizer/relation/operation/reverse/unoptimized_operand/optimizable_spec.rb +2 -0
  297. data/spec/unit/veritas/optimizer/relation/operation/reverse/unoptimized_operand/optimize_spec.rb +2 -0
  298. data/spec/unit/veritas/optimizer/relation/operation/unary/empty_operand/optimizable_spec.rb +5 -2
  299. data/spec/unit/veritas/optimizer/relation/operation/unary/empty_operand/optimize_spec.rb +2 -0
  300. data/spec/unit/veritas/optimizer/relation/operation/unary/header_spec.rb +15 -0
  301. data/spec/unit/veritas/optimizer/relation/operation/unary/materialized_operand/optimizable_spec.rb +5 -2
  302. data/spec/unit/veritas/optimizer/relation/operation/unary/materialized_operand/optimize_spec.rb +2 -0
  303. data/spec/unit/veritas/optimizer/relation/operation/unary/operand_spec.rb +8 -5
  304. data/spec/unit/veritas/optimizer/relation/operation/unary/order_operand/optimizable_spec.rb +28 -0
  305. data/spec/unit/veritas/optimizer/relation/operation/unary/order_operand/optimize_spec.rb +27 -0
  306. data/spec/unit/veritas/optimizer/relation/operation/unary/unchanged_header/optimizable_spec.rb +24 -0
  307. data/spec/unit/veritas/optimizer/relation/operation/unary/unchanged_header/optimize_spec.rb +14 -0
  308. data/tasks/metrics/ci.rake +7 -0
  309. data/tasks/{quality → metrics}/flay.rake +0 -0
  310. data/tasks/{quality → metrics}/flog.rake +0 -0
  311. data/tasks/{quality → metrics}/heckle.rake +1 -0
  312. data/tasks/{quality → metrics}/metric_fu.rake +3 -0
  313. data/tasks/{quality → metrics}/reek.rake +0 -0
  314. data/tasks/{quality → metrics}/roodi.rake +0 -0
  315. data/tasks/{quality → metrics}/yardstick.rake +0 -0
  316. data/tasks/spec.rake +1 -0
  317. data/veritas-optimizer.gemspec +183 -352
  318. metadata +232 -357
  319. data/lib/veritas/optimizer/logic/connective/negation.rb +0 -71
  320. data/lib/veritas/optimizer/logic/predicate.rb +0 -177
  321. data/spec/unit/veritas/optimizer/algebra/projection/header_spec.rb +0 -16
  322. data/spec/unit/veritas/optimizer/algebra/projection/unchanged_header/optimizable_spec.rb +0 -26
  323. data/spec/unit/veritas/optimizer/algebra/projection/unchanged_header/optimize_spec.rb +0 -16
  324. data/spec/unit/veritas/optimizer/algebra/rename/class_methods/union_aliases_spec.rb +0 -27
  325. data/spec/unit/veritas/optimizer/algebra/rename/header_spec.rb +0 -19
  326. data/spec/unit/veritas/optimizer/algebra/rename/unchanged_header/optimizable_spec.rb +0 -26
  327. data/spec/unit/veritas/optimizer/algebra/rename/unchanged_header/optimize_spec.rb +0 -16
  328. data/spec/unit/veritas/optimizer/algebra/restriction/class_methods/optimize_predicate_spec.rb +0 -31
  329. data/spec/unit/veritas/optimizer/algebra/restriction/reverse_operand/optimizable_spec.rb +0 -26
  330. data/spec/unit/veritas/optimizer/algebra/restriction/reverse_operand/optimize_spec.rb +0 -18
  331. data/spec/unit/veritas/optimizer/logic/connective/binary/unoptimized_operand/optimizable_spec.rb +0 -34
  332. data/spec/unit/veritas/optimizer/logic/connective/binary/unoptimized_operand/optimize_spec.rb +0 -21
  333. data/spec/unit/veritas/optimizer/logic/connective/conjunction/contradiction/optimizable_spec.rb +0 -41
  334. data/spec/unit/veritas/optimizer/logic/connective/conjunction/contradiction/optimize_spec.rb +0 -17
  335. data/spec/unit/veritas/optimizer/logic/connective/conjunction/right_operand_tautology/optimize_spec.rb +0 -17
  336. data/spec/unit/veritas/optimizer/logic/connective/disjunction/tautology/optimizable_spec.rb +0 -41
  337. data/spec/unit/veritas/optimizer/logic/connective/disjunction/tautology/optimize_spec.rb +0 -17
  338. data/spec/unit/veritas/optimizer/logic/connective/negation/invertible_operand/optimizable_spec.rb +0 -26
  339. data/spec/unit/veritas/optimizer/logic/connective/negation/invertible_operand/optimize_spec.rb +0 -20
  340. data/spec/unit/veritas/optimizer/logic/predicate/class_methods/optimize_operand_spec.rb +0 -20
  341. data/spec/unit/veritas/optimizer/logic/predicate/constant_operands/optimizable_spec.rb +0 -29
  342. data/spec/unit/veritas/optimizer/logic/predicate/constant_operands/optimize_spec.rb +0 -14
  343. data/spec/unit/veritas/optimizer/logic/predicate/contradiction/optimize_spec.rb +0 -16
  344. data/spec/unit/veritas/optimizer/logic/predicate/left_spec.rb +0 -25
  345. data/spec/unit/veritas/optimizer/logic/predicate/right_spec.rb +0 -25
  346. data/spec/unit/veritas/optimizer/logic/predicate/tautology/optimize_spec.rb +0 -16
  347. data/spec/unit/veritas/optimizer/logic/predicate/util/class_methods/max_spec.rb +0 -19
  348. data/spec/unit/veritas/optimizer/logic/predicate/util/class_methods/min_spec.rb +0 -19
  349. data/tasks/quality/ci.rake +0 -2
@@ -7,13 +7,6 @@ module Veritas
7
7
  # Abstract base class representing Rename optimizations
8
8
  class Rename < Relation::Operation::Unary
9
9
 
10
- # The renamed header
11
- #
12
- # @return [Header]
13
- #
14
- # @api private
15
- attr_reader :header
16
-
17
10
  # The optimized aliases
18
11
  #
19
12
  # @return [Rename::Aliases]
@@ -30,8 +23,7 @@ module Veritas
30
23
  # @api private
31
24
  def initialize(operation)
32
25
  super
33
- @header = operation.header
34
- @aliases = self.class.union_aliases(operation.aliases, operand)
26
+ @aliases = operation.aliases
35
27
  end
36
28
 
37
29
  private
@@ -41,53 +33,46 @@ module Veritas
41
33
  # @return [Rename]
42
34
  #
43
35
  # @api private
44
- def wrap_operand
45
- operation.class.new(operand.operand, aliases)
36
+ def wrap_operand(operand = operand.operand)
37
+ operation.class.new(operand, aliases)
46
38
  end
47
39
 
48
- # Union the operation aliases with any operand aliases
49
- #
50
- # @param [Rename::Aliases]
51
- # the original aliases
52
- # @param [Relation]
53
- # the operand
54
- #
55
- # @return [Rename::Aliases]
56
- #
57
- # @api private
58
- def self.union_aliases(aliases, operand)
59
- if operand.respond_to?(:aliases)
60
- aliases.union(operand.aliases)
61
- else
62
- aliases
63
- end
64
- end
65
-
66
- # Optimize when the headers are not changed
67
- class UnchangedHeader < self
40
+ # Optimize when the operand is a Rename
41
+ class RenameOperand < self
68
42
 
69
- # Test if the renamed headers are the same as the operand's
43
+ # Test if the operand is a Rename
70
44
  #
71
45
  # @return [Boolean]
72
46
  #
73
47
  # @api private
74
48
  def optimizable?
75
- header.to_a == operand.header.to_a
49
+ operand.kind_of?(operation.class)
76
50
  end
77
51
 
78
- # A Rename with unchanged headers is a noop
52
+ # Flatten nested Renames into a single Rename
79
53
  #
80
- # @return [Relation]
54
+ # @return [Projection]
81
55
  #
82
56
  # @api private
83
57
  def optimize
84
- operand
58
+ wrap_operand
85
59
  end
86
60
 
87
- end # class UnchangedHeader
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
88
73
 
89
74
  # Optimize when the operand is a Rename with aliases that cancel out
90
- class RenameOperandAndEmptyAliases < self
75
+ class RenameOperandAndEmptyAliases < RenameOperand
91
76
 
92
77
  # Test if the operand is a Rename with aliases that cancel out
93
78
  #
@@ -95,7 +80,7 @@ module Veritas
95
80
  #
96
81
  # @api private
97
82
  def optimizable?
98
- operand.kind_of?(operation.class) && aliases.empty?
83
+ super && aliases.empty?
99
84
  end
100
85
 
101
86
  # A Rename wrapping a Rename with aliases that cancel out is a noop
@@ -109,48 +94,56 @@ module Veritas
109
94
 
110
95
  end # class RenameOperandAndEmptyAliases
111
96
 
112
- # Optimize when the operand is a Rename
113
- class RenameOperand < self
97
+ # Optimize when the operand is a Projection
98
+ class ProjectionOperand < self
114
99
 
115
- # Test if the operand is a Rename
100
+ # Test if the operand is a Projection
116
101
  #
117
102
  # @return [Boolean]
118
103
  #
119
104
  # @api private
120
105
  def optimizable?
121
- operand.kind_of?(operation.class)
106
+ operand.kind_of?(Veritas::Algebra::Projection) && distributive?
122
107
  end
123
108
 
124
- # Flatten nested Renames into a single Rename
109
+ # Wrap the Rename in a Projection
125
110
  #
126
111
  # @return [Projection]
127
112
  #
128
113
  # @api private
129
114
  def optimize
130
- operation.class.new(operand.operand, aliases)
115
+ operand.class.new(wrap_operand, header)
131
116
  end
132
117
 
133
- end # class RenameOperand
134
-
135
- # Optimize when the operand is a Projection
136
- class ProjectionOperand < self
118
+ private
137
119
 
138
- # Test if the operand is a Projection
120
+ # Test if the rename can be distributed over the projection
139
121
  #
140
122
  # @return [Boolean]
141
123
  #
142
124
  # @api private
143
- def optimizable?
144
- operand.kind_of?(Veritas::Algebra::Projection)
125
+ def distributive?
126
+ names = alias_names
127
+ removed_attributes.all? { |attribute| !names.include?(attribute.name) }
145
128
  end
146
129
 
147
- # Wrap the Rename in a Projection
130
+ # Return the aliases as an inverted Hash
148
131
  #
149
- # @return [Projection]
132
+ # @return [Hash]
150
133
  #
151
134
  # @api private
152
- def optimize
153
- operand.class.new(wrap_operand, header)
135
+ def alias_names
136
+ aliases.to_hash.values.map { |attribute| attribute.name }
137
+ end
138
+
139
+ # Returns the attributes removed from the projection
140
+ #
141
+ # @return [#all?]
142
+ #
143
+ # @api private
144
+ def removed_attributes
145
+ operand = self.operand
146
+ operand.operand.header - operand.header
154
147
  end
155
148
 
156
149
  end # class ProjectionOperand
@@ -180,7 +173,7 @@ module Veritas
180
173
 
181
174
  # Rename the operand predicate
182
175
  #
183
- # @return [Expression]
176
+ # @return [Function]
184
177
  #
185
178
  # @api private
186
179
  def rename_predicate
@@ -218,7 +211,7 @@ module Veritas
218
211
  #
219
212
  # @api private
220
213
  def wrap_left
221
- operation.class.new(operand.left, aliases)
214
+ wrap_operand(operand.left)
222
215
  end
223
216
 
224
217
  # Utility method to wrap the right operand in a Rename
@@ -227,7 +220,7 @@ module Veritas
227
220
  #
228
221
  # @api private
229
222
  def wrap_right
230
- operation.class.new(operand.right, aliases)
223
+ wrap_operand(operand.right)
231
224
  end
232
225
 
233
226
  end # class SetOperand
@@ -257,15 +250,7 @@ module Veritas
257
250
 
258
251
  # Optimize when the operand is an Order
259
252
  class OrderOperand < self
260
-
261
- # Test if the operand is an Order
262
- #
263
- # @return [Boolean]
264
- #
265
- # @api private
266
- def optimizable?
267
- operand.kind_of?(Veritas::Relation::Operation::Order)
268
- end
253
+ include Relation::Operation::Unary::OrderOperand
269
254
 
270
255
  # Wrap the Rename in an Order
271
256
  #
@@ -351,17 +336,7 @@ module Veritas
351
336
 
352
337
  # Optimize when operand is optimizable
353
338
  class UnoptimizedOperand < self
354
-
355
- # Test if the operand is unoptimized
356
- #
357
- # @return [Boolean]
358
- #
359
- # @api private
360
- def optimizable?
361
- operation = self.operation
362
- !operand.equal?(operation.operand) ||
363
- !aliases.equal?(operation.aliases)
364
- end
339
+ include Function::Unary::UnoptimizedOperand
365
340
 
366
341
  # Return a Rename with an optimized operand
367
342
  #
@@ -369,7 +344,7 @@ module Veritas
369
344
  #
370
345
  # @api private
371
346
  def optimize
372
- operation.class.new(operand, aliases)
347
+ wrap_operand(operand)
373
348
  end
374
349
 
375
350
  end # class UnoptimizedOperand
@@ -9,7 +9,7 @@ module Veritas
9
9
 
10
10
  # The optimized predicate
11
11
  #
12
- # @return [Expression]
12
+ # @return [Function]
13
13
  #
14
14
  # @api private
15
15
  attr_reader :predicate
@@ -21,7 +21,7 @@ module Veritas
21
21
  # @api private
22
22
  def initialize(*)
23
23
  super
24
- @predicate = self.class.optimize_predicate(operation.predicate)
24
+ @predicate = Function.optimize_operand(operation.predicate)
25
25
  end
26
26
 
27
27
  private
@@ -31,19 +31,28 @@ module Veritas
31
31
  # @return [Restriction]
32
32
  #
33
33
  # @api private
34
- def wrap_operand
35
- operation.class.new(operand.operand, predicate)
34
+ def wrap_operand(operand = operand.operand)
35
+ operation.class.new(operand, predicate)
36
36
  end
37
37
 
38
- # Optimize the predicate if possible
38
+ # Return true if the predicate is a true value
39
39
  #
40
- # @param [Expression] predicate
40
+ # @return [Boolean]
41
41
  #
42
- # @return [Expression]
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]
43
52
  #
44
53
  # @api private
45
- def self.optimize_predicate(predicate)
46
- predicate.respond_to?(:optimize) ? predicate.optimize : predicate
54
+ def constant_false_predicate?
55
+ !(predicate.respond_to?(:call) || constant_true_predicate?)
47
56
  end
48
57
 
49
58
  # Optimize when the predicate is a tautology
@@ -55,7 +64,8 @@ module Veritas
55
64
  #
56
65
  # @api private
57
66
  def optimizable?
58
- predicate.equal?(Veritas::Logic::Proposition::Tautology.instance)
67
+ predicate.equal?(Veritas::Function::Proposition::Tautology.instance) ||
68
+ constant_true_predicate?
59
69
  end
60
70
 
61
71
  # A Restriction with a tautology is a noop
@@ -78,7 +88,8 @@ module Veritas
78
88
  #
79
89
  # @api private
80
90
  def optimizable?
81
- predicate.equal?(Veritas::Logic::Proposition::Contradiction.instance)
91
+ predicate.equal?(Veritas::Function::Proposition::Contradiction.instance) ||
92
+ constant_false_predicate?
82
93
  end
83
94
 
84
95
  # A Restriction with a contradiction matches nothing
@@ -106,22 +117,22 @@ module Veritas
106
117
 
107
118
  # Flatten nested Restrictions into a single Restriction
108
119
  #
109
- # @return [Projection]
120
+ # @return [Restriction]
110
121
  #
111
122
  # @api private
112
123
  def optimize
113
- operation.class.new(operand.operand, optimized_predicate)
124
+ wrap_operand
114
125
  end
115
126
 
116
127
  private
117
128
 
118
129
  # Join the operand and operation predicates and optimize them
119
130
  #
120
- # @return [Expression]
131
+ # @return [Function]
121
132
  #
122
133
  # @api private
123
- def optimized_predicate
124
- Veritas::Logic::Connective::Conjunction.new(operand.predicate, predicate).optimize
134
+ def predicate
135
+ Veritas::Function::Connective::Conjunction.new(operand.predicate, super).optimize
125
136
  end
126
137
 
127
138
  end # class RestrictionOperand
@@ -155,7 +166,7 @@ module Veritas
155
166
  #
156
167
  # @api private
157
168
  def wrap_left
158
- operation.class.new(operand.left, predicate)
169
+ wrap_operand(operand.left)
159
170
  end
160
171
 
161
172
  # Utility method to wrap the right operand in a Restriction
@@ -164,60 +175,19 @@ module Veritas
164
175
  #
165
176
  # @api private
166
177
  def wrap_right
167
- operation.class.new(operand.right, predicate)
178
+ wrap_operand(operand.right)
168
179
  end
169
180
 
170
181
  end # class SetOperand
171
182
 
172
- # Optimize when the operand is a Reverse
173
- class ReverseOperand < self
174
-
175
- # Test if the operand is a Reverse
176
- #
177
- # @return [Boolean]
178
- #
179
- # @api private
180
- def optimizable?
181
- operand.kind_of?(Veritas::Relation::Operation::Reverse)
182
- end
183
-
184
- # Wrap the Restriction in a Reverse
185
- #
186
- # @return [Reverse]
187
- #
188
- # @api private
189
- def optimize
190
- operand.class.new(wrap_operand)
191
- end
192
-
193
- end # class ReverseOperand
194
-
195
183
  # Optimize when the operand is an Order
196
184
  class OrderOperand < self
197
-
198
- # Test if the operand is an Order
199
- #
200
- # @return [Boolean]
201
- #
202
- # @api private
203
- def optimizable?
204
- operand.kind_of?(Veritas::Relation::Operation::Order)
205
- end
206
-
207
- # Wrap the Restriction in an Order
208
- #
209
- # @return [Order]
210
- #
211
- # @api private
212
- def optimize
213
- operand = self.operand
214
- operand.class.new(wrap_operand, operand.directions)
215
- end
216
-
185
+ include Relation::Operation::Unary::OrderOperand
217
186
  end # class OrderOperand
218
187
 
219
188
  # Optimize when operand is optimizable
220
189
  class UnoptimizedOperand < self
190
+ include Function::Unary::UnoptimizedOperand
221
191
 
222
192
  # Test if the operand is unoptimized
223
193
  #
@@ -225,9 +195,7 @@ module Veritas
225
195
  #
226
196
  # @api private
227
197
  def optimizable?
228
- operation = self.operation
229
- !operand.equal?(operation.operand) ||
230
- !predicate.equal?(operation.predicate)
198
+ super || !predicate.equal?(operation.predicate)
231
199
  end
232
200
 
233
201
  # Return a Restriction with an optimized operand
@@ -236,7 +204,7 @@ module Veritas
236
204
  #
237
205
  # @api private
238
206
  def optimize
239
- operation.class.new(operand, predicate)
207
+ wrap_operand(operand)
240
208
  end
241
209
 
242
210
  end # class UnoptimizedOperand
@@ -246,7 +214,6 @@ module Veritas
246
214
  Contradiction,
247
215
  RestrictionOperand,
248
216
  SetOperand,
249
- ReverseOperand,
250
217
  OrderOperand,
251
218
  EmptyOperand,
252
219
  MaterializedOperand,
@@ -7,8 +7,142 @@ module Veritas
7
7
  # Abstract base class representing Summarization optimizations
8
8
  class Summarization < Relation::Operation::Unary
9
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
+ operation.class.new(operand, 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?(Veritas::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
+ Veritas::Algebra::Extension.new(summarize_per, 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?(Veritas::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
+ Veritas::Relation::Empty.new(operation.header)
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
+
10
143
  # Optimize when operand is optimizable
11
144
  class UnoptimizedOperand < self
145
+ include Function::Unary::UnoptimizedOperand
12
146
 
13
147
  # Test if the operand is unoptimized
14
148
  #
@@ -16,7 +150,9 @@ module Veritas
16
150
  #
17
151
  # @api private
18
152
  def optimizable?
19
- !operand.equal?(operation.operand)
153
+ super ||
154
+ summarize_per_optimizable? ||
155
+ summarizers_optimizable?
20
156
  end
21
157
 
22
158
  # Return a Summarization with an optimized operand
@@ -25,13 +161,35 @@ module Veritas
25
161
  #
26
162
  # @api private
27
163
  def optimize
28
- operation = self.operation
29
- operation.class.new(operand, operation.summarize_by, operation.summarizers)
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)
30
185
  end
31
186
 
32
187
  end # class UnoptimizedOperand
33
188
 
34
189
  Veritas::Algebra::Summarization.optimizer = chain(
190
+ EmptyOperand,
191
+ EmptySummarizePer,
192
+ OrderOperand,
35
193
  MaterializedOperand,
36
194
  UnoptimizedOperand
37
195
  )
@@ -56,8 +56,10 @@ module Veritas
56
56
  EqualOperands,
57
57
  EmptyRight,
58
58
  EmptyLeft,
59
+ LeftOrderOperand,
60
+ RightOrderOperand,
59
61
  MaterializedOperand,
60
- UnoptimizedOperand
62
+ UnoptimizedOperands
61
63
  )
62
64
 
63
65
  end # class Union