aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Draper <matthew@trebex.net>2014-09-26 08:21:01 +0930
committerMatthew Draper <matthew@trebex.net>2014-09-26 08:21:01 +0930
commitcdae8216f582e035370b84edd236af7d22702e75 (patch)
tree6f607b2c312db046a488629f39bd8755b4cbc5c9
parentb57a11cb8abfca345f63084ce841c6f412c1156e (diff)
parentfef9ce493ec3eab3cf120550abd0257f89eaddf7 (diff)
downloadrails-cdae8216f582e035370b84edd236af7d22702e75.tar.gz
rails-cdae8216f582e035370b84edd236af7d22702e75.tar.bz2
rails-cdae8216f582e035370b84edd236af7d22702e75.zip
Merge pull request #318 from tamird/match-escape
{Matches,DoesNotMatch} support the ESCAPE clause
-rw-r--r--lib/arel/nodes.rb1
-rw-r--r--lib/arel/nodes/binary.rb2
-rw-r--r--lib/arel/nodes/matches.rb14
-rw-r--r--lib/arel/predications.rb33
-rw-r--r--lib/arel/visitors/to_sql.rb16
-rw-r--r--test/visitors/test_to_sql.rb14
6 files changed, 60 insertions, 20 deletions
diff --git a/lib/arel/nodes.rb b/lib/arel/nodes.rb
index c6bde8c3cc..ccccd471e2 100644
--- a/lib/arel/nodes.rb
+++ b/lib/arel/nodes.rb
@@ -28,6 +28,7 @@ require 'arel/nodes/delete_statement'
require 'arel/nodes/table_alias'
require 'arel/nodes/infix_operation'
require 'arel/nodes/over'
+require 'arel/nodes/matches'
# nary
require 'arel/nodes/and'
diff --git a/lib/arel/nodes/binary.rb b/lib/arel/nodes/binary.rb
index 939684957f..e35d2fd2e7 100644
--- a/lib/arel/nodes/binary.rb
+++ b/lib/arel/nodes/binary.rb
@@ -31,13 +31,11 @@ module Arel
As
Assignment
Between
- DoesNotMatch
GreaterThan
GreaterThanOrEqual
Join
LessThan
LessThanOrEqual
- Matches
NotEqual
NotIn
NotRegexp
diff --git a/lib/arel/nodes/matches.rb b/lib/arel/nodes/matches.rb
new file mode 100644
index 0000000000..583fb97c9b
--- /dev/null
+++ b/lib/arel/nodes/matches.rb
@@ -0,0 +1,14 @@
+module Arel
+ module Nodes
+ class Matches < Binary
+ attr_reader :escape
+
+ def initialize(left, right, escape = nil)
+ super(left, right)
+ @escape = escape && Nodes.build_quoted(escape)
+ end
+ end
+
+ class DoesNotMatch < Matches; end
+ end
+end
diff --git a/lib/arel/predications.rb b/lib/arel/predications.rb
index 1941383068..3050526a43 100644
--- a/lib/arel/predications.rb
+++ b/lib/arel/predications.rb
@@ -100,28 +100,28 @@ module Arel
grouping_all :not_in, others
end
- def matches other
- Nodes::Matches.new self, Nodes.build_quoted(other, self)
+ def matches other, escape = nil
+ Nodes::Matches.new self, Nodes.build_quoted(other, self), escape
end
- def matches_any others
- grouping_any :matches, others
+ def matches_any others, escape = nil
+ grouping_any :matches, others, escape
end
- def matches_all others
- grouping_all :matches, others
+ def matches_all others, escape = nil
+ grouping_all :matches, others, escape
end
- def does_not_match other
- Nodes::DoesNotMatch.new self, Nodes.build_quoted(other, self)
+ def does_not_match other, escape = nil
+ Nodes::DoesNotMatch.new self, Nodes.build_quoted(other, self), escape
end
- def does_not_match_any others
- grouping_any :does_not_match, others
+ def does_not_match_any others, escape = nil
+ grouping_any :does_not_match, others, escape
end
- def does_not_match_all others
- grouping_all :does_not_match, others
+ def does_not_match_all others, escape = nil
+ grouping_all :does_not_match, others, escape
end
def gteq right
@@ -174,15 +174,16 @@ module Arel
private
- def grouping_any method_id, others
- nodes = others.map {|expr| send(method_id, expr)}
+ def grouping_any method_id, others, *extras
+ nodes = others.map {|expr| send(method_id, expr, *extras)}
Nodes::Grouping.new nodes.inject { |memo,node|
Nodes::Or.new(memo, node)
}
end
- def grouping_all method_id, others
- Nodes::Grouping.new Nodes::And.new(others.map {|expr| send(method_id, expr)})
+ def grouping_all method_id, others, *extras
+ nodes = others.map {|expr| send(method_id, expr, *extras)}
+ Nodes::Grouping.new Nodes::And.new(nodes)
end
end
end
diff --git a/lib/arel/visitors/to_sql.rb b/lib/arel/visitors/to_sql.rb
index 7bef8feded..7fa3322148 100644
--- a/lib/arel/visitors/to_sql.rb
+++ b/lib/arel/visitors/to_sql.rb
@@ -539,13 +539,25 @@ module Arel
def visit_Arel_Nodes_Matches o, collector
collector = visit o.left, collector
collector << " LIKE "
- visit o.right, collector
+ collector = visit o.right, collector
+ if o.escape
+ collector << ' ESCAPE '
+ visit o.escape, collector
+ else
+ collector
+ end
end
def visit_Arel_Nodes_DoesNotMatch o, collector
collector = visit o.left, collector
collector << " NOT LIKE "
- visit o.right, collector
+ collector = visit o.right, collector
+ if o.escape
+ collector << ' ESCAPE '
+ visit o.escape, collector
+ else
+ collector
+ end
end
def visit_Arel_Nodes_JoinSource o, collector
diff --git a/test/visitors/test_to_sql.rb b/test/visitors/test_to_sql.rb
index 195566902b..abd8cfe356 100644
--- a/test/visitors/test_to_sql.rb
+++ b/test/visitors/test_to_sql.rb
@@ -312,6 +312,13 @@ module Arel
}
end
+ it "can handle ESCAPE" do
+ node = @table[:name].matches('foo!%', '!')
+ compile(node).must_be_like %{
+ "users"."name" LIKE 'foo!%' ESCAPE '!'
+ }
+ end
+
it 'can handle subqueries' do
subquery = @table.project(:id).where(@table[:name].matches('foo%'))
node = @attr.in subquery
@@ -329,6 +336,13 @@ module Arel
}
end
+ it "can handle ESCAPE" do
+ node = @table[:name].does_not_match('foo!%', '!')
+ compile(node).must_be_like %{
+ "users"."name" NOT LIKE 'foo!%' ESCAPE '!'
+ }
+ end
+
it 'can handle subqueries' do
subquery = @table.project(:id).where(@table[:name].does_not_match('foo%'))
node = @attr.in subquery