axiom-optimizer 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gemtest +0 -0
- data/.gitignore +37 -0
- data/.rspec +4 -0
- data/.rvmrc +1 -0
- data/.travis.yml +35 -0
- data/CONTRIBUTING.md +11 -0
- data/Gemfile +10 -0
- data/Gemfile.devtools +57 -0
- data/Guardfile +23 -0
- data/LICENSE +20 -0
- data/README.md +111 -0
- data/Rakefile +5 -0
- data/TODO +144 -0
- data/axiom-optimizer.gemspec +25 -0
- data/config/flay.yml +3 -0
- data/config/flog.yml +2 -0
- data/config/mutant.yml +3 -0
- data/config/reek.yml +162 -0
- data/config/roodi.yml +16 -0
- data/config/yardstick.yml +2 -0
- data/lib/axiom-optimizer.rb +3 -0
- data/lib/axiom/optimizer.rb +168 -0
- data/lib/axiom/optimizer/aggregate.rb +16 -0
- data/lib/axiom/optimizer/aggregate/count.rb +17 -0
- data/lib/axiom/optimizer/aggregate/maximum.rb +17 -0
- data/lib/axiom/optimizer/aggregate/mean.rb +17 -0
- data/lib/axiom/optimizer/aggregate/minimum.rb +17 -0
- data/lib/axiom/optimizer/aggregate/standard_deviation.rb +17 -0
- data/lib/axiom/optimizer/aggregate/sum.rb +17 -0
- data/lib/axiom/optimizer/aggregate/variance.rb +17 -0
- data/lib/axiom/optimizer/algebra/difference.rb +68 -0
- data/lib/axiom/optimizer/algebra/extension.rb +97 -0
- data/lib/axiom/optimizer/algebra/intersection.rb +68 -0
- data/lib/axiom/optimizer/algebra/join.rb +184 -0
- data/lib/axiom/optimizer/algebra/product.rb +70 -0
- data/lib/axiom/optimizer/algebra/projection.rb +212 -0
- data/lib/axiom/optimizer/algebra/rename.rb +381 -0
- data/lib/axiom/optimizer/algebra/restriction.rb +373 -0
- data/lib/axiom/optimizer/algebra/summarization.rb +200 -0
- data/lib/axiom/optimizer/algebra/union.rb +68 -0
- data/lib/axiom/optimizer/function.rb +87 -0
- data/lib/axiom/optimizer/function/binary.rb +124 -0
- data/lib/axiom/optimizer/function/connective/binary.rb +245 -0
- data/lib/axiom/optimizer/function/connective/conjunction.rb +122 -0
- data/lib/axiom/optimizer/function/connective/disjunction.rb +122 -0
- data/lib/axiom/optimizer/function/connective/negation.rb +65 -0
- data/lib/axiom/optimizer/function/numeric.rb +34 -0
- data/lib/axiom/optimizer/function/numeric/absolute.rb +20 -0
- data/lib/axiom/optimizer/function/numeric/addition.rb +20 -0
- data/lib/axiom/optimizer/function/numeric/division.rb +20 -0
- data/lib/axiom/optimizer/function/numeric/exponentiation.rb +20 -0
- data/lib/axiom/optimizer/function/numeric/modulo.rb +20 -0
- data/lib/axiom/optimizer/function/numeric/multiplication.rb +20 -0
- data/lib/axiom/optimizer/function/numeric/square_root.rb +20 -0
- data/lib/axiom/optimizer/function/numeric/subtraction.rb +20 -0
- data/lib/axiom/optimizer/function/numeric/unary_minus.rb +20 -0
- data/lib/axiom/optimizer/function/numeric/unary_plus.rb +20 -0
- data/lib/axiom/optimizer/function/predicate.rb +61 -0
- data/lib/axiom/optimizer/function/predicate/comparable.rb +144 -0
- data/lib/axiom/optimizer/function/predicate/enumerable.rb +138 -0
- data/lib/axiom/optimizer/function/predicate/equality.rb +44 -0
- data/lib/axiom/optimizer/function/predicate/exclusion.rb +43 -0
- data/lib/axiom/optimizer/function/predicate/greater_than.rb +55 -0
- data/lib/axiom/optimizer/function/predicate/greater_than_or_equal_to.rb +55 -0
- data/lib/axiom/optimizer/function/predicate/inclusion.rb +43 -0
- data/lib/axiom/optimizer/function/predicate/inequality.rb +44 -0
- data/lib/axiom/optimizer/function/predicate/less_than.rb +55 -0
- data/lib/axiom/optimizer/function/predicate/less_than_or_equal_to.rb +55 -0
- data/lib/axiom/optimizer/function/predicate/match.rb +20 -0
- data/lib/axiom/optimizer/function/predicate/no_match.rb +20 -0
- data/lib/axiom/optimizer/function/string/length.rb +31 -0
- data/lib/axiom/optimizer/function/unary.rb +86 -0
- data/lib/axiom/optimizer/optimizable.rb +60 -0
- data/lib/axiom/optimizer/relation/materialized.rb +40 -0
- data/lib/axiom/optimizer/relation/operation/binary.rb +134 -0
- data/lib/axiom/optimizer/relation/operation/combination.rb +33 -0
- data/lib/axiom/optimizer/relation/operation/deletion.rb +20 -0
- data/lib/axiom/optimizer/relation/operation/insertion.rb +20 -0
- data/lib/axiom/optimizer/relation/operation/limit.rb +141 -0
- data/lib/axiom/optimizer/relation/operation/offset.rb +106 -0
- data/lib/axiom/optimizer/relation/operation/order.rb +85 -0
- data/lib/axiom/optimizer/relation/operation/reverse.rb +85 -0
- data/lib/axiom/optimizer/relation/operation/unary.rb +124 -0
- data/lib/axiom/optimizer/support/predicate_partition.rb +184 -0
- data/lib/axiom/optimizer/version.rb +10 -0
- data/spec/integration/axiom/algebra/difference/optimize_spec.rb +160 -0
- data/spec/integration/axiom/algebra/intersection/optimize_spec.rb +160 -0
- data/spec/integration/axiom/algebra/join/optimize_spec.rb +112 -0
- data/spec/integration/axiom/algebra/product/optimize_spec.rb +178 -0
- data/spec/integration/axiom/algebra/projection/optimize_spec.rb +250 -0
- data/spec/integration/axiom/algebra/rename/optimize_spec.rb +442 -0
- data/spec/integration/axiom/algebra/restriction/optimize_spec.rb +218 -0
- data/spec/integration/axiom/algebra/summarization/optimize_spec.rb +49 -0
- data/spec/integration/axiom/algebra/union/optimize_spec.rb +200 -0
- data/spec/integration/axiom/function/connective/conjunction/optimize_spec.rb +236 -0
- data/spec/integration/axiom/function/connective/disjunction/optimize_spec.rb +237 -0
- data/spec/integration/axiom/function/connective/negation/optimize_spec.rb +43 -0
- data/spec/integration/axiom/function/optimize_spec.rb +30 -0
- data/spec/integration/axiom/function/predicate/equality/optimize_spec.rb +92 -0
- data/spec/integration/axiom/function/predicate/exclusion/optimize_spec.rb +133 -0
- data/spec/integration/axiom/function/predicate/greater_than/optimize_spec.rb +102 -0
- data/spec/integration/axiom/function/predicate/greater_than_or_equal_to/optimize_spec.rb +102 -0
- data/spec/integration/axiom/function/predicate/inclusion/optimize_spec.rb +133 -0
- data/spec/integration/axiom/function/predicate/inequality/optimize_spec.rb +92 -0
- data/spec/integration/axiom/function/predicate/less_than/optimize_spec.rb +102 -0
- data/spec/integration/axiom/function/predicate/less_than_or_equal_to/optimize_spec.rb +102 -0
- data/spec/integration/axiom/relation/empty/optimize_spec.rb +13 -0
- data/spec/integration/axiom/relation/materialized/optimize_spec.rb +29 -0
- data/spec/integration/axiom/relation/operation/limit/optimize_spec.rb +142 -0
- data/spec/integration/axiom/relation/operation/offset/optimize_spec.rb +100 -0
- data/spec/integration/axiom/relation/operation/order/optimize_spec.rb +105 -0
- data/spec/integration/axiom/relation/operation/reverse/optimize_spec.rb +115 -0
- data/spec/integration/axiom/relation/optimize_spec.rb +23 -0
- data/spec/rcov.opts +7 -0
- data/spec/shared/function_connective_binary_optimize_behavior.rb +102 -0
- data/spec/shared/optimize_method_behavior.rb +16 -0
- data/spec/spec_helper.rb +38 -0
- data/spec/support/add_method_missing.rb +15 -0
- data/spec/support/config_alias.rb +3 -0
- data/spec/support/ice_nine_config.rb +6 -0
- data/spec/support/lazy_enumerable.rb +18 -0
- data/spec/unit/axiom/optimizer/algebra/difference/empty_left/optimize_spec.rb +19 -0
- data/spec/unit/axiom/optimizer/algebra/difference/empty_right/optimize_spec.rb +19 -0
- data/spec/unit/axiom/optimizer/algebra/difference/equal_operands/optimize_spec.rb +23 -0
- data/spec/unit/axiom/optimizer/algebra/extension/extensions_spec.rb +31 -0
- data/spec/unit/axiom/optimizer/algebra/extension/order_operand/optimizable_predicate_spec.rb +23 -0
- data/spec/unit/axiom/optimizer/algebra/extension/order_operand/optimize_spec.rb +22 -0
- data/spec/unit/axiom/optimizer/algebra/extension/unoptimized_operand/optimizable_predicate_spec.rb +37 -0
- data/spec/unit/axiom/optimizer/algebra/extension/unoptimized_operand/optimize_spec.rb +27 -0
- data/spec/unit/axiom/optimizer/algebra/intersection/empty_left/optimize_spec.rb +19 -0
- data/spec/unit/axiom/optimizer/algebra/intersection/empty_right/optimize_spec.rb +19 -0
- data/spec/unit/axiom/optimizer/algebra/intersection/equal_operands/optimize_spec.rb +19 -0
- data/spec/unit/axiom/optimizer/algebra/join/disjoint_headers/optimizable_predicate_spec.rb +29 -0
- data/spec/unit/axiom/optimizer/algebra/join/disjoint_headers/optimize_spec.rb +22 -0
- data/spec/unit/axiom/optimizer/algebra/join/equal_headers/optimizable_predicate_spec.rb +29 -0
- data/spec/unit/axiom/optimizer/algebra/join/equal_headers/optimize_spec.rb +23 -0
- data/spec/unit/axiom/optimizer/algebra/join/materialized_left/optimizable_predicate_spec.rb +42 -0
- data/spec/unit/axiom/optimizer/algebra/join/materialized_left/optimize_spec.rb +55 -0
- data/spec/unit/axiom/optimizer/algebra/join/materialized_right/optimizable_predicate_spec.rb +42 -0
- data/spec/unit/axiom/optimizer/algebra/join/materialized_right/optimize_spec.rb +55 -0
- data/spec/unit/axiom/optimizer/algebra/product/table_dee_left/optimizable_predicate_spec.rb +27 -0
- data/spec/unit/axiom/optimizer/algebra/product/table_dee_left/optimize_spec.rb +18 -0
- data/spec/unit/axiom/optimizer/algebra/product/table_dee_right/optimizable_predicate_spec.rb +27 -0
- data/spec/unit/axiom/optimizer/algebra/product/table_dee_right/optimize_spec.rb +18 -0
- data/spec/unit/axiom/optimizer/algebra/projection/empty_operand/optimizable_predicate_spec.rb +27 -0
- data/spec/unit/axiom/optimizer/algebra/projection/empty_operand/optimize_spec.rb +22 -0
- data/spec/unit/axiom/optimizer/algebra/projection/extension_operand/optimizable_predicate_spec.rb +35 -0
- data/spec/unit/axiom/optimizer/algebra/projection/extension_operand/optimize_spec.rb +22 -0
- data/spec/unit/axiom/optimizer/algebra/projection/projection_operand/optimizable_predicate_spec.rb +28 -0
- data/spec/unit/axiom/optimizer/algebra/projection/projection_operand/optimize_spec.rb +22 -0
- data/spec/unit/axiom/optimizer/algebra/projection/union_operand/optimizable_predicate_spec.rb +29 -0
- data/spec/unit/axiom/optimizer/algebra/projection/union_operand/optimize_spec.rb +25 -0
- data/spec/unit/axiom/optimizer/algebra/projection/unoptimized_operand/optimizable_predicate_spec.rb +28 -0
- data/spec/unit/axiom/optimizer/algebra/projection/unoptimized_operand/optimize_spec.rb +22 -0
- data/spec/unit/axiom/optimizer/algebra/rename/aliases_spec.rb +23 -0
- data/spec/unit/axiom/optimizer/algebra/rename/empty_operand/optimizable_predicate_spec.rb +27 -0
- data/spec/unit/axiom/optimizer/algebra/rename/empty_operand/optimize_spec.rb +21 -0
- data/spec/unit/axiom/optimizer/algebra/rename/limit_operand/optimizable_predicate_spec.rb +28 -0
- data/spec/unit/axiom/optimizer/algebra/rename/limit_operand/optimize_spec.rb +23 -0
- data/spec/unit/axiom/optimizer/algebra/rename/offset_operand/optimizable_predicate_spec.rb +28 -0
- data/spec/unit/axiom/optimizer/algebra/rename/offset_operand/optimize_spec.rb +23 -0
- data/spec/unit/axiom/optimizer/algebra/rename/order_operand/optimizable_predicate_spec.rb +28 -0
- data/spec/unit/axiom/optimizer/algebra/rename/order_operand/optimize_spec.rb +22 -0
- data/spec/unit/axiom/optimizer/algebra/rename/projection_operand/optimizable_predicate_spec.rb +43 -0
- data/spec/unit/axiom/optimizer/algebra/rename/projection_operand/optimize_spec.rb +22 -0
- data/spec/unit/axiom/optimizer/algebra/rename/rename_operand/optimizable_predicate_spec.rb +30 -0
- data/spec/unit/axiom/optimizer/algebra/rename/rename_operand/optimize_spec.rb +22 -0
- data/spec/unit/axiom/optimizer/algebra/rename/rename_operand_and_empty_aliases/optimizable_predicate_spec.rb +37 -0
- data/spec/unit/axiom/optimizer/algebra/rename/rename_operand_and_empty_aliases/optimize_spec.rb +18 -0
- data/spec/unit/axiom/optimizer/algebra/rename/restriction_operand/optimizable_predicate_spec.rb +29 -0
- data/spec/unit/axiom/optimizer/algebra/rename/restriction_operand/optimize_spec.rb +23 -0
- data/spec/unit/axiom/optimizer/algebra/rename/reverse_operand/optimizable_predicate_spec.rb +27 -0
- data/spec/unit/axiom/optimizer/algebra/rename/reverse_operand/optimize_spec.rb +23 -0
- data/spec/unit/axiom/optimizer/algebra/rename/set_operand/optimizable_predicate_spec.rb +29 -0
- data/spec/unit/axiom/optimizer/algebra/rename/set_operand/optimize_spec.rb +23 -0
- data/spec/unit/axiom/optimizer/algebra/rename/unoptimized_operand/optimizable_predicate_spec.rb +29 -0
- data/spec/unit/axiom/optimizer/algebra/rename/unoptimized_operand/optimize_spec.rb +23 -0
- data/spec/unit/axiom/optimizer/algebra/restriction/combination_operand/optimizable_predicate_spec.rb +41 -0
- data/spec/unit/axiom/optimizer/algebra/restriction/combination_operand/optimize_spec.rb +35 -0
- data/spec/unit/axiom/optimizer/algebra/restriction/contradiction/optimizable_predicate_spec.rb +46 -0
- data/spec/unit/axiom/optimizer/algebra/restriction/contradiction/optimize_spec.rb +23 -0
- data/spec/unit/axiom/optimizer/algebra/restriction/join_operand/optimizable_predicate_spec.rb +51 -0
- data/spec/unit/axiom/optimizer/algebra/restriction/join_operand/optimize_spec.rb +48 -0
- data/spec/unit/axiom/optimizer/algebra/restriction/order_operand/optimizable_predicate_spec.rb +28 -0
- data/spec/unit/axiom/optimizer/algebra/restriction/order_operand/optimize_spec.rb +22 -0
- data/spec/unit/axiom/optimizer/algebra/restriction/predicate_spec.rb +18 -0
- data/spec/unit/axiom/optimizer/algebra/restriction/product_operand/optimizable_predicate_spec.rb +44 -0
- data/spec/unit/axiom/optimizer/algebra/restriction/product_operand/optimize_spec.rb +48 -0
- data/spec/unit/axiom/optimizer/algebra/restriction/restriction_operand/optimizable_predicate_spec.rb +30 -0
- data/spec/unit/axiom/optimizer/algebra/restriction/restriction_operand/optimize_spec.rb +24 -0
- data/spec/unit/axiom/optimizer/algebra/restriction/set_operand/optimizable_predicate_spec.rb +30 -0
- data/spec/unit/axiom/optimizer/algebra/restriction/set_operand/optimize_spec.rb +24 -0
- data/spec/unit/axiom/optimizer/algebra/restriction/tautology/optimizable_predicate_spec.rb +33 -0
- data/spec/unit/axiom/optimizer/algebra/restriction/tautology/optimize_spec.rb +19 -0
- data/spec/unit/axiom/optimizer/algebra/restriction/unoptimized_operand/optimizable_predicate_spec.rb +44 -0
- data/spec/unit/axiom/optimizer/algebra/restriction/unoptimized_operand/optimize_spec.rb +24 -0
- data/spec/unit/axiom/optimizer/algebra/summarization/empty_operand/class_methods/extension_default_spec.rb +22 -0
- data/spec/unit/axiom/optimizer/algebra/summarization/empty_operand/optimizable_predicate_spec.rb +29 -0
- data/spec/unit/axiom/optimizer/algebra/summarization/empty_operand/optimize_spec.rb +47 -0
- data/spec/unit/axiom/optimizer/algebra/summarization/empty_summarize_per/optimizable_predicate_spec.rb +29 -0
- data/spec/unit/axiom/optimizer/algebra/summarization/empty_summarize_per/optimize_spec.rb +25 -0
- data/spec/unit/axiom/optimizer/algebra/summarization/order_operand/optimizable_predicate_spec.rb +23 -0
- data/spec/unit/axiom/optimizer/algebra/summarization/order_operand/optimize_spec.rb +22 -0
- data/spec/unit/axiom/optimizer/algebra/summarization/summarize_per_spec.rb +29 -0
- data/spec/unit/axiom/optimizer/algebra/summarization/summarizers_spec.rb +31 -0
- data/spec/unit/axiom/optimizer/algebra/summarization/unoptimized_operand/optimizable_predicate_spec.rb +49 -0
- data/spec/unit/axiom/optimizer/algebra/summarization/unoptimized_operand/optimize_spec.rb +30 -0
- data/spec/unit/axiom/optimizer/algebra/union/empty_left/optimize_spec.rb +19 -0
- data/spec/unit/axiom/optimizer/algebra/union/empty_right/optimize_spec.rb +19 -0
- data/spec/unit/axiom/optimizer/algebra/union/equal_operands/optimize_spec.rb +19 -0
- data/spec/unit/axiom/optimizer/class_methods/chain_spec.rb +56 -0
- data/spec/unit/axiom/optimizer/function/binary/constant_operands/optimizable_predicate_spec.rb +36 -0
- data/spec/unit/axiom/optimizer/function/binary/constant_operands/optimize_spec.rb +18 -0
- data/spec/unit/axiom/optimizer/function/binary/left_spec.rb +28 -0
- data/spec/unit/axiom/optimizer/function/binary/right_spec.rb +28 -0
- data/spec/unit/axiom/optimizer/function/binary/unoptimized_operands/optimizable_predicate_spec.rb +37 -0
- data/spec/unit/axiom/optimizer/function/binary/unoptimized_operands/optimize_spec.rb +23 -0
- data/spec/unit/axiom/optimizer/function/class_methods/optimize_functions_spec.rb +26 -0
- data/spec/unit/axiom/optimizer/function/class_methods/optimize_operand_spec.rb +22 -0
- data/spec/unit/axiom/optimizer/function/connective/binary/constant_operands/optimize_spec.rb +16 -0
- data/spec/unit/axiom/optimizer/function/connective/binary/equal_operands/optimizable_predicate_spec.rb +29 -0
- data/spec/unit/axiom/optimizer/function/connective/binary/equal_operands/optimize_spec.rb +19 -0
- data/spec/unit/axiom/optimizer/function/connective/binary/left_spec.rb +16 -0
- data/spec/unit/axiom/optimizer/function/connective/binary/redundant_left/optimizable_predicate_spec.rb +28 -0
- data/spec/unit/axiom/optimizer/function/connective/binary/redundant_left/optimize_spec.rb +23 -0
- data/spec/unit/axiom/optimizer/function/connective/binary/redundant_right/optimizable_predicate_spec.rb +28 -0
- data/spec/unit/axiom/optimizer/function/connective/binary/redundant_right/optimize_spec.rb +23 -0
- data/spec/unit/axiom/optimizer/function/connective/binary/right_spec.rb +16 -0
- data/spec/unit/axiom/optimizer/function/connective/conjunction/contradiction/optimizable_predicate_spec.rb +64 -0
- data/spec/unit/axiom/optimizer/function/connective/conjunction/contradiction/optimize_spec.rb +19 -0
- data/spec/unit/axiom/optimizer/function/connective/conjunction/optimizable_to_exclusion/optimizable_predicate_spec.rb +61 -0
- data/spec/unit/axiom/optimizer/function/connective/conjunction/optimizable_to_exclusion/optimize_spec.rb +76 -0
- data/spec/unit/axiom/optimizer/function/connective/conjunction/tautology_left/optimizable_predicate_spec.rb +29 -0
- data/spec/unit/axiom/optimizer/function/connective/conjunction/tautology_left/optimize_spec.rb +19 -0
- data/spec/unit/axiom/optimizer/function/connective/conjunction/tautology_right/optimizable_predicate_spec.rb +29 -0
- data/spec/unit/axiom/optimizer/function/connective/conjunction/tautology_right/optimize_spec.rb +19 -0
- data/spec/unit/axiom/optimizer/function/connective/disjunction/contradiction_left/optimizable_predicate_spec.rb +29 -0
- data/spec/unit/axiom/optimizer/function/connective/disjunction/contradiction_left/optimize_spec.rb +19 -0
- data/spec/unit/axiom/optimizer/function/connective/disjunction/contradiction_right/optimizable_predicate_spec.rb +29 -0
- data/spec/unit/axiom/optimizer/function/connective/disjunction/contradiction_right/optimize_spec.rb +19 -0
- data/spec/unit/axiom/optimizer/function/connective/disjunction/optimizable_to_inclusion/optimizable_predicate_spec.rb +61 -0
- data/spec/unit/axiom/optimizer/function/connective/disjunction/optimizable_to_inclusion/optimize_spec.rb +76 -0
- data/spec/unit/axiom/optimizer/function/connective/disjunction/tautology/optimizable_predicate_spec.rb +64 -0
- data/spec/unit/axiom/optimizer/function/connective/disjunction/tautology/optimize_spec.rb +19 -0
- data/spec/unit/axiom/optimizer/function/connective/negation/constant_operand/optimize_spec.rb +16 -0
- data/spec/unit/axiom/optimizer/function/connective/negation/invertible_operand/optimizable_predicate_spec.rb +28 -0
- data/spec/unit/axiom/optimizer/function/connective/negation/invertible_operand/optimize_spec.rb +22 -0
- data/spec/unit/axiom/optimizer/function/connective/negation/operand_spec.rb +14 -0
- data/spec/unit/axiom/optimizer/function/predicate/comparable/never_comparable/optimizable_predicate_spec.rb +74 -0
- data/spec/unit/axiom/optimizer/function/predicate/comparable/never_equivalent/optimizable_predicate_spec.rb +74 -0
- data/spec/unit/axiom/optimizer/function/predicate/comparable/normalizable_operands/optimizable_predicate_spec.rb +43 -0
- data/spec/unit/axiom/optimizer/function/predicate/comparable/normalizable_operands/optimize_spec.rb +21 -0
- data/spec/unit/axiom/optimizer/function/predicate/constant_operands/optimize_spec.rb +16 -0
- data/spec/unit/axiom/optimizer/function/predicate/contradiction/optimize_spec.rb +18 -0
- data/spec/unit/axiom/optimizer/function/predicate/enumerable/class_methods/sort_by_value_spec.rb +27 -0
- data/spec/unit/axiom/optimizer/function/predicate/enumerable/empty_right/optimizable_predicate_spec.rb +78 -0
- data/spec/unit/axiom/optimizer/function/predicate/enumerable/one_right/optimizable_predicate_spec.rb +78 -0
- data/spec/unit/axiom/optimizer/function/predicate/enumerable/unoptimized_operands/optimizable_predicate_spec.rb +51 -0
- data/spec/unit/axiom/optimizer/function/predicate/enumerable/unoptimized_operands/optimize_spec.rb +66 -0
- data/spec/unit/axiom/optimizer/function/predicate/equality/tautology/optimizable_predicate_spec.rb +29 -0
- data/spec/unit/axiom/optimizer/function/predicate/exclusion/empty_right/optimize_spec.rb +45 -0
- data/spec/unit/axiom/optimizer/function/predicate/exclusion/one_right/optimize_spec.rb +65 -0
- data/spec/unit/axiom/optimizer/function/predicate/greater_than/contradiction/optimizable_predicate_spec.rb +43 -0
- data/spec/unit/axiom/optimizer/function/predicate/greater_than/tautology/optimizable_predicate_spec.rb +28 -0
- data/spec/unit/axiom/optimizer/function/predicate/greater_than_or_equal_to/contradiction/optimizable_predicate_spec.rb +43 -0
- data/spec/unit/axiom/optimizer/function/predicate/greater_than_or_equal_to/tautology/optimizable_predicate_spec.rb +43 -0
- data/spec/unit/axiom/optimizer/function/predicate/inclusion/empty_right/optimize_spec.rb +45 -0
- data/spec/unit/axiom/optimizer/function/predicate/inclusion/one_right/optimize_spec.rb +66 -0
- data/spec/unit/axiom/optimizer/function/predicate/inequality/contradiction/optimizable_predicate_spec.rb +29 -0
- data/spec/unit/axiom/optimizer/function/predicate/less_than/contradiction/optimizable_predicate_spec.rb +43 -0
- data/spec/unit/axiom/optimizer/function/predicate/less_than/tautology/optimizable_predicate_spec.rb +28 -0
- data/spec/unit/axiom/optimizer/function/predicate/less_than_or_equal_to/contradiction/optimizable_predicate_spec.rb +43 -0
- data/spec/unit/axiom/optimizer/function/predicate/less_than_or_equal_to/tautology/optimizable_predicate_spec.rb +43 -0
- data/spec/unit/axiom/optimizer/function/predicate/tautology/optimize_spec.rb +18 -0
- data/spec/unit/axiom/optimizer/function/unary/constant_operand/optimizable_predicate_spec.rb +27 -0
- data/spec/unit/axiom/optimizer/function/unary/constant_operand/optimize_spec.rb +18 -0
- data/spec/unit/axiom/optimizer/function/unary/operand_spec.rb +27 -0
- data/spec/unit/axiom/optimizer/function/unary/unoptimized_operand/optimizable_predicate_spec.rb +27 -0
- data/spec/unit/axiom/optimizer/function/unary/unoptimized_operand/optimize_spec.rb +18 -0
- data/spec/unit/axiom/optimizer/function/util/class_methods/attribute_spec.rb +21 -0
- data/spec/unit/axiom/optimizer/function/util/class_methods/constant_spec.rb +27 -0
- data/spec/unit/axiom/optimizer/function/util/class_methods/max_spec.rb +27 -0
- data/spec/unit/axiom/optimizer/function/util/class_methods/min_spec.rb +27 -0
- data/spec/unit/axiom/optimizer/operation_spec.rb +13 -0
- data/spec/unit/axiom/optimizer/optimizable/class_methods/optimizer_spec.rb +34 -0
- data/spec/unit/axiom/optimizer/optimizable/optimize_spec.rb +38 -0
- data/spec/unit/axiom/optimizer/optimizable_predicate_spec.rb +17 -0
- data/spec/unit/axiom/optimizer/optimize_spec.rb +17 -0
- data/spec/unit/axiom/optimizer/predicate_partition/left_spec.rb +149 -0
- data/spec/unit/axiom/optimizer/predicate_partition/remainder_spec.rb +149 -0
- data/spec/unit/axiom/optimizer/predicate_partition/right_spec.rb +149 -0
- data/spec/unit/axiom/optimizer/relation/materialized/empty_operand/optimizable_predicate_spec.rb +22 -0
- data/spec/unit/axiom/optimizer/relation/materialized/empty_operand/optimize_spec.rb +21 -0
- data/spec/unit/axiom/optimizer/relation/operation/binary/empty_left/optimizable_predicate_spec.rb +28 -0
- data/spec/unit/axiom/optimizer/relation/operation/binary/empty_right/optimizable_predicate_spec.rb +28 -0
- data/spec/unit/axiom/optimizer/relation/operation/binary/equal_operands/optimizable_predicate_spec.rb +31 -0
- data/spec/unit/axiom/optimizer/relation/operation/binary/left_spec.rb +15 -0
- data/spec/unit/axiom/optimizer/relation/operation/binary/materialized_operands/optimizable_predicate_spec.rb +37 -0
- data/spec/unit/axiom/optimizer/relation/operation/binary/materialized_operands/optimize_spec.rb +22 -0
- data/spec/unit/axiom/optimizer/relation/operation/binary/order_left/optimizable_predicate_spec.rb +23 -0
- data/spec/unit/axiom/optimizer/relation/operation/binary/order_left/optimize_spec.rb +23 -0
- data/spec/unit/axiom/optimizer/relation/operation/binary/order_right/optimizable_predicate_spec.rb +23 -0
- data/spec/unit/axiom/optimizer/relation/operation/binary/order_right/optimize_spec.rb +23 -0
- data/spec/unit/axiom/optimizer/relation/operation/binary/right_spec.rb +15 -0
- data/spec/unit/axiom/optimizer/relation/operation/binary/unoptimized_operands/optimizable_predicate_spec.rb +40 -0
- data/spec/unit/axiom/optimizer/relation/operation/binary/unoptimized_operands/optimize_spec.rb +24 -0
- data/spec/unit/axiom/optimizer/relation/operation/combination/optimize_spec.rb +18 -0
- data/spec/unit/axiom/optimizer/relation/operation/limit/equal_limit_operand/optimizable_predicate_spec.rb +33 -0
- data/spec/unit/axiom/optimizer/relation/operation/limit/equal_limit_operand/optimize_spec.rb +18 -0
- data/spec/unit/axiom/optimizer/relation/operation/limit/limit_operand/optimizable_predicate_spec.rb +27 -0
- data/spec/unit/axiom/optimizer/relation/operation/limit/limit_operand/optimize_spec.rb +35 -0
- data/spec/unit/axiom/optimizer/relation/operation/limit/unoptimized_operand/optimizable_predicate_spec.rb +28 -0
- data/spec/unit/axiom/optimizer/relation/operation/limit/unoptimized_operand/optimize_spec.rb +22 -0
- data/spec/unit/axiom/optimizer/relation/operation/limit/zero_limit/optimizable_predicate_spec.rb +27 -0
- data/spec/unit/axiom/optimizer/relation/operation/limit/zero_limit/optimize_spec.rb +22 -0
- data/spec/unit/axiom/optimizer/relation/operation/offset/offset_operand/optimizable_predicate_spec.rb +27 -0
- data/spec/unit/axiom/optimizer/relation/operation/offset/offset_operand/optimize_spec.rb +21 -0
- data/spec/unit/axiom/optimizer/relation/operation/offset/unoptimized_operand/optimizable_predicate_spec.rb +28 -0
- data/spec/unit/axiom/optimizer/relation/operation/offset/unoptimized_operand/optimize_spec.rb +22 -0
- data/spec/unit/axiom/optimizer/relation/operation/offset/zero_offset/optimizable_predicate_spec.rb +27 -0
- data/spec/unit/axiom/optimizer/relation/operation/offset/zero_offset/optimize_spec.rb +17 -0
- data/spec/unit/axiom/optimizer/relation/operation/order/one_limit_operand/optimizable_predicate_spec.rb +33 -0
- data/spec/unit/axiom/optimizer/relation/operation/order/one_limit_operand/optimize_spec.rb +18 -0
- data/spec/unit/axiom/optimizer/relation/operation/order/order_operand/optimizable_predicate_spec.rb +27 -0
- data/spec/unit/axiom/optimizer/relation/operation/order/order_operand/optimize_spec.rb +22 -0
- data/spec/unit/axiom/optimizer/relation/operation/order/unoptimized_operand/optimizable_predicate_spec.rb +28 -0
- data/spec/unit/axiom/optimizer/relation/operation/order/unoptimized_operand/optimize_spec.rb +23 -0
- data/spec/unit/axiom/optimizer/relation/operation/reverse/order_operand/optimizable_predicate_spec.rb +27 -0
- data/spec/unit/axiom/optimizer/relation/operation/reverse/order_operand/optimize_spec.rb +22 -0
- data/spec/unit/axiom/optimizer/relation/operation/reverse/reverse_operand/optimizable_predicate_spec.rb +27 -0
- data/spec/unit/axiom/optimizer/relation/operation/reverse/reverse_operand/optimize_spec.rb +19 -0
- data/spec/unit/axiom/optimizer/relation/operation/reverse/unoptimized_operand/optimizable_predicate_spec.rb +27 -0
- data/spec/unit/axiom/optimizer/relation/operation/reverse/unoptimized_operand/optimize_spec.rb +24 -0
- data/spec/unit/axiom/optimizer/relation/operation/unary/empty_operand/optimizable_predicate_spec.rb +23 -0
- data/spec/unit/axiom/optimizer/relation/operation/unary/empty_operand/optimize_spec.rb +17 -0
- data/spec/unit/axiom/optimizer/relation/operation/unary/header_spec.rb +15 -0
- data/spec/unit/axiom/optimizer/relation/operation/unary/materialized_operand/optimizable_predicate_spec.rb +23 -0
- data/spec/unit/axiom/optimizer/relation/operation/unary/materialized_operand/optimize_spec.rb +20 -0
- data/spec/unit/axiom/optimizer/relation/operation/unary/operand_spec.rb +16 -0
- data/spec/unit/axiom/optimizer/relation/operation/unary/order_operand/optimizable_predicate_spec.rb +28 -0
- data/spec/unit/axiom/optimizer/relation/operation/unary/order_operand/optimize_spec.rb +27 -0
- data/spec/unit/axiom/optimizer/relation/operation/unary/unchanged_header/optimizable_predicate_spec.rb +24 -0
- data/spec/unit/axiom/optimizer/relation/operation/unary/unchanged_header/optimize_spec.rb +14 -0
- metadata +697 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe Algebra::Projection, '#optimize' do
|
|
6
|
+
subject { object.optimize }
|
|
7
|
+
|
|
8
|
+
let(:header) { [ [ :id, Integer ], [ :name, String ], [ :age, Integer ] ] }
|
|
9
|
+
let(:body) { LazyEnumerable.new([ [ 1, 'Dan Kubb', 35 ] ]) }
|
|
10
|
+
let(:relation) { Relation.new(header, body) }
|
|
11
|
+
let(:operand) { relation }
|
|
12
|
+
let(:object) { described_class.new(operand, attributes) }
|
|
13
|
+
|
|
14
|
+
before do
|
|
15
|
+
# skip dup of the body to avoid clearing the method stubs
|
|
16
|
+
body.stub!(:frozen?).and_return(true)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
context 'when the attributes are equivalent to the relation headers, and in the same order' do
|
|
20
|
+
let(:attributes) { header }
|
|
21
|
+
|
|
22
|
+
it { should equal(operand) }
|
|
23
|
+
|
|
24
|
+
it 'returns an equivalent relation to the unoptimized operation' do
|
|
25
|
+
should == object
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'does not execute body#each' do
|
|
29
|
+
body.should_not_receive(:each)
|
|
30
|
+
subject
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it_should_behave_like 'an optimize method'
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
context 'when the attributes are equivalent to the relation headers, and not in the same order' do
|
|
37
|
+
let(:attributes) { [ :name, :id ] }
|
|
38
|
+
|
|
39
|
+
it 'does not factor out the object, because tuple order is currently significant' do
|
|
40
|
+
should equal(object)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it 'does not execute body#each' do
|
|
44
|
+
body.should_not_receive(:each)
|
|
45
|
+
subject
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it_should_behave_like 'an optimize method'
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
context 'when the attributes are different from the relation headers' do
|
|
52
|
+
let(:attributes) { [ :id ] }
|
|
53
|
+
|
|
54
|
+
it { should equal(object) }
|
|
55
|
+
|
|
56
|
+
it 'does not execute body#each' do
|
|
57
|
+
body.should_not_receive(:each)
|
|
58
|
+
subject
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it_should_behave_like 'an optimize method'
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
context 'containing an empty relation' do
|
|
65
|
+
let(:operand) { Relation::Empty.new(header) }
|
|
66
|
+
let(:attributes) { [ :id ] }
|
|
67
|
+
|
|
68
|
+
it { should eql(Relation::Empty.new(object.header)) }
|
|
69
|
+
|
|
70
|
+
it 'returns an equivalent relation to the unoptimized operation' do
|
|
71
|
+
should == object
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it_should_behave_like 'an optimize method'
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
context 'containing an empty relation when optimized' do
|
|
78
|
+
let(:operand) { Algebra::Restriction.new(relation, Function::Proposition::Contradiction.instance) }
|
|
79
|
+
let(:attributes) { [ :id ] }
|
|
80
|
+
|
|
81
|
+
it { should eql(Relation::Empty.new(object.header)) }
|
|
82
|
+
|
|
83
|
+
it 'returns an equivalent relation to the unoptimized operation' do
|
|
84
|
+
should == object
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it 'does not execute body#each' do
|
|
88
|
+
body.should_not_receive(:each)
|
|
89
|
+
subject
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it_should_behave_like 'an optimize method'
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
context 'containing an optimizable relation' do
|
|
96
|
+
let(:operand) { Algebra::Restriction.new(relation, Function::Proposition::Tautology.instance) }
|
|
97
|
+
let(:attributes) { [ :id ] }
|
|
98
|
+
|
|
99
|
+
it { should_not equal(object) }
|
|
100
|
+
|
|
101
|
+
it { should be_kind_of(described_class) }
|
|
102
|
+
|
|
103
|
+
its(:operand) { should equal(relation) }
|
|
104
|
+
|
|
105
|
+
its(:header) { should == object.header }
|
|
106
|
+
|
|
107
|
+
it 'returns an equivalent relation to the unoptimized operation' do
|
|
108
|
+
should == object
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it 'does not execute body#each' do
|
|
112
|
+
body.should_not_receive(:each)
|
|
113
|
+
subject
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
it_should_behave_like 'an optimize method'
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
context 'containing a projection' do
|
|
120
|
+
let(:operand) { relation.project([ :id, :name ]) }
|
|
121
|
+
let(:attributes) { [ :id ] }
|
|
122
|
+
|
|
123
|
+
it { should_not equal(object) }
|
|
124
|
+
|
|
125
|
+
it { should be_kind_of(described_class) }
|
|
126
|
+
|
|
127
|
+
its(:operand) { should equal(relation) }
|
|
128
|
+
|
|
129
|
+
its(:header) { should == object.header }
|
|
130
|
+
|
|
131
|
+
it 'returns an equivalent relation to the unoptimized operation' do
|
|
132
|
+
should == object
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
it 'does not execute body#each' do
|
|
136
|
+
body.should_not_receive(:each)
|
|
137
|
+
subject
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
it_should_behave_like 'an optimize method'
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
context 'containing a set operation' do
|
|
144
|
+
let(:left) { Relation.new([ [ :id, Integer ], [ :name, String ] ], LazyEnumerable.new([ [ 1, 'Dan Kubb' ] ])) }
|
|
145
|
+
let(:right) { Relation.new([ [ :id, Integer ], [ :name, String ] ], LazyEnumerable.new([ [ 2, 'Dan Kubb' ] ])) }
|
|
146
|
+
let(:operand) { left.union(right) }
|
|
147
|
+
let(:attributes) { [ :name ] }
|
|
148
|
+
|
|
149
|
+
it 'pushes the object to each relation' do
|
|
150
|
+
should eql(Algebra::Union.new(
|
|
151
|
+
described_class.new(left, object.header),
|
|
152
|
+
described_class.new(right, object.header)
|
|
153
|
+
))
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
it 'returns an equivalent relation to the unoptimized operation' do
|
|
157
|
+
should == object
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
it 'does not execute body#each' do
|
|
161
|
+
body.should_not_receive(:each)
|
|
162
|
+
subject
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
it_should_behave_like 'an optimize method'
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
context 'containing a set operation containing a projection of relations' do
|
|
169
|
+
let(:left_body) { LazyEnumerable.new([ [ 1, 'Dan Kubb', 35 ] ]) }
|
|
170
|
+
let(:right_body) { LazyEnumerable.new([ [ 2, 'Dan Kubb', 35 ] ]) }
|
|
171
|
+
let(:left) { Relation.new(header, left_body) }
|
|
172
|
+
let(:right) { Relation.new(header, right_body) }
|
|
173
|
+
let(:operand) { left.project([ :id, :name ]).union(right.project([ :id, :name ])) }
|
|
174
|
+
let(:attributes) { [ :name ] }
|
|
175
|
+
|
|
176
|
+
before do
|
|
177
|
+
# skip dup of the left and right body to avoid clearing the method stubs
|
|
178
|
+
left_body.stub!(:frozen?).and_return(true)
|
|
179
|
+
right_body.stub!(:frozen?).and_return(true)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
it 'pushes the object to each relation, and combine the nested objects' do
|
|
183
|
+
should eql(left.project([ :name ]).union(right.project([ :name ])))
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
it 'returns an equivalent relation to the unoptimized operation' do
|
|
187
|
+
should == object
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
it 'does not execute left_body#each' do
|
|
191
|
+
pending 'TODO: should only compare left and right with #eql? if they are materialized' do
|
|
192
|
+
left_body.should_not_receive(:each)
|
|
193
|
+
subject
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
it 'does not execute right_body#each' do
|
|
198
|
+
pending 'TODO: should only compare left and right with #eql? if they are materialized' do
|
|
199
|
+
right_body.should_not_receive(:each)
|
|
200
|
+
subject
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
it_should_behave_like 'an optimize method'
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
context 'containing a set operation containing a projection of materialized relations' do
|
|
208
|
+
let(:left_body) { [ [ 1, 'Dan Kubb', 35 ] ] }
|
|
209
|
+
let(:right_body) { [ [ 2, 'Dan Kubb', 35 ] ] }
|
|
210
|
+
let(:left) { Relation.new(header, left_body) }
|
|
211
|
+
let(:right) { Relation.new(header, right_body) }
|
|
212
|
+
let(:operand) { left.project([ :id, :name ]).union(right.project([ :id, :name ])) }
|
|
213
|
+
let(:attributes) { [ :name ] }
|
|
214
|
+
|
|
215
|
+
it 'pushes the object to each relation, and combine the nested objects, then materializes' do
|
|
216
|
+
should eql(Relation.new([ [ :name, String ] ], [ [ 'Dan Kubb' ] ]))
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
it 'returns an equivalent relation to the unoptimized operation' do
|
|
220
|
+
should == object
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
it 'executes left_body#each' do
|
|
224
|
+
pending 'TODO: make sure this is only received once'
|
|
225
|
+
left_body.should_receive(:each)
|
|
226
|
+
subject
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
it 'executes right_body#each' do
|
|
230
|
+
pending 'TODO: make sure this is only received once'
|
|
231
|
+
right_body.should_receive(:each)
|
|
232
|
+
subject
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
it_should_behave_like 'an optimize method'
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
context 'containing a materialized relation' do
|
|
239
|
+
let(:operand) { Relation.new(header, [ [ 1, 'Dan Kubb', 35 ] ]) }
|
|
240
|
+
let(:attributes) { [ :id ] }
|
|
241
|
+
|
|
242
|
+
it { should eql(Relation::Materialized.new([ [ :id, Integer ] ], [ [ 1 ] ])) }
|
|
243
|
+
|
|
244
|
+
it 'returns an equivalent relation to the unoptimized operation' do
|
|
245
|
+
should == object
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
it_should_behave_like 'an optimize method'
|
|
249
|
+
end
|
|
250
|
+
end
|
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe Algebra::Rename, '#optimize' do
|
|
6
|
+
subject { object.optimize }
|
|
7
|
+
|
|
8
|
+
let(:body) { LazyEnumerable.new([ [ 1, 'Dan Kubb' ] ]) }
|
|
9
|
+
let(:relation) { Relation.new([ [ :id, Integer ], [ :name, String ] ], body) }
|
|
10
|
+
let(:operand) { relation }
|
|
11
|
+
let(:aliases) { { :id => :other_id } }
|
|
12
|
+
let(:object) { described_class.new(operand, aliases) }
|
|
13
|
+
|
|
14
|
+
context 'containing a relation' do
|
|
15
|
+
it { should equal(object) }
|
|
16
|
+
|
|
17
|
+
it 'does not execute body#each' do
|
|
18
|
+
body.should_not_receive(:each)
|
|
19
|
+
subject
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it_should_behave_like 'an optimize method'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
context 'containing an empty relation' do
|
|
26
|
+
let(:operand) { Relation::Empty.new(relation.header) }
|
|
27
|
+
|
|
28
|
+
it { should eql(Relation::Empty.new(object.header)) }
|
|
29
|
+
|
|
30
|
+
it 'returns an equivalent relation to the unoptimized operation' do
|
|
31
|
+
should == object
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'does not execute body#each' do
|
|
35
|
+
body.should_not_receive(:each)
|
|
36
|
+
subject
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it_should_behave_like 'an optimize method'
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
context 'containing an optimizable relation' do
|
|
43
|
+
let(:operand) { relation.project(relation.header) }
|
|
44
|
+
|
|
45
|
+
it { should_not equal(object) }
|
|
46
|
+
|
|
47
|
+
it { should be_kind_of(described_class) }
|
|
48
|
+
|
|
49
|
+
it 'sets aliases the same as the original object' do
|
|
50
|
+
subject.aliases.should == object.aliases
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
its(:operand) { should equal(relation) }
|
|
54
|
+
|
|
55
|
+
it 'returns an equivalent relation to the unoptimized operation' do
|
|
56
|
+
should == object
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it 'does not execute body#each' do
|
|
60
|
+
body.should_not_receive(:each)
|
|
61
|
+
subject
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it_should_behave_like 'an optimize method'
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
context 'containing a object operation' do
|
|
68
|
+
let(:operand) { described_class.new(relation, :id => :other_id) }
|
|
69
|
+
let(:aliases) { { :name => :other_name } }
|
|
70
|
+
|
|
71
|
+
it { should_not equal(object) }
|
|
72
|
+
|
|
73
|
+
it { should be_kind_of(described_class) }
|
|
74
|
+
|
|
75
|
+
it 'sets aliases as a union of both aliases' do
|
|
76
|
+
subject.aliases.should == described_class::Aliases.coerce(
|
|
77
|
+
relation.header,
|
|
78
|
+
:id => :other_id,
|
|
79
|
+
:name => :other_name
|
|
80
|
+
)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
its(:operand) { should equal(relation) }
|
|
84
|
+
|
|
85
|
+
it 'returns an equivalent relation to the unoptimized operation' do
|
|
86
|
+
should == object
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it 'does not execute body#each' do
|
|
90
|
+
body.should_not_receive(:each)
|
|
91
|
+
subject
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it_should_behave_like 'an optimize method'
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
context 'containing a object operation with overlapping aliases' do
|
|
98
|
+
let(:operand) { described_class.new(relation, :id => :other_id) }
|
|
99
|
+
let(:aliases) { { :other_id => :another_id } }
|
|
100
|
+
|
|
101
|
+
it { should_not equal(object) }
|
|
102
|
+
|
|
103
|
+
it { should be_kind_of(described_class) }
|
|
104
|
+
|
|
105
|
+
it 'sets aliases as a union of both aliases' do
|
|
106
|
+
subject.aliases.should == described_class::Aliases.coerce(
|
|
107
|
+
relation.header,
|
|
108
|
+
:id => :another_id
|
|
109
|
+
)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
its(:operand) { should equal(relation) }
|
|
113
|
+
|
|
114
|
+
it 'returns an equivalent relation to the unoptimized operation' do
|
|
115
|
+
should == object
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
it 'does not execute body#each' do
|
|
119
|
+
body.should_not_receive(:each)
|
|
120
|
+
subject
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it_should_behave_like 'an optimize method'
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
context 'containing an inverse object operation' do
|
|
127
|
+
let(:operand) { described_class.new(relation, :id => :other_id) }
|
|
128
|
+
let(:aliases) { { :other_id => :id } }
|
|
129
|
+
|
|
130
|
+
it { should equal(relation) }
|
|
131
|
+
|
|
132
|
+
it 'returns an equivalent relation to the unoptimized operation' do
|
|
133
|
+
should == object
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
it 'does not execute body#each' do
|
|
137
|
+
body.should_not_receive(:each)
|
|
138
|
+
subject
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
it_should_behave_like 'an optimize method'
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
context 'containing a projection' do
|
|
145
|
+
let(:operand) { relation.project([ :id ]) }
|
|
146
|
+
|
|
147
|
+
it { should be_kind_of(Algebra::Projection) }
|
|
148
|
+
|
|
149
|
+
its(:operand) { should eql(described_class.new(relation, aliases)) }
|
|
150
|
+
|
|
151
|
+
its(:header) { should == [ [ :other_id, Integer ] ] }
|
|
152
|
+
|
|
153
|
+
it 'returns an equivalent relation to the unoptimized operation' do
|
|
154
|
+
should == object
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
it 'does not execute body#each' do
|
|
158
|
+
body.should_not_receive(:each)
|
|
159
|
+
subject
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
it_should_behave_like 'an optimize method'
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
context 'containing a projection, containing a object that cancels out' do
|
|
166
|
+
let(:operand) { relation.rename(:id => :other_id).project([ :other_id ]) }
|
|
167
|
+
let(:aliases) { { :other_id => :id } }
|
|
168
|
+
|
|
169
|
+
it 'pushes the object before the projection, and then cancel it out' do
|
|
170
|
+
should eql(relation.project([ :id ]))
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
it 'returns an equivalent relation to the unoptimized operation' do
|
|
174
|
+
should == object
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
it 'does not execute body#each' do
|
|
178
|
+
body.should_not_receive(:each)
|
|
179
|
+
subject
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
it_should_behave_like 'an optimize method'
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
context 'containing a restriction' do
|
|
186
|
+
let(:operand) { relation.restrict { |r| r.id.eq(1) } }
|
|
187
|
+
|
|
188
|
+
it { should be_kind_of(Algebra::Restriction) }
|
|
189
|
+
|
|
190
|
+
its(:operand) { should eql(described_class.new(relation, aliases)) }
|
|
191
|
+
|
|
192
|
+
its(:header) { should == [ [ :other_id, Integer ], [ :name, String ] ] }
|
|
193
|
+
|
|
194
|
+
it 'returns an equivalent relation to the unoptimized operation' do
|
|
195
|
+
should == object
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
it 'does not execute body#each' do
|
|
199
|
+
body.should_not_receive(:each)
|
|
200
|
+
subject
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
it_should_behave_like 'an optimize method'
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
context 'containing a restriction, containing a object that cancels out' do
|
|
207
|
+
let(:operand) { relation.rename(:id => :other_id).restrict { |r| r.other_id.eq(1) } }
|
|
208
|
+
let(:aliases) { { :other_id => :id } }
|
|
209
|
+
|
|
210
|
+
it 'pushes the object before the restriction, and then cancel it out' do
|
|
211
|
+
should eql(relation.restrict { |r| r.id.eq(1) })
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
it 'returns an equivalent relation to the unoptimized operation' do
|
|
215
|
+
should == object
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
it 'does not execute body#each' do
|
|
219
|
+
body.should_not_receive(:each)
|
|
220
|
+
subject
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
it_should_behave_like 'an optimize method'
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
context 'containing a set operation' do
|
|
227
|
+
let(:left) { Relation.new([ [ :id, Integer ], [ :name, String ] ], LazyEnumerable.new([ [ 1, 'Dan Kubb' ] ])) }
|
|
228
|
+
let(:right) { Relation.new([ [ :id, Integer ], [ :name, String ] ], LazyEnumerable.new([ [ 2, 'Dan Kubb' ] ])) }
|
|
229
|
+
let(:operand) { left.union(right) }
|
|
230
|
+
|
|
231
|
+
it 'pushes the object to each relation' do
|
|
232
|
+
should eql(left.rename(aliases).union(right.rename(aliases)))
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
it 'returns an equivalent relation to the unoptimized operation' do
|
|
236
|
+
should == object
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
it 'does not execute body#each' do
|
|
240
|
+
body.should_not_receive(:each)
|
|
241
|
+
subject
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
it_should_behave_like 'an optimize method'
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
context 'containing a set operation, containing a object that cancels out' do
|
|
248
|
+
let(:left) { Relation.new([ [ :id, Integer ], [ :name, String ] ], LazyEnumerable.new([ [ 1, 'Dan Kubb' ] ])) }
|
|
249
|
+
let(:right) { Relation.new([ [ :id, Integer ], [ :name, String ] ], LazyEnumerable.new([ [ 2, 'Dan Kubb' ] ])) }
|
|
250
|
+
let(:operand) { left.rename(:id => :other_id).union(right.rename(:id => :other_id)) }
|
|
251
|
+
let(:aliases) { { :other_id => :id } }
|
|
252
|
+
|
|
253
|
+
it 'pushes the object to each relation, then cancel it out' do
|
|
254
|
+
should eql(left.union(right))
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
it 'returns an equivalent relation to the unoptimized operation' do
|
|
258
|
+
should == object
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
it 'does not execute body#each' do
|
|
262
|
+
body.should_not_receive(:each)
|
|
263
|
+
subject
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
it_should_behave_like 'an optimize method'
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
context 'containing a reverse operation' do
|
|
270
|
+
let(:limit) { relation.sort_by { |r| [ r.id, r.name ] }.take(2) }
|
|
271
|
+
let(:operand) { limit.reverse }
|
|
272
|
+
|
|
273
|
+
it 'pushes the object under the order, limit and reverse' do
|
|
274
|
+
should eql(relation.rename(aliases).sort_by { |r| [ r.other_id, r.name ] }.take(2).reverse)
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
it 'returns an equivalent relation to the unoptimized operation' do
|
|
278
|
+
should == object
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
it 'does not execute body#each' do
|
|
282
|
+
body.should_not_receive(:each)
|
|
283
|
+
subject
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
it_should_behave_like 'an optimize method'
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
context 'containing a reverse operation, containing a object that cancels out' do
|
|
290
|
+
let(:limit) { relation.sort_by { |r| [ r.id, r.name ] }.take(2) }
|
|
291
|
+
let(:operand) { limit.rename(:id => :other_id).reverse }
|
|
292
|
+
let(:aliases) { { :other_id => :id } }
|
|
293
|
+
|
|
294
|
+
it 'pushes the object under the order, limit and reverse, and then cancel it out' do
|
|
295
|
+
should eql(relation.sort_by { |r| [ r.id, r.name ] }.take(2).reverse)
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
it 'returns an equivalent relation to the unoptimized operation' do
|
|
299
|
+
should == object
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
it 'does not execute body#each' do
|
|
303
|
+
body.should_not_receive(:each)
|
|
304
|
+
subject
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
it_should_behave_like 'an optimize method'
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
context 'containing an order operation' do
|
|
311
|
+
let(:operand) { relation.sort_by { |r| [ r.id, r.name ] } }
|
|
312
|
+
|
|
313
|
+
it 'pushes the object under the order' do
|
|
314
|
+
should eql(relation.rename(aliases).sort_by { |r| [ r.other_id, r.name ] })
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
it 'returns an equivalent relation to the unoptimized operation' do
|
|
318
|
+
should == object
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
it 'does not execute body#each' do
|
|
322
|
+
body.should_not_receive(:each)
|
|
323
|
+
subject
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
it_should_behave_like 'an optimize method'
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
context 'containing an order operation, containing a object that cancels out' do
|
|
330
|
+
let(:operand) { relation.rename(:id => :other_id).sort_by { |r| [ r.other_id, r.name ] } }
|
|
331
|
+
let(:aliases) { { :other_id => :id } }
|
|
332
|
+
|
|
333
|
+
it 'pushes the object under the order, and then cancel it out' do
|
|
334
|
+
should eql(relation.sort_by { |r| [ r.id, r.name ] })
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
it 'returns an equivalent relation to the unoptimized operation' do
|
|
338
|
+
should == object
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
it 'does not execute body#each' do
|
|
342
|
+
body.should_not_receive(:each)
|
|
343
|
+
subject
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
it_should_behave_like 'an optimize method'
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
context 'containing a limit operation' do
|
|
350
|
+
let(:order) { relation.sort_by { |r| [ r.id, r.name ] } }
|
|
351
|
+
let(:operand) { order.take(2) }
|
|
352
|
+
|
|
353
|
+
it 'pushes the object under the limit and order' do
|
|
354
|
+
should eql(relation.rename(aliases).sort_by { |r| [ r.other_id, r.name ] }.take(2))
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
it 'returns an equivalent relation to the unoptimized operation' do
|
|
358
|
+
should == object
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
it 'does not execute body#each' do
|
|
362
|
+
body.should_not_receive(:each)
|
|
363
|
+
subject
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
it_should_behave_like 'an optimize method'
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
context 'containing a limit operation, containing a object that cancels out' do
|
|
370
|
+
let(:order) { relation.sort_by { |r| [ r.id, r.name ] } }
|
|
371
|
+
let(:operand) { order.rename(:id => :other_id).take(2) }
|
|
372
|
+
let(:aliases) { { :other_id => :id } }
|
|
373
|
+
|
|
374
|
+
it 'pushes the object under the limit and order, and then cancel it out' do
|
|
375
|
+
should eql(relation.sort_by { |r| [ r.id, r.name ] }.take(2))
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
it 'returns an equivalent relation to the unoptimized operation' do
|
|
379
|
+
should == object
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
it 'does not execute body#each' do
|
|
383
|
+
body.should_not_receive(:each)
|
|
384
|
+
subject
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
it_should_behave_like 'an optimize method'
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
context 'containing an offset operation' do
|
|
391
|
+
let(:order) { relation.sort_by { |r| [ r.id, r.name ] } }
|
|
392
|
+
let(:operand) { order.drop(1) }
|
|
393
|
+
|
|
394
|
+
it 'pushes the object under the offset and order' do
|
|
395
|
+
should eql(relation.rename(aliases).sort_by { |r| [ r.other_id, r.name ] }.drop(1))
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
it 'returns an equivalent relation to the unoptimized operation' do
|
|
399
|
+
should == object
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
it 'does not execute body#each' do
|
|
403
|
+
body.should_not_receive(:each)
|
|
404
|
+
subject
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
it_should_behave_like 'an optimize method'
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
context 'containing an offset operation, containing a object that cancels out' do
|
|
411
|
+
let(:order) { relation.sort_by { |r| [ r.id, r.name ] } }
|
|
412
|
+
let(:operand) { order.rename(:id => :other_id).drop(1) }
|
|
413
|
+
let(:aliases) { { :other_id => :id } }
|
|
414
|
+
|
|
415
|
+
it 'pushes the object under the offset and order, and then cancel it out' do
|
|
416
|
+
should eql(relation.sort_by { |r| [ r.id, r.name ] }.drop(1))
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
it 'returns an equivalent relation to the unoptimized operation' do
|
|
420
|
+
should == object
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
it 'does not execute body#each' do
|
|
424
|
+
body.should_not_receive(:each)
|
|
425
|
+
subject
|
|
426
|
+
end
|
|
427
|
+
|
|
428
|
+
it_should_behave_like 'an optimize method'
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
context 'containing a materialized relation' do
|
|
432
|
+
let(:operand) { Relation.new([ [ :id, Integer ], [ :name, String ] ], [ [ 1, 'Dan Kubb' ] ]) }
|
|
433
|
+
|
|
434
|
+
it { should eql(Relation::Materialized.new([ [ :other_id, Integer ], [ :name, String ] ], [ [ 1, 'Dan Kubb' ] ])) }
|
|
435
|
+
|
|
436
|
+
it 'returns an equivalent relation to the unoptimized operation' do
|
|
437
|
+
should == object
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
it_should_behave_like 'an optimize method'
|
|
441
|
+
end
|
|
442
|
+
end
|