veritas-optimizer 0.0.3

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 (279) hide show
  1. data/Gemfile +33 -0
  2. data/LICENSE +20 -0
  3. data/README.rdoc +27 -0
  4. data/Rakefile +25 -0
  5. data/TODO +75 -0
  6. data/config/flay.yml +3 -0
  7. data/config/flog.yml +2 -0
  8. data/config/roodi.yml +16 -0
  9. data/config/site.reek +91 -0
  10. data/config/yardstick.yml +2 -0
  11. data/lib/veritas/optimizer/algebra/difference.rb +66 -0
  12. data/lib/veritas/optimizer/algebra/extension.rb +42 -0
  13. data/lib/veritas/optimizer/algebra/intersection.rb +66 -0
  14. data/lib/veritas/optimizer/algebra/join.rb +44 -0
  15. data/lib/veritas/optimizer/algebra/product.rb +70 -0
  16. data/lib/veritas/optimizer/algebra/projection.rb +174 -0
  17. data/lib/veritas/optimizer/algebra/rename.rb +396 -0
  18. data/lib/veritas/optimizer/algebra/restriction.rb +259 -0
  19. data/lib/veritas/optimizer/algebra/summarization.rb +42 -0
  20. data/lib/veritas/optimizer/algebra/union.rb +66 -0
  21. data/lib/veritas/optimizer/logic/connective/binary.rb +254 -0
  22. data/lib/veritas/optimizer/logic/connective/conjunction.rb +122 -0
  23. data/lib/veritas/optimizer/logic/connective/disjunction.rb +122 -0
  24. data/lib/veritas/optimizer/logic/connective/negation.rb +71 -0
  25. data/lib/veritas/optimizer/logic/predicate/comparable.rb +134 -0
  26. data/lib/veritas/optimizer/logic/predicate/enumerable.rb +141 -0
  27. data/lib/veritas/optimizer/logic/predicate/equality.rb +44 -0
  28. data/lib/veritas/optimizer/logic/predicate/exclusion.rb +53 -0
  29. data/lib/veritas/optimizer/logic/predicate/greater_than.rb +54 -0
  30. data/lib/veritas/optimizer/logic/predicate/greater_than_or_equal_to.rb +56 -0
  31. data/lib/veritas/optimizer/logic/predicate/inclusion.rb +53 -0
  32. data/lib/veritas/optimizer/logic/predicate/inequality.rb +44 -0
  33. data/lib/veritas/optimizer/logic/predicate/less_than.rb +54 -0
  34. data/lib/veritas/optimizer/logic/predicate/less_than_or_equal_to.rb +56 -0
  35. data/lib/veritas/optimizer/logic/predicate/match.rb +19 -0
  36. data/lib/veritas/optimizer/logic/predicate/no_match.rb +19 -0
  37. data/lib/veritas/optimizer/logic/predicate.rb +177 -0
  38. data/lib/veritas/optimizer/optimizable.rb +59 -0
  39. data/lib/veritas/optimizer/relation/materialized.rb +40 -0
  40. data/lib/veritas/optimizer/relation/operation/binary.rb +168 -0
  41. data/lib/veritas/optimizer/relation/operation/combination.rb +33 -0
  42. data/lib/veritas/optimizer/relation/operation/limit.rb +149 -0
  43. data/lib/veritas/optimizer/relation/operation/offset.rb +114 -0
  44. data/lib/veritas/optimizer/relation/operation/order.rb +96 -0
  45. data/lib/veritas/optimizer/relation/operation/reverse.rb +94 -0
  46. data/lib/veritas/optimizer/relation/operation/unary.rb +88 -0
  47. data/lib/veritas/optimizer/version.rb +7 -0
  48. data/lib/veritas/optimizer.rb +136 -0
  49. data/lib/veritas-optimizer.rb +3 -0
  50. data/spec/integration/veritas/algebra/difference/optimize_spec.rb +152 -0
  51. data/spec/integration/veritas/algebra/intersection/optimize_spec.rb +152 -0
  52. data/spec/integration/veritas/algebra/join/optimize_spec.rb +110 -0
  53. data/spec/integration/veritas/algebra/product/optimize_spec.rb +176 -0
  54. data/spec/integration/veritas/algebra/projection/optimize_spec.rb +237 -0
  55. data/spec/integration/veritas/algebra/rename/optimize_spec.rb +440 -0
  56. data/spec/integration/veritas/algebra/restriction/optimize_spec.rb +216 -0
  57. data/spec/integration/veritas/algebra/union/optimize_spec.rb +192 -0
  58. data/spec/integration/veritas/logic/connective/conjunction/optimize_spec.rb +234 -0
  59. data/spec/integration/veritas/logic/connective/disjunction/optimize_spec.rb +235 -0
  60. data/spec/integration/veritas/logic/connective/negation/optimize_spec.rb +41 -0
  61. data/spec/integration/veritas/logic/expression/optimize_spec.rb +42 -0
  62. data/spec/integration/veritas/logic/predicate/equality/optimize_spec.rb +90 -0
  63. data/spec/integration/veritas/logic/predicate/exclusion/optimize_spec.rb +131 -0
  64. data/spec/integration/veritas/logic/predicate/greater_than/optimize_spec.rb +100 -0
  65. data/spec/integration/veritas/logic/predicate/greater_than_or_equal_to/optimize_spec.rb +100 -0
  66. data/spec/integration/veritas/logic/predicate/inclusion/optimize_spec.rb +131 -0
  67. data/spec/integration/veritas/logic/predicate/inequality/optimize_spec.rb +90 -0
  68. data/spec/integration/veritas/logic/predicate/less_than/optimize_spec.rb +100 -0
  69. data/spec/integration/veritas/logic/predicate/less_than_or_equal_to/optimize_spec.rb +100 -0
  70. data/spec/integration/veritas/relation/empty/optimize_spec.rb +11 -0
  71. data/spec/integration/veritas/relation/materialized/optimize_spec.rb +37 -0
  72. data/spec/integration/veritas/relation/operation/limit/optimize_spec.rb +140 -0
  73. data/spec/integration/veritas/relation/operation/offset/optimize_spec.rb +98 -0
  74. data/spec/integration/veritas/relation/operation/order/optimize_spec.rb +103 -0
  75. data/spec/integration/veritas/relation/operation/reverse/optimize_spec.rb +113 -0
  76. data/spec/integration/veritas/relation/optimize_spec.rb +33 -0
  77. data/spec/rcov.opts +6 -0
  78. data/spec/shared/idempotent_method_behavior.rb +5 -0
  79. data/spec/shared/logic_connective_binary_optimize_behavior.rb +100 -0
  80. data/spec/shared/optimize_method_behavior.rb +14 -0
  81. data/spec/spec.opts +3 -0
  82. data/spec/spec_helper.rb +16 -0
  83. data/spec/support/add_method_missing.rb +13 -0
  84. data/spec/unit/veritas/optimizer/algebra/difference/empty_left/optimize_spec.rb +17 -0
  85. data/spec/unit/veritas/optimizer/algebra/difference/empty_right/optimize_spec.rb +17 -0
  86. data/spec/unit/veritas/optimizer/algebra/difference/equal_operands/optimize_spec.rb +19 -0
  87. data/spec/unit/veritas/optimizer/algebra/extension/unoptimized_operand/optimizable_spec.rb +27 -0
  88. data/spec/unit/veritas/optimizer/algebra/extension/unoptimized_operand/optimize_spec.rb +25 -0
  89. data/spec/unit/veritas/optimizer/algebra/intersection/empty_left/optimize_spec.rb +17 -0
  90. data/spec/unit/veritas/optimizer/algebra/intersection/empty_right/optimize_spec.rb +17 -0
  91. data/spec/unit/veritas/optimizer/algebra/intersection/equal_operands/optimize_spec.rb +17 -0
  92. data/spec/unit/veritas/optimizer/algebra/join/equal_headers/optimizable_spec.rb +27 -0
  93. data/spec/unit/veritas/optimizer/algebra/join/equal_headers/optimize_spec.rb +21 -0
  94. data/spec/unit/veritas/optimizer/algebra/product/table_dee_left/optimizable_spec.rb +25 -0
  95. data/spec/unit/veritas/optimizer/algebra/product/table_dee_left/optimize_spec.rb +16 -0
  96. data/spec/unit/veritas/optimizer/algebra/product/table_dee_right/optimizable_spec.rb +25 -0
  97. data/spec/unit/veritas/optimizer/algebra/product/table_dee_right/optimize_spec.rb +16 -0
  98. data/spec/unit/veritas/optimizer/algebra/projection/empty_operand/optimizable_spec.rb +25 -0
  99. data/spec/unit/veritas/optimizer/algebra/projection/empty_operand/optimize_spec.rb +18 -0
  100. data/spec/unit/veritas/optimizer/algebra/projection/header_spec.rb +16 -0
  101. data/spec/unit/veritas/optimizer/algebra/projection/projection_operand/optimizable_spec.rb +26 -0
  102. data/spec/unit/veritas/optimizer/algebra/projection/projection_operand/optimize_spec.rb +20 -0
  103. data/spec/unit/veritas/optimizer/algebra/projection/set_operand/optimizable_spec.rb +27 -0
  104. data/spec/unit/veritas/optimizer/algebra/projection/set_operand/optimize_spec.rb +23 -0
  105. data/spec/unit/veritas/optimizer/algebra/projection/unchanged_header/optimizable_spec.rb +26 -0
  106. data/spec/unit/veritas/optimizer/algebra/projection/unchanged_header/optimize_spec.rb +16 -0
  107. data/spec/unit/veritas/optimizer/algebra/projection/unoptimized_operand/optimizable_spec.rb +26 -0
  108. data/spec/unit/veritas/optimizer/algebra/projection/unoptimized_operand/optimize_spec.rb +20 -0
  109. data/spec/unit/veritas/optimizer/algebra/rename/aliases_spec.rb +31 -0
  110. data/spec/unit/veritas/optimizer/algebra/rename/class_methods/union_aliases_spec.rb +27 -0
  111. data/spec/unit/veritas/optimizer/algebra/rename/empty_operand/optimizable_spec.rb +25 -0
  112. data/spec/unit/veritas/optimizer/algebra/rename/empty_operand/optimize_spec.rb +17 -0
  113. data/spec/unit/veritas/optimizer/algebra/rename/header_spec.rb +19 -0
  114. data/spec/unit/veritas/optimizer/algebra/rename/limit_operand/optimizable_spec.rb +26 -0
  115. data/spec/unit/veritas/optimizer/algebra/rename/limit_operand/optimize_spec.rb +21 -0
  116. data/spec/unit/veritas/optimizer/algebra/rename/offset_operand/optimizable_spec.rb +26 -0
  117. data/spec/unit/veritas/optimizer/algebra/rename/offset_operand/optimize_spec.rb +21 -0
  118. data/spec/unit/veritas/optimizer/algebra/rename/order_operand/optimizable_spec.rb +26 -0
  119. data/spec/unit/veritas/optimizer/algebra/rename/order_operand/optimize_spec.rb +20 -0
  120. data/spec/unit/veritas/optimizer/algebra/rename/projection_operand/optimizable_spec.rb +26 -0
  121. data/spec/unit/veritas/optimizer/algebra/rename/projection_operand/optimize_spec.rb +20 -0
  122. data/spec/unit/veritas/optimizer/algebra/rename/rename_operand/optimizable_spec.rb +28 -0
  123. data/spec/unit/veritas/optimizer/algebra/rename/rename_operand/optimize_spec.rb +20 -0
  124. data/spec/unit/veritas/optimizer/algebra/rename/rename_operand_and_empty_aliases/optimizable_spec.rb +35 -0
  125. data/spec/unit/veritas/optimizer/algebra/rename/rename_operand_and_empty_aliases/optimize_spec.rb +16 -0
  126. data/spec/unit/veritas/optimizer/algebra/rename/restriction_operand/optimizable_spec.rb +27 -0
  127. data/spec/unit/veritas/optimizer/algebra/rename/restriction_operand/optimize_spec.rb +21 -0
  128. data/spec/unit/veritas/optimizer/algebra/rename/reverse_operand/optimizable_spec.rb +25 -0
  129. data/spec/unit/veritas/optimizer/algebra/rename/reverse_operand/optimize_spec.rb +21 -0
  130. data/spec/unit/veritas/optimizer/algebra/rename/set_operand/optimizable_spec.rb +27 -0
  131. data/spec/unit/veritas/optimizer/algebra/rename/set_operand/optimize_spec.rb +21 -0
  132. data/spec/unit/veritas/optimizer/algebra/rename/unchanged_header/optimizable_spec.rb +26 -0
  133. data/spec/unit/veritas/optimizer/algebra/rename/unchanged_header/optimize_spec.rb +16 -0
  134. data/spec/unit/veritas/optimizer/algebra/rename/unoptimized_operand/optimizable_spec.rb +42 -0
  135. data/spec/unit/veritas/optimizer/algebra/rename/unoptimized_operand/optimize_spec.rb +21 -0
  136. data/spec/unit/veritas/optimizer/algebra/restriction/class_methods/optimize_predicate_spec.rb +31 -0
  137. data/spec/unit/veritas/optimizer/algebra/restriction/contradiction/optimizable_spec.rb +26 -0
  138. data/spec/unit/veritas/optimizer/algebra/restriction/contradiction/optimize_spec.rb +19 -0
  139. data/spec/unit/veritas/optimizer/algebra/restriction/order_operand/optimizable_spec.rb +26 -0
  140. data/spec/unit/veritas/optimizer/algebra/restriction/order_operand/optimize_spec.rb +18 -0
  141. data/spec/unit/veritas/optimizer/algebra/restriction/predicate_spec.rb +16 -0
  142. data/spec/unit/veritas/optimizer/algebra/restriction/restriction_operand/optimizable_spec.rb +28 -0
  143. data/spec/unit/veritas/optimizer/algebra/restriction/restriction_operand/optimize_spec.rb +22 -0
  144. data/spec/unit/veritas/optimizer/algebra/restriction/reverse_operand/optimizable_spec.rb +26 -0
  145. data/spec/unit/veritas/optimizer/algebra/restriction/reverse_operand/optimize_spec.rb +18 -0
  146. data/spec/unit/veritas/optimizer/algebra/restriction/set_operand/optimizable_spec.rb +28 -0
  147. data/spec/unit/veritas/optimizer/algebra/restriction/set_operand/optimize_spec.rb +22 -0
  148. data/spec/unit/veritas/optimizer/algebra/restriction/tautology/optimizable_spec.rb +25 -0
  149. data/spec/unit/veritas/optimizer/algebra/restriction/tautology/optimize_spec.rb +17 -0
  150. data/spec/unit/veritas/optimizer/algebra/restriction/unoptimized_operand/optimizable_spec.rb +42 -0
  151. data/spec/unit/veritas/optimizer/algebra/restriction/unoptimized_operand/optimize_spec.rb +22 -0
  152. data/spec/unit/veritas/optimizer/algebra/summarization/unoptimized_operand/optimizable_spec.rb +27 -0
  153. data/spec/unit/veritas/optimizer/algebra/summarization/unoptimized_operand/optimize_spec.rb +27 -0
  154. data/spec/unit/veritas/optimizer/algebra/union/empty_left/optimize_spec.rb +17 -0
  155. data/spec/unit/veritas/optimizer/algebra/union/empty_right/optimize_spec.rb +17 -0
  156. data/spec/unit/veritas/optimizer/algebra/union/equal_operands/optimize_spec.rb +17 -0
  157. data/spec/unit/veritas/optimizer/class_methods/chain_spec.rb +54 -0
  158. data/spec/unit/veritas/optimizer/logic/connective/binary/equal_operands/optimizable_spec.rb +27 -0
  159. data/spec/unit/veritas/optimizer/logic/connective/binary/equal_operands/optimize_spec.rb +17 -0
  160. data/spec/unit/veritas/optimizer/logic/connective/binary/left_spec.rb +14 -0
  161. data/spec/unit/veritas/optimizer/logic/connective/binary/redundant_left_operand/optimizable_spec.rb +26 -0
  162. data/spec/unit/veritas/optimizer/logic/connective/binary/redundant_left_operand/optimize_spec.rb +21 -0
  163. data/spec/unit/veritas/optimizer/logic/connective/binary/redundant_right_operand/optimizable_spec.rb +26 -0
  164. data/spec/unit/veritas/optimizer/logic/connective/binary/redundant_right_operand/optimize_spec.rb +21 -0
  165. data/spec/unit/veritas/optimizer/logic/connective/binary/right_spec.rb +14 -0
  166. data/spec/unit/veritas/optimizer/logic/connective/binary/unoptimized_operand/optimizable_spec.rb +34 -0
  167. data/spec/unit/veritas/optimizer/logic/connective/binary/unoptimized_operand/optimize_spec.rb +21 -0
  168. data/spec/unit/veritas/optimizer/logic/connective/conjunction/contradiction/optimizable_spec.rb +41 -0
  169. data/spec/unit/veritas/optimizer/logic/connective/conjunction/contradiction/optimize_spec.rb +17 -0
  170. data/spec/unit/veritas/optimizer/logic/connective/conjunction/left_operand_tautology/optimizable_spec.rb +27 -0
  171. data/spec/unit/veritas/optimizer/logic/connective/conjunction/left_operand_tautology/optimize_spec.rb +17 -0
  172. data/spec/unit/veritas/optimizer/logic/connective/conjunction/optimizable_to_exclusion/optimizable_spec.rb +27 -0
  173. data/spec/unit/veritas/optimizer/logic/connective/conjunction/optimizable_to_exclusion/optimize_spec.rb +36 -0
  174. data/spec/unit/veritas/optimizer/logic/connective/conjunction/right_operand_tautology/optimizable_spec.rb +27 -0
  175. data/spec/unit/veritas/optimizer/logic/connective/conjunction/right_operand_tautology/optimize_spec.rb +17 -0
  176. data/spec/unit/veritas/optimizer/logic/connective/disjunction/contradiction_left_operand/optimizable_spec.rb +27 -0
  177. data/spec/unit/veritas/optimizer/logic/connective/disjunction/contradiction_left_operand/optimize_spec.rb +17 -0
  178. data/spec/unit/veritas/optimizer/logic/connective/disjunction/contradiction_right_operand/optimizable_spec.rb +27 -0
  179. data/spec/unit/veritas/optimizer/logic/connective/disjunction/contradiction_right_operand/optimize_spec.rb +17 -0
  180. data/spec/unit/veritas/optimizer/logic/connective/disjunction/optimizable_to_inclusion/optimizable_spec.rb +27 -0
  181. data/spec/unit/veritas/optimizer/logic/connective/disjunction/optimizable_to_inclusion/optimize_spec.rb +36 -0
  182. data/spec/unit/veritas/optimizer/logic/connective/disjunction/tautology/optimizable_spec.rb +41 -0
  183. data/spec/unit/veritas/optimizer/logic/connective/disjunction/tautology/optimize_spec.rb +17 -0
  184. data/spec/unit/veritas/optimizer/logic/connective/negation/invertible_operand/optimizable_spec.rb +26 -0
  185. data/spec/unit/veritas/optimizer/logic/connective/negation/invertible_operand/optimize_spec.rb +20 -0
  186. data/spec/unit/veritas/optimizer/logic/connective/negation/operand_spec.rb +12 -0
  187. data/spec/unit/veritas/optimizer/logic/predicate/class_methods/optimize_operand_spec.rb +20 -0
  188. data/spec/unit/veritas/optimizer/logic/predicate/comparable/never_comparable/optimizable_spec.rb +58 -0
  189. data/spec/unit/veritas/optimizer/logic/predicate/comparable/never_equivalent/optimizable_spec.rb +58 -0
  190. data/spec/unit/veritas/optimizer/logic/predicate/comparable/normalizable_operands/optimizable_spec.rb +41 -0
  191. data/spec/unit/veritas/optimizer/logic/predicate/comparable/normalizable_operands/optimize_spec.rb +19 -0
  192. data/spec/unit/veritas/optimizer/logic/predicate/constant_operands/optimizable_spec.rb +29 -0
  193. data/spec/unit/veritas/optimizer/logic/predicate/constant_operands/optimize_spec.rb +14 -0
  194. data/spec/unit/veritas/optimizer/logic/predicate/contradiction/optimize_spec.rb +16 -0
  195. data/spec/unit/veritas/optimizer/logic/predicate/enumerable/empty_right_operand/optimizable_spec.rb +76 -0
  196. data/spec/unit/veritas/optimizer/logic/predicate/enumerable/one_right_operand/optimizable_spec.rb +76 -0
  197. data/spec/unit/veritas/optimizer/logic/predicate/enumerable/unoptimized_operand/optimizable_spec.rb +49 -0
  198. data/spec/unit/veritas/optimizer/logic/predicate/enumerable/unoptimized_operand/optimize_spec.rb +53 -0
  199. data/spec/unit/veritas/optimizer/logic/predicate/equality/tautology/optimizable_spec.rb +27 -0
  200. data/spec/unit/veritas/optimizer/logic/predicate/exclusion/empty_right_operand/optimize_spec.rb +43 -0
  201. data/spec/unit/veritas/optimizer/logic/predicate/exclusion/one_right_operand/optimize_spec.rb +63 -0
  202. data/spec/unit/veritas/optimizer/logic/predicate/greater_than/contradiction/optimizable_spec.rb +41 -0
  203. data/spec/unit/veritas/optimizer/logic/predicate/greater_than/tautology/optimizable_spec.rb +26 -0
  204. data/spec/unit/veritas/optimizer/logic/predicate/greater_than_or_equal_to/contradiction/optimizable_spec.rb +41 -0
  205. data/spec/unit/veritas/optimizer/logic/predicate/greater_than_or_equal_to/tautology/optimizable_spec.rb +41 -0
  206. data/spec/unit/veritas/optimizer/logic/predicate/inclusion/empty_right_operand/optimize_spec.rb +43 -0
  207. data/spec/unit/veritas/optimizer/logic/predicate/inclusion/one_right_operand/optimize_spec.rb +64 -0
  208. data/spec/unit/veritas/optimizer/logic/predicate/inequality/contradiction/optimizable_spec.rb +27 -0
  209. data/spec/unit/veritas/optimizer/logic/predicate/left_spec.rb +25 -0
  210. data/spec/unit/veritas/optimizer/logic/predicate/less_than/contradiction/optimizable_spec.rb +41 -0
  211. data/spec/unit/veritas/optimizer/logic/predicate/less_than/tautology/optimizable_spec.rb +26 -0
  212. data/spec/unit/veritas/optimizer/logic/predicate/less_than_or_equal_to/contradiction/optimizable_spec.rb +41 -0
  213. data/spec/unit/veritas/optimizer/logic/predicate/less_than_or_equal_to/tautology/optimizable_spec.rb +41 -0
  214. data/spec/unit/veritas/optimizer/logic/predicate/right_spec.rb +25 -0
  215. data/spec/unit/veritas/optimizer/logic/predicate/tautology/optimize_spec.rb +16 -0
  216. data/spec/unit/veritas/optimizer/logic/predicate/util/class_methods/attribute_spec.rb +19 -0
  217. data/spec/unit/veritas/optimizer/logic/predicate/util/class_methods/constant_spec.rb +19 -0
  218. data/spec/unit/veritas/optimizer/logic/predicate/util/class_methods/max_spec.rb +19 -0
  219. data/spec/unit/veritas/optimizer/logic/predicate/util/class_methods/min_spec.rb +19 -0
  220. data/spec/unit/veritas/optimizer/operation_spec.rb +11 -0
  221. data/spec/unit/veritas/optimizer/optimizable/class_methods/optimizer_spec.rb +32 -0
  222. data/spec/unit/veritas/optimizer/optimizable/optimize_spec.rb +36 -0
  223. data/spec/unit/veritas/optimizer/optimizable_spec.rb +15 -0
  224. data/spec/unit/veritas/optimizer/optimize_spec.rb +15 -0
  225. data/spec/unit/veritas/optimizer/relation/materialized/empty_operand/optimizable_spec.rb +20 -0
  226. data/spec/unit/veritas/optimizer/relation/materialized/empty_operand/optimize_spec.rb +17 -0
  227. data/spec/unit/veritas/optimizer/relation/operation/binary/empty_left/optimizable_spec.rb +30 -0
  228. data/spec/unit/veritas/optimizer/relation/operation/binary/empty_right/optimizable_spec.rb +30 -0
  229. data/spec/unit/veritas/optimizer/relation/operation/binary/equal_operands/optimizable_spec.rb +34 -0
  230. data/spec/unit/veritas/optimizer/relation/operation/binary/left_spec.rb +17 -0
  231. data/spec/unit/veritas/optimizer/relation/operation/binary/materialized_operand/optimizable_spec.rb +35 -0
  232. data/spec/unit/veritas/optimizer/relation/operation/binary/materialized_operand/optimize_spec.rb +20 -0
  233. data/spec/unit/veritas/optimizer/relation/operation/binary/right_spec.rb +17 -0
  234. data/spec/unit/veritas/optimizer/relation/operation/binary/unoptimized_operand/optimizable_spec.rb +38 -0
  235. data/spec/unit/veritas/optimizer/relation/operation/binary/unoptimized_operand/optimize_spec.rb +22 -0
  236. data/spec/unit/veritas/optimizer/relation/operation/combination/optimize_spec.rb +14 -0
  237. data/spec/unit/veritas/optimizer/relation/operation/limit/equal_limit_operand/optimizable_spec.rb +31 -0
  238. data/spec/unit/veritas/optimizer/relation/operation/limit/equal_limit_operand/optimize_spec.rb +16 -0
  239. data/spec/unit/veritas/optimizer/relation/operation/limit/limit_operand/optimizable_spec.rb +25 -0
  240. data/spec/unit/veritas/optimizer/relation/operation/limit/limit_operand/optimize_spec.rb +33 -0
  241. data/spec/unit/veritas/optimizer/relation/operation/limit/unoptimized_operand/optimizable_spec.rb +26 -0
  242. data/spec/unit/veritas/optimizer/relation/operation/limit/unoptimized_operand/optimize_spec.rb +20 -0
  243. data/spec/unit/veritas/optimizer/relation/operation/limit/zero_limit/optimizable_spec.rb +25 -0
  244. data/spec/unit/veritas/optimizer/relation/operation/limit/zero_limit/optimize_spec.rb +18 -0
  245. data/spec/unit/veritas/optimizer/relation/operation/offset/offset_operand/optimizable_spec.rb +25 -0
  246. data/spec/unit/veritas/optimizer/relation/operation/offset/offset_operand/optimize_spec.rb +19 -0
  247. data/spec/unit/veritas/optimizer/relation/operation/offset/unoptimized_operand/optimizable_spec.rb +26 -0
  248. data/spec/unit/veritas/optimizer/relation/operation/offset/unoptimized_operand/optimize_spec.rb +20 -0
  249. data/spec/unit/veritas/optimizer/relation/operation/offset/zero_offset/optimizable_spec.rb +25 -0
  250. data/spec/unit/veritas/optimizer/relation/operation/offset/zero_offset/optimize_spec.rb +15 -0
  251. data/spec/unit/veritas/optimizer/relation/operation/order/one_limit_operand/optimizable_spec.rb +31 -0
  252. data/spec/unit/veritas/optimizer/relation/operation/order/one_limit_operand/optimize_spec.rb +16 -0
  253. data/spec/unit/veritas/optimizer/relation/operation/order/order_operand/optimizable_spec.rb +25 -0
  254. data/spec/unit/veritas/optimizer/relation/operation/order/order_operand/optimize_spec.rb +20 -0
  255. data/spec/unit/veritas/optimizer/relation/operation/order/unoptimized_operand/optimizable_spec.rb +26 -0
  256. data/spec/unit/veritas/optimizer/relation/operation/order/unoptimized_operand/optimize_spec.rb +21 -0
  257. data/spec/unit/veritas/optimizer/relation/operation/reverse/order_operand/optimizable_spec.rb +25 -0
  258. data/spec/unit/veritas/optimizer/relation/operation/reverse/order_operand/optimize_spec.rb +20 -0
  259. data/spec/unit/veritas/optimizer/relation/operation/reverse/reverse_operand/optimizable_spec.rb +25 -0
  260. data/spec/unit/veritas/optimizer/relation/operation/reverse/reverse_operand/optimize_spec.rb +17 -0
  261. data/spec/unit/veritas/optimizer/relation/operation/reverse/unoptimized_operand/optimizable_spec.rb +25 -0
  262. data/spec/unit/veritas/optimizer/relation/operation/reverse/unoptimized_operand/optimize_spec.rb +22 -0
  263. data/spec/unit/veritas/optimizer/relation/operation/unary/empty_operand/optimizable_spec.rb +20 -0
  264. data/spec/unit/veritas/optimizer/relation/operation/unary/empty_operand/optimize_spec.rb +15 -0
  265. data/spec/unit/veritas/optimizer/relation/operation/unary/materialized_operand/optimizable_spec.rb +20 -0
  266. data/spec/unit/veritas/optimizer/relation/operation/unary/materialized_operand/optimize_spec.rb +18 -0
  267. data/spec/unit/veritas/optimizer/relation/operation/unary/operand_spec.rb +13 -0
  268. data/tasks/quality/ci.rake +2 -0
  269. data/tasks/quality/flay.rake +41 -0
  270. data/tasks/quality/flog.rake +45 -0
  271. data/tasks/quality/heckle.rake +203 -0
  272. data/tasks/quality/metric_fu.rake +26 -0
  273. data/tasks/quality/reek.rake +9 -0
  274. data/tasks/quality/roodi.rake +15 -0
  275. data/tasks/quality/yardstick.rake +23 -0
  276. data/tasks/spec.rake +38 -0
  277. data/tasks/yard.rake +9 -0
  278. data/veritas-optimizer.gemspec +550 -0
  279. metadata +613 -0
