From 0433b054eebd5a53ff6c5f35383a6c0aed0015b2 Mon Sep 17 00:00:00 2001 From: Ernie Miller Date: Tue, 30 Mar 2010 15:32:39 -0400 Subject: Tests for notmatches and notin, and fixes for issues found in tests --- lib/arel/algebra/predicates.rb | 23 +++++++++++---- lib/arel/engines/memory/predicates.rb | 53 +++++++++++++++++++++++++++++++++-- lib/arel/engines/sql/predicates.rb | 6 ++-- 3 files changed, 71 insertions(+), 11 deletions(-) (limited to 'lib') diff --git a/lib/arel/algebra/predicates.rb b/lib/arel/algebra/predicates.rb index 43606139b0..be80f2a987 100644 --- a/lib/arel/algebra/predicates.rb +++ b/lib/arel/algebra/predicates.rb @@ -14,19 +14,28 @@ module Arel end end - class Grouped < Predicate - attributes :operator, :operand1, :operands2 + class Polyadic < Predicate + attributes :operator, :operand1, :additional_operands - def initialize(operator, operand1, *operands2) + def initialize(operator, operand1, *additional_operands) @operator = operator @operand1 = operand1 - @operands2 = operands2.uniq + @additional_operands = additional_operands.uniq end def ==(other) self.class === other and + @operator == operator and @operand1 == other.operand1 and - same_elements?(@operands2, other.operands2) + same_elements?(@additional_operands, other.additional_operands) + end + + def bind(relation) + self.class.new( + operator, + operand1.find_correlate_in(relation), + *additional_operands.map {|o| o.find_correlate_in(relation)} + ) end private @@ -43,6 +52,10 @@ module Arel class Unary < Predicate attributes :operand deriving :initialize, :== + + def bind(relation) + self.class.new(operand.find_correlate_in(relation)) + end end class Binary < Predicate diff --git a/lib/arel/engines/memory/predicates.rb b/lib/arel/engines/memory/predicates.rb index d0963e2f74..c0ee862626 100644 --- a/lib/arel/engines/memory/predicates.rb +++ b/lib/arel/engines/memory/predicates.rb @@ -5,6 +5,49 @@ module Arel operand1.eval(row).send(operator, operand2.eval(row)) end end + + class Unary < Predicate + def eval(row) + operand.eval(row).send(operator) + end + end + + class Not < Unary + def operator; '!' end + end + + class CompoundPredicate < Binary + def eval(row) + eval "operand1.eval(row) #{operator} operand2.eval(row)" + end + end + + class Or < CompoundPredicate + def operator; :or end + end + + class And < CompoundPredicate + def operator; :and end + end + + class GroupedPredicate < Polyadic + def eval(row) + group = additional_operands.inject([]) do |results, operand| + results << operator.new(operand1, operand) + end + group.send(compounder) do |operation| + operation.eval(row) + end + end + end + + class Any < GroupedPredicate + def compounder; :any? end + end + + class All < GroupedPredicate + def compounder; :all? end + end class Equality < Binary def operator; :== end @@ -37,16 +80,20 @@ module Arel end class NotMatch < Binary - def operator; :!~ end + def eval(row) + operand1.eval(row) !~ operand2.eval(row) + end end class In < Binary - def operator; :include? end + def eval(row) + operand2.eval(row).include?(operand1.eval(row)) + end end class NotIn < Binary def eval(row) - !(operand1.eval(row).include?(operand2.eval(row))) + !(operand2.eval(row).include?(operand1.eval(row))) end end end diff --git a/lib/arel/engines/sql/predicates.rb b/lib/arel/engines/sql/predicates.rb index 29bc74c605..b459168620 100644 --- a/lib/arel/engines/sql/predicates.rb +++ b/lib/arel/engines/sql/predicates.rb @@ -30,11 +30,11 @@ module Arel def predicate_sql; "AND" end end - class GroupedPredicate < Grouped + class GroupedPredicate < Polyadic def to_sql(formatter = nil) "(" + - operands2.inject([]) { |predicates, operand| - predicates << operator.new(operand1, operand).to_sql + additional_operands.inject([]) { |predicates, operand| + predicates << operator.new(operand1, operand).to_sql(formatter) }.join(" #{predicate_sql} ") + ")" end -- cgit v1.2.3