veritas-optimizer 0.0.3 → 0.0.4

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 (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