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,373 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module Axiom
|
|
4
|
+
class Optimizer
|
|
5
|
+
module Algebra
|
|
6
|
+
|
|
7
|
+
# Abstract base class representing Restriction optimizations
|
|
8
|
+
class Restriction < Relation::Operation::Unary
|
|
9
|
+
|
|
10
|
+
# The optimized predicate
|
|
11
|
+
#
|
|
12
|
+
# @return [Function]
|
|
13
|
+
#
|
|
14
|
+
# @api private
|
|
15
|
+
attr_reader :predicate
|
|
16
|
+
|
|
17
|
+
# Initialize an Restriction optimizer
|
|
18
|
+
#
|
|
19
|
+
# @return [undefined]
|
|
20
|
+
#
|
|
21
|
+
# @api private
|
|
22
|
+
def initialize(*)
|
|
23
|
+
super
|
|
24
|
+
@predicate = Function.optimize_operand(operation.predicate)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
# Wrap the operand's operand in a Restriction
|
|
30
|
+
#
|
|
31
|
+
# @return [Restriction]
|
|
32
|
+
#
|
|
33
|
+
# @api private
|
|
34
|
+
def wrap_operand(operand = operand.operand)
|
|
35
|
+
operand.restrict(predicate)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Return true if the predicate is a true value
|
|
39
|
+
#
|
|
40
|
+
# @return [Boolean]
|
|
41
|
+
#
|
|
42
|
+
# @api private
|
|
43
|
+
def constant_true_predicate?
|
|
44
|
+
predicate.equal?(true)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Return true if the predicate is not callable, and not a true value
|
|
48
|
+
#
|
|
49
|
+
# In the system anything not a Tautology or true is false.
|
|
50
|
+
#
|
|
51
|
+
# @return [Boolean]
|
|
52
|
+
#
|
|
53
|
+
# @api private
|
|
54
|
+
def constant_false_predicate?
|
|
55
|
+
! (predicate.respond_to?(:call) || constant_true_predicate?)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Optimize when the predicate is a tautology
|
|
59
|
+
class Tautology < self
|
|
60
|
+
|
|
61
|
+
# Test if the predicate is a tautology
|
|
62
|
+
#
|
|
63
|
+
# @return [Boolean]
|
|
64
|
+
#
|
|
65
|
+
# @api private
|
|
66
|
+
def optimizable?
|
|
67
|
+
predicate.equal?(Axiom::Function::Proposition::Tautology.instance) ||
|
|
68
|
+
constant_true_predicate?
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# A Restriction with a tautology is a noop
|
|
72
|
+
#
|
|
73
|
+
# @return [Relation]
|
|
74
|
+
#
|
|
75
|
+
# @api private
|
|
76
|
+
def optimize
|
|
77
|
+
operand
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
end # class Tautology
|
|
81
|
+
|
|
82
|
+
# Optimize when the predicate is a contradiction
|
|
83
|
+
class Contradiction < self
|
|
84
|
+
|
|
85
|
+
# Test if the predicate is a contradiction
|
|
86
|
+
#
|
|
87
|
+
# @return [Boolean]
|
|
88
|
+
#
|
|
89
|
+
# @api private
|
|
90
|
+
def optimizable?
|
|
91
|
+
predicate.equal?(Axiom::Function::Proposition::Contradiction.instance) ||
|
|
92
|
+
constant_false_predicate?
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# A Restriction with a contradiction matches nothing
|
|
96
|
+
#
|
|
97
|
+
# @return [Relation]
|
|
98
|
+
#
|
|
99
|
+
# @api private
|
|
100
|
+
def optimize
|
|
101
|
+
Axiom::Relation::Empty.new(operation.header, operation)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
end # class Contradiction
|
|
105
|
+
|
|
106
|
+
# Optimize when the operand is a Restriction
|
|
107
|
+
class RestrictionOperand < self
|
|
108
|
+
|
|
109
|
+
# Test if the operand is a Restriction
|
|
110
|
+
#
|
|
111
|
+
# @return [Boolean]
|
|
112
|
+
#
|
|
113
|
+
# @api private
|
|
114
|
+
def optimizable?
|
|
115
|
+
operand.kind_of?(operation.class)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# Flatten nested Restrictions into a single Restriction
|
|
119
|
+
#
|
|
120
|
+
# @return [Restriction]
|
|
121
|
+
#
|
|
122
|
+
# @api private
|
|
123
|
+
def optimize
|
|
124
|
+
wrap_operand
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
private
|
|
128
|
+
|
|
129
|
+
# Join the operand and operation predicates and optimize them
|
|
130
|
+
#
|
|
131
|
+
# @return [Function]
|
|
132
|
+
#
|
|
133
|
+
# @api private
|
|
134
|
+
def predicate
|
|
135
|
+
operand.predicate.and(super).optimize
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
end # class RestrictionOperand
|
|
139
|
+
|
|
140
|
+
# Optimize when the operand is a combine operation
|
|
141
|
+
class CombinationOperand < self
|
|
142
|
+
|
|
143
|
+
# Test if the restriction is commutative
|
|
144
|
+
#
|
|
145
|
+
# @return [Boolean]
|
|
146
|
+
#
|
|
147
|
+
# @api private
|
|
148
|
+
def optimizable?
|
|
149
|
+
restriction_commutative?
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Distribute the restriction across the operation and apply to the operands
|
|
153
|
+
#
|
|
154
|
+
# @return [Restriction]
|
|
155
|
+
#
|
|
156
|
+
# @api private
|
|
157
|
+
def optimize
|
|
158
|
+
left_restriction.send(relation_method, right_restriction).restrict(partition.remainder)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
private
|
|
162
|
+
|
|
163
|
+
# Return a predicate partition for the restriction and operand headers
|
|
164
|
+
#
|
|
165
|
+
# @return [PredicatePartition]
|
|
166
|
+
#
|
|
167
|
+
# @api private
|
|
168
|
+
def partition
|
|
169
|
+
PredicatePartition.new(predicate, operand.left.header, operand.right.header)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# Test if the restriction can be distributed over the operation
|
|
173
|
+
#
|
|
174
|
+
# If the predicates for the left and right operands would match
|
|
175
|
+
# everything, there is no point in distributing the restriction
|
|
176
|
+
# across the operation, since it will not affect the result.
|
|
177
|
+
#
|
|
178
|
+
# @return [Boolean]
|
|
179
|
+
#
|
|
180
|
+
# @api private
|
|
181
|
+
def restriction_commutative?
|
|
182
|
+
! (partition_left_tautology? && partition_right_tautology?)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# Test if the predicate for the left operand would match everything
|
|
186
|
+
#
|
|
187
|
+
# @return [Boolean]
|
|
188
|
+
#
|
|
189
|
+
# @api private
|
|
190
|
+
def partition_left_tautology?
|
|
191
|
+
partition.left.equal?(Axiom::Function::Proposition::Tautology.instance)
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# Test if the predicate for the right operand would match everything
|
|
195
|
+
#
|
|
196
|
+
# @return [Boolean]
|
|
197
|
+
#
|
|
198
|
+
# @api private
|
|
199
|
+
def partition_right_tautology?
|
|
200
|
+
partition.right.equal?(Axiom::Function::Proposition::Tautology.instance)
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# Abstract method to return the relation method name
|
|
204
|
+
#
|
|
205
|
+
# @raise [NotImplementedError]
|
|
206
|
+
# raised when the subclass does not implement the method
|
|
207
|
+
#
|
|
208
|
+
# @api private
|
|
209
|
+
def relation_method
|
|
210
|
+
raise NotImplementedError, "#{self.class}#relation_method must be implemented"
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# Restrict the left operand with the left predicate partition
|
|
214
|
+
#
|
|
215
|
+
# @return [Restriction]
|
|
216
|
+
#
|
|
217
|
+
# @api private
|
|
218
|
+
def left_restriction
|
|
219
|
+
operand.left.restrict(partition.left)
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# Restrict the right operand with the right predicate partition
|
|
223
|
+
#
|
|
224
|
+
# @return [Restriction]
|
|
225
|
+
#
|
|
226
|
+
# @api private
|
|
227
|
+
def right_restriction
|
|
228
|
+
operand.right.restrict(partition.right)
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
memoize :partition
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
# Optimize when the operand is a Join
|
|
235
|
+
class JoinOperand < CombinationOperand
|
|
236
|
+
|
|
237
|
+
# Test if the operand is a Join and the restriction is commutative
|
|
238
|
+
#
|
|
239
|
+
# @return [Boolean]
|
|
240
|
+
#
|
|
241
|
+
# @api private
|
|
242
|
+
def optimizable?
|
|
243
|
+
operand.kind_of?(Axiom::Algebra::Join) && super
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
private
|
|
247
|
+
|
|
248
|
+
# Return the relation method name for a Join operation
|
|
249
|
+
#
|
|
250
|
+
# @return [Symbol]
|
|
251
|
+
#
|
|
252
|
+
# @api private
|
|
253
|
+
def relation_method
|
|
254
|
+
:join
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
end # class JoinOperand
|
|
258
|
+
|
|
259
|
+
# Optimize when the operand is a Product
|
|
260
|
+
class ProductOperand < CombinationOperand
|
|
261
|
+
|
|
262
|
+
# Test if the operand is a Join and the restriction is commutative
|
|
263
|
+
#
|
|
264
|
+
# @return [Boolean]
|
|
265
|
+
#
|
|
266
|
+
# @api private
|
|
267
|
+
def optimizable?
|
|
268
|
+
operand.kind_of?(Axiom::Algebra::Product) && super
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
private
|
|
272
|
+
|
|
273
|
+
# Return the relation method name for a Product operation
|
|
274
|
+
#
|
|
275
|
+
# @return [Symbol]
|
|
276
|
+
#
|
|
277
|
+
# @api private
|
|
278
|
+
|
|
279
|
+
def relation_method
|
|
280
|
+
:product
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
end # class ProductOperand
|
|
284
|
+
|
|
285
|
+
# Optimize when the operand is a Set
|
|
286
|
+
class SetOperand < self
|
|
287
|
+
|
|
288
|
+
# Test if the operand is a Restriction
|
|
289
|
+
#
|
|
290
|
+
# @return [Boolean]
|
|
291
|
+
#
|
|
292
|
+
# @api private
|
|
293
|
+
def optimizable?
|
|
294
|
+
operand.kind_of?(Axiom::Relation::Operation::Set)
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
# Wrap each operand in the Set in a Restriction
|
|
298
|
+
#
|
|
299
|
+
# @return [Set]
|
|
300
|
+
#
|
|
301
|
+
# @api private
|
|
302
|
+
def optimize
|
|
303
|
+
operand.class.new(wrap_left, wrap_right)
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
private
|
|
307
|
+
|
|
308
|
+
# Utility method to wrap the left operand in a Restriction
|
|
309
|
+
#
|
|
310
|
+
# @return [Restriction]
|
|
311
|
+
#
|
|
312
|
+
# @api private
|
|
313
|
+
def wrap_left
|
|
314
|
+
wrap_operand(operand.left)
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
# Utility method to wrap the right operand in a Restriction
|
|
318
|
+
#
|
|
319
|
+
# @return [Restriction]
|
|
320
|
+
#
|
|
321
|
+
# @api private
|
|
322
|
+
def wrap_right
|
|
323
|
+
wrap_operand(operand.right)
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
end # class SetOperand
|
|
327
|
+
|
|
328
|
+
# Optimize when the operand is an Order
|
|
329
|
+
class OrderOperand < self
|
|
330
|
+
include Relation::Operation::Unary::OrderOperand
|
|
331
|
+
end # class OrderOperand
|
|
332
|
+
|
|
333
|
+
# Optimize when operand is optimizable
|
|
334
|
+
class UnoptimizedOperand < self
|
|
335
|
+
include Function::Unary::UnoptimizedOperand
|
|
336
|
+
|
|
337
|
+
# Test if the operand is unoptimized
|
|
338
|
+
#
|
|
339
|
+
# @return [Boolean]
|
|
340
|
+
#
|
|
341
|
+
# @api private
|
|
342
|
+
def optimizable?
|
|
343
|
+
super || ! predicate.equal?(operation.predicate)
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
# Return a Restriction with an optimized operand
|
|
347
|
+
#
|
|
348
|
+
# @return [Rename]
|
|
349
|
+
#
|
|
350
|
+
# @api private
|
|
351
|
+
def optimize
|
|
352
|
+
wrap_operand(operand)
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
end # class UnoptimizedOperand
|
|
356
|
+
|
|
357
|
+
Axiom::Algebra::Restriction.optimizer = chain(
|
|
358
|
+
Tautology,
|
|
359
|
+
Contradiction,
|
|
360
|
+
RestrictionOperand,
|
|
361
|
+
JoinOperand,
|
|
362
|
+
ProductOperand,
|
|
363
|
+
SetOperand,
|
|
364
|
+
OrderOperand,
|
|
365
|
+
EmptyOperand,
|
|
366
|
+
MaterializedOperand,
|
|
367
|
+
UnoptimizedOperand
|
|
368
|
+
)
|
|
369
|
+
|
|
370
|
+
end # class Restriction
|
|
371
|
+
end # module Algebra
|
|
372
|
+
end # class Optimizer
|
|
373
|
+
end # module Axiom
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module Axiom
|
|
4
|
+
class Optimizer
|
|
5
|
+
module Algebra
|
|
6
|
+
|
|
7
|
+
# Abstract base class representing Summarization optimizations
|
|
8
|
+
class Summarization < Relation::Operation::Unary
|
|
9
|
+
|
|
10
|
+
# The optimized summarize_per relation
|
|
11
|
+
#
|
|
12
|
+
# @return [Relation]
|
|
13
|
+
#
|
|
14
|
+
# @api private
|
|
15
|
+
attr_reader :summarize_per
|
|
16
|
+
|
|
17
|
+
# The optimized summarizers
|
|
18
|
+
#
|
|
19
|
+
# @return [Hash{Attribute => Function}]
|
|
20
|
+
#
|
|
21
|
+
# @api private
|
|
22
|
+
attr_reader :summarizers
|
|
23
|
+
|
|
24
|
+
# Initialize a Summarization optimizer
|
|
25
|
+
#
|
|
26
|
+
# @return [undefined]
|
|
27
|
+
#
|
|
28
|
+
# @api private
|
|
29
|
+
def initialize(*)
|
|
30
|
+
super
|
|
31
|
+
@summarize_per = optimize_summarize_per
|
|
32
|
+
@summarizers = optimize_summarizers
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
# Optimize the summarize per relation
|
|
38
|
+
#
|
|
39
|
+
# @return [Relation]
|
|
40
|
+
#
|
|
41
|
+
# @api private
|
|
42
|
+
def optimize_summarize_per
|
|
43
|
+
operation.summarize_per.optimize
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Optimize the summarizers
|
|
47
|
+
#
|
|
48
|
+
# @return [Hash{Attribute => Function}]
|
|
49
|
+
#
|
|
50
|
+
# @api private
|
|
51
|
+
def optimize_summarizers
|
|
52
|
+
Function.optimize_functions(operation.summarizers)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Wrap the operand's operand in a Summarization
|
|
56
|
+
#
|
|
57
|
+
# @return [Summarization]
|
|
58
|
+
#
|
|
59
|
+
# @api private
|
|
60
|
+
def wrap_operand(operand = operand.operand)
|
|
61
|
+
operand.summarize(summarize_per, summarizers)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Optimize when the operand is Empty
|
|
65
|
+
class EmptyOperand < self
|
|
66
|
+
|
|
67
|
+
# Return the default value for a function
|
|
68
|
+
#
|
|
69
|
+
# @param [Object] function
|
|
70
|
+
#
|
|
71
|
+
# @return [Object]
|
|
72
|
+
#
|
|
73
|
+
# @api private
|
|
74
|
+
def self.extension_default(function)
|
|
75
|
+
if function.respond_to?(:default)
|
|
76
|
+
function.finalize(function.default)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Test if the operand is empty
|
|
81
|
+
#
|
|
82
|
+
# @return [Boolean]
|
|
83
|
+
#
|
|
84
|
+
# @api private
|
|
85
|
+
def optimizable?
|
|
86
|
+
operand.kind_of?(Axiom::Relation::Empty)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Return an extended relation with the same headers
|
|
90
|
+
#
|
|
91
|
+
# @return [Extension]
|
|
92
|
+
#
|
|
93
|
+
# @api private
|
|
94
|
+
def optimize
|
|
95
|
+
summarize_per.extend(extensions)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
private
|
|
99
|
+
|
|
100
|
+
# Return the extensions for the optimized relation
|
|
101
|
+
#
|
|
102
|
+
# @return [Hash{Attribute => #call}]
|
|
103
|
+
#
|
|
104
|
+
# @api private
|
|
105
|
+
def extensions
|
|
106
|
+
extensions = {}
|
|
107
|
+
operation.summarizers.each do |attribute, function|
|
|
108
|
+
extensions[attribute] = self.class.extension_default(function)
|
|
109
|
+
end
|
|
110
|
+
extensions
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
end # class EmptyOperand
|
|
114
|
+
|
|
115
|
+
# Optimize when the summarize_per is empty
|
|
116
|
+
class EmptySummarizePer < self
|
|
117
|
+
|
|
118
|
+
# Test if summarize_per is empty
|
|
119
|
+
#
|
|
120
|
+
# @return [Boolean]
|
|
121
|
+
#
|
|
122
|
+
# @api private
|
|
123
|
+
def optimizable?
|
|
124
|
+
summarize_per.kind_of?(Axiom::Relation::Empty)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Return an empty relation if there is nothing to summarize over
|
|
128
|
+
#
|
|
129
|
+
# @return [Relation::Empty]
|
|
130
|
+
#
|
|
131
|
+
# @api private
|
|
132
|
+
def optimize
|
|
133
|
+
Axiom::Relation::Empty.new(operation.header, operation)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
end # class EmptySummarizePer
|
|
137
|
+
|
|
138
|
+
# Optimize when the operand is an Order
|
|
139
|
+
class OrderOperand < self
|
|
140
|
+
include Relation::Operation::Unary::OrderOperand
|
|
141
|
+
end # class OrderOperand
|
|
142
|
+
|
|
143
|
+
# Optimize when operand is optimizable
|
|
144
|
+
class UnoptimizedOperand < self
|
|
145
|
+
include Function::Unary::UnoptimizedOperand
|
|
146
|
+
|
|
147
|
+
# Test if the operand is unoptimized
|
|
148
|
+
#
|
|
149
|
+
# @return [Boolean]
|
|
150
|
+
#
|
|
151
|
+
# @api private
|
|
152
|
+
def optimizable?
|
|
153
|
+
super ||
|
|
154
|
+
summarize_per_optimizable? ||
|
|
155
|
+
summarizers_optimizable?
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Return a Summarization with an optimized operand
|
|
159
|
+
#
|
|
160
|
+
# @return [Rename]
|
|
161
|
+
#
|
|
162
|
+
# @api private
|
|
163
|
+
def optimize
|
|
164
|
+
wrap_operand(operand)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
private
|
|
168
|
+
|
|
169
|
+
# Test if the summarize_per relation is optimizable
|
|
170
|
+
#
|
|
171
|
+
# @return [Boolean]
|
|
172
|
+
#
|
|
173
|
+
# @api private
|
|
174
|
+
def summarize_per_optimizable?
|
|
175
|
+
! summarize_per.equal?(operation.summarize_per)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# Test if the summarizers are optimizable
|
|
179
|
+
#
|
|
180
|
+
# @return [Boolean]
|
|
181
|
+
#
|
|
182
|
+
# @api private
|
|
183
|
+
def summarizers_optimizable?
|
|
184
|
+
! summarizers.eql?(operation.summarizers)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
end # class UnoptimizedOperand
|
|
188
|
+
|
|
189
|
+
Axiom::Algebra::Summarization.optimizer = chain(
|
|
190
|
+
EmptyOperand,
|
|
191
|
+
EmptySummarizePer,
|
|
192
|
+
OrderOperand,
|
|
193
|
+
MaterializedOperand,
|
|
194
|
+
UnoptimizedOperand
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
end # class Summarization
|
|
198
|
+
end # module Algebra
|
|
199
|
+
end # class Optimizer
|
|
200
|
+
end # module Axiom
|