@@ -0,0 +1,88 @@
1
+ # encoding: utf-8
2
+
3
+ module Veritas
4
+ class Optimizer
5
+ module Relation
6
+ module Operation
7
+
8
+ # Abstract base class representing Unary relation optimizations
9
+ class Unary < Optimizer
10
+
11
+ # The optimized operand
12
+ #
13
+ # @return [Relation]
14
+ #
15
+ # @api private
16
+ attr_reader :operand
17
+
18
+ # Initialize a Unary optimizer
19
+ #
20
+ # @return [undefined]
21
+ #
22
+ # @api private
23
+ def initialize(*)
24
+ super
25
+ @operand = optimize_operand
26
+ end
27
+
28
+ private
29
+
30
+ # Optimize the operand
31
+ #
32
+ # @return [Relation]
33
+ #
34
+ # @api private
35
+ def optimize_operand
36
+ operation.operand.optimize
37
+ end
38
+
39
+ # Optimize when the operand is Empty
40
+ class EmptyOperand < self
41
+
42
+ # Test if the operand is empty
43
+ #
44
+ # @return [Boolean]
45
+ #
46
+ # @api private
47
+ def optimizable?
48
+ operand.kind_of?(Veritas::Relation::Empty)
49
+ end
50
+
51
+ # A Unary operation on an empty operand is empty
52
+ #
53
+ # @return [Relation::Empty]
54
+ #
55
+ # @api private
56
+ def optimize
57
+ operand
58
+ end
59
+
60
+ end # class EmptyOperand
61
+
62
+ # Optimize when the operand is Materialized
63
+ class MaterializedOperand < self
64
+
65
+ # Test if the operand is materialized
66
+ #
67
+ # @return [Boolean]
68
+ #
69
+ # @api private
70
+ def optimizable?
71
+ operand.kind_of?(Veritas::Relation::Materialized)
72
+ end
73
+
74
+ # Return the materialized operation
75
+ #
76
+ # @return [Relation::Materialized]
77
+ #
78
+ # @api private
79
+ def optimize
80
+ operation.materialize
81
+ end
82
+
83
+ end # class MaterializedOperand
84
+ end # class Unary
85
+ end # module Operation
86
+ end # module Relation
87
+ end # class Optimizer
88
+ end # module Veritas
@@ -0,0 +1,7 @@
1
+ # encoding: utf-8
2
+
3
+ module Veritas
4
+ class Optimizer
5
+ VERSION = '0.0.3'
6
+ end # class Optimizer
7
+ end # module Veritas
@@ -0,0 +1,136 @@
1
+ # encoding: utf-8
2
+
3
+ require 'veritas'
4
+
5
+ module Veritas
6
+
7
+ # A optimization for an operation
8
+ class Optimizer
9
+ include AbstractClass, Immutable
10
+
11
+ # A noop optimizer that returns the operation as-is
12
+ Noop = lambda { |operation| operation }.freeze
13
+
14
+ # The operation to optimize
15
+ #
16
+ # @return [Optimizable]
17
+ #
18
+ # @api private
19
+ attr_reader :operation
20
+
21
+ # Initialize an Optimizer
22
+ #
23
+ # @param [Optimizable] operation
24
+ # the operation to optimize
25
+ #
26
+ # @return [undefined]
27
+ #
28
+ # @api private
29
+ def initialize(operation)
30
+ @operation = operation
31
+ end
32
+
33
+ # Abstract method that tests if the optimization should be applied
34
+ #
35
+ # @example
36
+ # optimizer.optimizable? # => true or false
37
+ #
38
+ # @return [Boolean]
39
+ #
40
+ # @api public
41
+ def optimizable?
42
+ raise NotImplementedError, "#{self.class}#optimizable? must be implemented"
43
+ end
44
+
45
+ # Abstract method that executes the optimization for the operation
46
+ #
47
+ # @example
48
+ # optimized = optimizer.optimize
49
+ #
50
+ # @return [Optimizable]
51
+ #
52
+ # @api public
53
+ def optimize
54
+ raise NotImplementedError, "#{self.class}#optimize must be implemented"
55
+ end
56
+
57
+ # Chain together a list of optimizer classes into a callable object
58
+ #
59
+ # @example
60
+ # Optimizer.chain(Optimizer::Foo, Optimizer::Bar)
61
+ #
62
+ # @param [Array<Class<Optimizer>>] *optimizers
63
+ # a list of optimizer classes to apply
64
+ #
65
+ # @return [#call]
66
+ #
67
+ # @api public
68
+ def self.chain(*optimizers)
69
+ optimizers.reverse_each.reduce(Noop) do |successor, optimizer|
70
+ link_optimizers(optimizer, successor)
71
+ end
72
+ end
73
+
74
+ # Link an optimizer to a successor
75
+ #
76
+ # @param [Class<Optimizer>] optimizer
77
+ # the optimizer to link to the successor
78
+ # @param [#proc] successor
79
+ # the next optimizer to call if the current optimizer is not applied
80
+ #
81
+ # @return [#call]
82
+ #
83
+ # @api private
84
+ def self.link_optimizers(optimizer, successor)
85
+ lambda do |operation|
86
+ op = optimizer.new(operation)
87
+ op.optimizable? ? op.optimize : successor.call(operation)
88
+ end
89
+ end
90
+
91
+ private_class_method :link_optimizers
92
+
93
+ end # class Optimizer
94
+ end # module Veritas
95
+
96
+ require 'veritas/optimizer/version'
97
+
98
+ require 'veritas/optimizer/optimizable'
99
+
100
+ require 'veritas/optimizer/relation/materialized'
101
+
102
+ require 'veritas/optimizer/relation/operation/binary'
103
+ require 'veritas/optimizer/relation/operation/unary'
104
+ require 'veritas/optimizer/relation/operation/combination'
105
+ require 'veritas/optimizer/relation/operation/limit'
106
+ require 'veritas/optimizer/relation/operation/offset'
107
+ require 'veritas/optimizer/relation/operation/order'
108
+ require 'veritas/optimizer/relation/operation/reverse'
109
+
110
+ require 'veritas/optimizer/algebra/difference'
111
+ require 'veritas/optimizer/algebra/extension'
112
+ require 'veritas/optimizer/algebra/intersection'
113
+ require 'veritas/optimizer/algebra/join'
114
+ require 'veritas/optimizer/algebra/product'
115
+ require 'veritas/optimizer/algebra/projection'
116
+ require 'veritas/optimizer/algebra/rename'
117
+ require 'veritas/optimizer/algebra/restriction'
118
+ require 'veritas/optimizer/algebra/summarization'
119
+ require 'veritas/optimizer/algebra/union'
120
+
121
+ require 'veritas/optimizer/logic/connective/binary'
122
+ require 'veritas/optimizer/logic/connective/conjunction'
123
+ require 'veritas/optimizer/logic/connective/disjunction'
124
+ require 'veritas/optimizer/logic/connective/negation'
125
+
126
+ require 'veritas/optimizer/logic/predicate'
127
+ require 'veritas/optimizer/logic/predicate/comparable'
128
+ require 'veritas/optimizer/logic/predicate/enumerable'
129
+ require 'veritas/optimizer/logic/predicate/equality'
130
+ require 'veritas/optimizer/logic/predicate/exclusion'
131
+ require 'veritas/optimizer/logic/predicate/greater_than'
132
+ require 'veritas/optimizer/logic/predicate/greater_than_or_equal_to'
133
+ require 'veritas/optimizer/logic/predicate/inequality'
134
+ require 'veritas/optimizer/logic/predicate/inclusion'
135
+ require 'veritas/optimizer/logic/predicate/less_than'
136
+ require 'veritas/optimizer/logic/predicate/less_than_or_equal_to'
@@ -0,0 +1,3 @@
1
+ # encoding: utf-8
2
+
3
+ require 'veritas/optimizer'
@@ -0,0 +1,152 @@
1
+ require 'spec_helper'
2
+
3
+ describe Algebra::Difference, '#optimize' do
4
+ subject { object.optimize }
5
+
6
+ let(:header) { [ [ :id, Integer ] ] }
7
+ let(:left_body) { [ [ 1 ] ].each }
8
+ let(:right_body) { [ [ 2 ] ].each }
9
+ let(:original_left) { Relation.new(header, left_body) }
10
+ let(:original_right) { Relation.new(header, right_body) }
11
+ let(:object) { described_class.new(left, right) }
12
+
13
+ context 'left is an empty relation' do
14
+ let(:left) { Relation::Empty.new(header) }
15
+ let(:right) { original_right }
16
+
17
+ it { should equal(left) }
18
+
19
+ it 'returns an equivalent relation to the unoptimized operation' do
20
+ should == object
21
+ end
22
+
23
+ it 'does not execute right_body#each' do
24
+ right_body.should_not_receive(:each)
25
+ subject
26
+ end
27
+
28
+ it_should_behave_like 'an optimize method'
29
+ end
30
+
31
+ context 'right is an empty relation' do
32
+ let(:left) { original_left }
33
+ let(:right) { Relation::Empty.new(header) }
34
+
35
+ it { should equal(left) }
36
+
37
+ it 'returns an equivalent relation to the unoptimized operation' do
38
+ should == object
39
+ end
40
+
41
+ it 'does not execute left_body#each' do
42
+ left_body.should_not_receive(:each)
43
+ subject
44
+ end
45
+
46
+ it_should_behave_like 'an optimize method'
47
+ end
48
+
49
+ context 'left is an empty relation when optimized' do
50
+ let(:left) { Algebra::Restriction.new(original_left, Logic::Proposition::Contradiction.instance) }
51
+ let(:right) { original_right }
52
+
53
+ it { should eql(Relation::Empty.new(left.header | right.header)) }
54
+
55
+ it 'returns an equivalent relation to the unoptimized operation' do
56
+ should == object
57
+ end
58
+
59
+ it 'does not execute left_body#each' do
60
+ left_body.should_not_receive(:each)
61
+ subject
62
+ end
63
+
64
+ it 'does not execute right_body#each' do
65
+ right_body.should_not_receive(:each)
66
+ subject
67
+ end
68
+
69
+ it_should_behave_like 'an optimize method'
70
+ end
71
+
72
+ context 'right is an empty relation when optimized' do
73
+ let(:left) { original_left }
74
+ let(:right) { Algebra::Restriction.new(original_right, Logic::Proposition::Contradiction.instance) }
75
+
76
+ it { should equal(left) }
77
+
78
+ it 'returns an equivalent relation to the unoptimized operation' do
79
+ should == object
80
+ end
81
+
82
+ it 'does not execute left_body#each' do
83
+ left_body.should_not_receive(:each)
84
+ subject
85
+ end
86
+
87
+ it 'does not execute right_body#each' do
88
+ right_body.should_not_receive(:each)
89
+ subject
90
+ end
91
+
92
+ it_should_behave_like 'an optimize method'
93
+ end
94
+
95
+ unless defined?(JRUBY_VERSION) && JRUBY_VERSION < '1.6'
96
+ context 'left and right are equivalent relations' do
97
+ let(:right_body) { left_body.dup }
98
+ let(:left) { original_left }
99
+ let(:right) { original_right }
100
+
101
+ it { should eql(Relation::Empty.new(header)) }
102
+
103
+ it 'returns an equivalent relation to the unoptimized operation' do
104
+ should == object
105
+ end
106
+
107
+ it 'executes left_body#each' do
108
+ left_body.should_receive(:each)
109
+ subject
110
+ end
111
+
112
+ it 'executes right_body#each' do
113
+ right_body.should_receive(:each)
114
+ subject
115
+ end
116
+
117
+ it_should_behave_like 'an optimize method'
118
+ end
119
+ end
120
+
121
+ context 'left and right are not empty relations' do
122
+ let(:left) { original_left }
123
+ let(:right) { original_right }
124
+
125
+ it { should equal(object) }
126
+
127
+ it 'executes left_body#each' do
128
+ left_body.should_receive(:each)
129
+ subject
130
+ end
131
+
132
+ it 'executes right_body#each' do
133
+ right_body.should_receive(:each)
134
+ subject
135
+ end
136
+
137
+ it_should_behave_like 'an optimize method'
138
+ end
139
+
140
+ context 'left and right are materialized relations' do
141
+ let(:left) { Relation.new(header, [ [ 1 ], [ 2 ] ]) }
142
+ let(:right) { Relation.new(header, [ [ 1 ] ]) }
143
+
144
+ it { should eql(Relation::Materialized.new(header, [ [ 2 ] ])) }
145
+
146
+ it 'returns an equivalent relation to the unoptimized operation' do
147
+ should == object
148
+ end
149
+
150
+ it_should_behave_like 'an optimize method'
151
+ end
152
+ end
@@ -0,0 +1,152 @@
1
+ require 'spec_helper'
2
+
3
+ describe Algebra::Intersection, '#optimize' do
4
+ subject { object.optimize }
5
+
6
+ let(:header) { [ [ :id, Integer ] ] }
7
+ let(:left_body) { [ [ 1 ] ].each }
8
+ let(:right_body) { [ [ 2 ] ].each }
9
+ let(:original_left) { Relation.new(header, left_body) }
10
+ let(:original_right) { Relation.new(header, right_body) }
11
+ let(:object) { described_class.new(left, right) }
12
+
13
+ context 'left is an empty relation' do
14
+ let(:left) { Relation::Empty.new(header) }
15
+ let(:right) { original_right }
16
+
17
+ it { should equal(left) }
18
+
19
+ it 'returns an equivalent relation to the unoptimized operation' do
20
+ should == object
21
+ end
22
+
23
+ it 'does not execute right_body#each' do
24
+ right_body.should_not_receive(:each)
25
+ subject
26
+ end
27
+
28
+ it_should_behave_like 'an optimize method'
29
+ end
30
+
31
+ context 'right is an empty relation' do
32
+ let(:left) { original_left }
33
+ let(:right) { Relation::Empty.new(header) }
34
+
35
+ it { should equal(right) }
36
+
37
+ it 'returns an equivalent relation to the unoptimized operation' do
38
+ should == object
39
+ end
40
+
41
+ it 'does not execute left_body#each' do
42
+ left_body.should_not_receive(:each)
43
+ subject
44
+ end
45
+
46
+ it_should_behave_like 'an optimize method'
47
+ end
48
+
49
+ context 'left is an empty relation when optimized' do
50
+ let(:left) { Algebra::Restriction.new(original_left, Logic::Proposition::Contradiction.instance) }
51
+ let(:right) { original_right }
52
+
53
+ it { should eql(Relation::Empty.new(left.header | right.header)) }
54
+
55
+ it 'returns an equivalent relation to the unoptimized operation' do
56
+ should == object
57
+ end
58
+
59
+ it 'does not execute left_body#each' do
60
+ left_body.should_not_receive(:each)
61
+ subject
62
+ end
63
+
64
+ it 'does not execute right_body#each' do
65
+ right_body.should_not_receive(:each)
66
+ subject
67
+ end
68
+
69
+ it_should_behave_like 'an optimize method'
70
+ end
71
+
72
+ context 'right is an empty relation when optimized' do
73
+ let(:left) { original_left }
74
+ let(:right) { Algebra::Restriction.new(original_right, Logic::Proposition::Contradiction.instance) }
75
+
76
+ it { should eql(Relation::Empty.new(left.header | right.header)) }
77
+
78
+ it 'returns an equivalent relation to the unoptimized operation' do
79
+ should == object
80
+ end
81
+
82
+ it 'does not execute left_body#each' do
83
+ left_body.should_not_receive(:each)
84
+ subject
85
+ end
86
+
87
+ it 'does not execute right_body#each' do
88
+ right_body.should_not_receive(:each)
89
+ subject
90
+ end
91
+
92
+ it_should_behave_like 'an optimize method'
93
+ end
94
+
95
+ unless defined?(JRUBY_VERSION) && JRUBY_VERSION < '1.6'
96
+ context 'left and right are equivalent relations' do
97
+ let(:right_body) { left_body.dup }
98
+ let(:left) { original_left }
99
+ let(:right) { original_right }
100
+
101
+ it { should equal(left) }
102
+
103
+ it 'returns an equivalent relation to the unoptimized operation' do
104
+ should == object
105
+ end
106
+
107
+ it 'executes left_body#each' do
108
+ left_body.should_receive(:each)
109
+ subject
110
+ end
111
+
112
+ it 'executes right_body#each' do
113
+ right_body.should_receive(:each)
114
+ subject
115
+ end
116
+
117
+ it_should_behave_like 'an optimize method'
118
+ end
119
+ end
120
+
121
+ context 'left and right are not empty relations' do
122
+ let(:left) { original_left }
123
+ let(:right) { original_right }
124
+
125
+ it { should equal(object) }
126
+
127
+ it 'executed left_body#each' do
128
+ left_body.should_receive(:each)
129
+ subject
130
+ end
131
+
132
+ it 'executed right_body#each' do
133
+ right_body.should_receive(:each)
134
+ subject
135
+ end
136
+
137
+ it_should_behave_like 'an optimize method'
138
+ end
139
+
140
+ context 'left and right are materialized relations' do
141
+ let(:left) { Relation.new(header, [ [ 1 ], [ 2 ] ]) }
142
+ let(:right) { Relation.new(header, [ [ 1 ] ]) }
143
+
144
+ it { should eql(Relation::Materialized.new(header, [ [ 1 ] ])) }
145
+
146
+ it 'returns an equivalent relation to the unoptimized operation' do
147
+ should == object
148
+ end
149
+
150
+ it_should_behave_like 'an optimize method'
151
+ end
152
+ end
@@ -0,0 +1,110 @@
1
+ require 'spec_helper'
2
+
3
+ describe Algebra::Join, '#optimize' do
4
+ subject { object.optimize }
5
+
6
+ let(:left_body) { [ [ 1 ], [ 2 ] ].each }
7
+ let(:right_body) { [ [ 2, 'Dan Kubb' ] ].each }
8
+ let(:original_left) { Relation.new([ [ :id, Integer ] ], left_body) }
9
+ let(:original_right) { Relation.new([ [ :id, Integer ], [ :name, String ] ], right_body) }
10
+ let(:left) { original_left }
11
+ let(:right) { original_right }
12
+ let(:object) { described_class.new(left, right) }
13
+
14
+ context 'left is an empty relation' do
15
+ let(:left) { Relation::Empty.new(original_left.header) }
16
+
17
+ it { should eql(Relation::Empty.new(right.header)) }
18
+
19
+ it 'returns an equivalent relation to the unoptimized operation' do
20
+ should == object
21
+ end
22
+
23
+ it 'does not execute right_body#each' do
24
+ right_body.should_not_receive(:each)
25
+ subject
26
+ end
27
+
28
+ it_should_behave_like 'an optimize method'
29
+ end
30
+
31
+ context 'right is an empty relation' do
32
+ let(:right) { Relation::Empty.new(original_right.header) }
33
+
34
+ it { should eql(Relation::Empty.new(right.header)) }
35
+
36
+ it 'returns an equivalent relation to the unoptimized operation' do
37
+ should == object
38
+ end
39
+
40
+ it 'does not execute left_body#each' do
41
+ left_body.should_not_receive(:each)
42
+ subject
43
+ end
44
+
45
+ it_should_behave_like 'an optimize method'
46
+ end
47
+
48
+ context 'left is an empty relation when optimized' do
49
+ let(:left) { Algebra::Restriction.new(original_left, Logic::Proposition::Contradiction.instance) }
50
+
51
+ it { should eql(Relation::Empty.new(right.header)) }
52
+
53
+ it 'returns an equivalent relation to the unoptimized operation' do
54
+ should == object
55
+ end
56
+
57
+ it 'does not execute right_body#each' do
58
+ right_body.should_not_receive(:each)
59
+ subject
60
+ end
61
+
62
+ it_should_behave_like 'an optimize method'
63
+ end
64
+
65
+ context 'right is an empty relation when optimized' do
66
+ let(:right) { Algebra::Restriction.new(original_right, Logic::Proposition::Contradiction.instance) }
67
+
68
+ it { should eql(Relation::Empty.new(right.header)) }
69
+
70
+ it 'returns an equivalent relation to the unoptimized operation' do
71
+ should == object
72
+ end
73
+
74
+ it 'does not execute left_body#each' do
75
+ left_body.should_not_receive(:each)
76
+ subject
77
+ end
78
+
79
+ it_should_behave_like 'an optimize method'
80
+ end
81
+
82
+ context 'left and right are not empty relations' do
83
+ it { should equal(object) }
84
+
85
+ it 'does not execute left_body#each' do
86
+ left_body.should_not_receive(:each)
87
+ subject
88
+ end
89
+
90
+ it 'does not execute right_body#each' do
91
+ right_body.should_not_receive(:each)
92
+ subject
93
+ end
94
+
95
+ it_should_behave_like 'an optimize method'
96
+ end
97
+
98
+ context 'left and right are materialized relations' do
99
+ let(:left) { Relation.new([ [ :id, Integer ] ], [ [ 1 ], [ 2 ] ]) }
100
+ let(:right) { Relation.new([ [ :id, Integer ], [ :name, String ] ], [ [ 2, 'Dan Kubb' ] ]) }
101
+
102
+ it { should eql(Relation::Materialized.new([ [ :id, Integer ], [ :name, String ] ], [ [ 2, 'Dan Kubb' ] ])) }
103
+
104
+ it 'returns an equivalent relation to the unoptimized operation' do
105
+ should == object
106
+ end
107
+
108
+ it_should_behave_like 'an optimize method'
109
+ end
110
+ end