From 508a6783c8f75742ac64e5073b3b211b0c15662a Mon Sep 17 00:00:00 2001
From: Keenan Brock <keenan@thebrocks.net>
Date: Sat, 5 Dec 2015 18:54:09 -0500
Subject: Add case sensitive match

Explicitly declare if this is case sensitive or not

most implementation assume case sensitive
postgres assumes case insensitive
---
 lib/arel/nodes/matches.rb       |  4 +++-
 lib/arel/predications.rb        | 16 ++++++++--------
 lib/arel/visitors/postgresql.rb |  6 ++++--
 3 files changed, 15 insertions(+), 11 deletions(-)

(limited to 'lib/arel')

diff --git a/lib/arel/nodes/matches.rb b/lib/arel/nodes/matches.rb
index 583fb97c9b..0d9c1925dc 100644
--- a/lib/arel/nodes/matches.rb
+++ b/lib/arel/nodes/matches.rb
@@ -2,10 +2,12 @@ module Arel
   module Nodes
     class Matches < Binary
       attr_reader :escape
+      attr_accessor :case_sensitive
 
-      def initialize(left, right, escape = nil)
+      def initialize(left, right, escape = nil, case_sensitive = false)
         super(left, right)
         @escape = escape && Nodes.build_quoted(escape)
+        @case_sensitive = case_sensitive
       end
     end
 
diff --git a/lib/arel/predications.rb b/lib/arel/predications.rb
index b05fc6f99a..ed083f5402 100644
--- a/lib/arel/predications.rb
+++ b/lib/arel/predications.rb
@@ -118,20 +118,20 @@ Passing a range to `#not_in` is deprecated. Call `#not_between`, instead.
       grouping_all :not_in, others
     end
 
-    def matches other, escape = nil
-      Nodes::Matches.new self, quoted_node(other), escape
+    def matches other, escape = nil, case_sensitive = false
+      Nodes::Matches.new self, quoted_node(other), escape, case_sensitive
     end
 
-    def matches_any others, escape = nil
-      grouping_any :matches, others, escape
+    def matches_any others, escape = nil, case_sensitive = false
+      grouping_any :matches, others, escape, case_sensitive
     end
 
-    def matches_all others, escape = nil
-      grouping_all :matches, others, escape
+    def matches_all others, escape = nil, case_sensitive = false
+      grouping_all :matches, others, escape, case_sensitive
     end
 
-    def does_not_match other, escape = nil
-      Nodes::DoesNotMatch.new self, quoted_node(other), escape
+    def does_not_match other, escape = nil, case_sensitive = false
+      Nodes::DoesNotMatch.new self, quoted_node(other), escape, case_sensitive
     end
 
     def does_not_match_any others, escape = nil
diff --git a/lib/arel/visitors/postgresql.rb b/lib/arel/visitors/postgresql.rb
index bd23fc0a47..75d2ad9c93 100644
--- a/lib/arel/visitors/postgresql.rb
+++ b/lib/arel/visitors/postgresql.rb
@@ -4,7 +4,8 @@ module Arel
       private
 
       def visit_Arel_Nodes_Matches o, collector
-        collector = infix_value o, collector, ' ILIKE '
+        op = o.case_sensitive ? ' LIKE ' : ' ILIKE '
+        collector = infix_value o, collector, op
         if o.escape
           collector << ' ESCAPE '
           visit o.escape, collector
@@ -14,7 +15,8 @@ module Arel
       end
 
       def visit_Arel_Nodes_DoesNotMatch o, collector
-        collector = infix_value o, collector, ' NOT ILIKE '
+        op = o.case_sensitive ? ' NOT LIKE ' : ' NOT ILIKE '
+        collector = infix_value o, collector, op
         if o.escape
           collector << ' ESCAPE '
           visit o.escape, collector
-- 
cgit v1.2.3


From 193d2ad2147a5cd1de44f2d57f4f3bd65e161293 Mon Sep 17 00:00:00 2001
From: Keenan Brock <keenan@thebrocks.net>
Date: Sat, 5 Dec 2015 19:13:05 -0500
Subject: Add case sensitive regexp

Explicitly declare if this is case sensitive or not

currently postgres assumes case insensitive regexp
no other databases support regexps
---
 lib/arel/nodes.rb               |  1 +
 lib/arel/nodes/binary.rb        |  2 --
 lib/arel/nodes/regexp.rb        | 14 ++++++++++++++
 lib/arel/visitors/postgresql.rb |  6 ++++--
 4 files changed, 19 insertions(+), 4 deletions(-)
 create mode 100644 lib/arel/nodes/regexp.rb

(limited to 'lib/arel')

diff --git a/lib/arel/nodes.rb b/lib/arel/nodes.rb
index 8d61bb320f..0e66d2dd0c 100644
--- a/lib/arel/nodes.rb
+++ b/lib/arel/nodes.rb
@@ -30,6 +30,7 @@ require 'arel/nodes/table_alias'
 require 'arel/nodes/infix_operation'
 require 'arel/nodes/over'
 require 'arel/nodes/matches'
+require 'arel/nodes/regexp'
 
 # nary
 require 'arel/nodes/and'
diff --git a/lib/arel/nodes/binary.rb b/lib/arel/nodes/binary.rb
index dddbde1431..763091c267 100644
--- a/lib/arel/nodes/binary.rb
+++ b/lib/arel/nodes/binary.rb
@@ -38,9 +38,7 @@ module Arel
       LessThanOrEqual
       NotEqual
       NotIn
-      NotRegexp
       Or
-      Regexp
       Union
       UnionAll
       Intersect
diff --git a/lib/arel/nodes/regexp.rb b/lib/arel/nodes/regexp.rb
new file mode 100644
index 0000000000..784368f5bf
--- /dev/null
+++ b/lib/arel/nodes/regexp.rb
@@ -0,0 +1,14 @@
+module Arel
+  module Nodes
+    class Regexp < Binary
+      attr_accessor :case_sensitive
+
+      def initialize(left, right, case_sensitive = true)
+        super(left, right)
+        @case_sensitive = case_sensitive
+      end
+    end
+
+    class NotRegexp < Regexp; end
+  end
+end
diff --git a/lib/arel/visitors/postgresql.rb b/lib/arel/visitors/postgresql.rb
index 75d2ad9c93..1ef0261bdd 100644
--- a/lib/arel/visitors/postgresql.rb
+++ b/lib/arel/visitors/postgresql.rb
@@ -26,11 +26,13 @@ module Arel
       end
 
       def visit_Arel_Nodes_Regexp o, collector
-        infix_value o, collector, ' ~ '
+        op = o.case_sensitive ? ' ~ ' : ' ~* '
+        infix_value o, collector, op
       end
 
       def visit_Arel_Nodes_NotRegexp o, collector
-        infix_value o, collector, ' !~ '
+        op = o.case_sensitive ? ' !~ ' : ' !~* '
+        infix_value o, collector, op
       end
 
       def visit_Arel_Nodes_DistinctOn o, collector
-- 
cgit v1.2.3


From d2e6be1677b124b3eef5b3ebe0fd4a0d31d8a2bf Mon Sep 17 00:00:00 2001
From: Keenan Brock <keenan@thebrocks.net>
Date: Sat, 5 Dec 2015 20:23:12 -0500
Subject: introduce predicate {does_not_}matches_regexp

---
 lib/arel/predications.rb | 8 ++++++++
 1 file changed, 8 insertions(+)

(limited to 'lib/arel')

diff --git a/lib/arel/predications.rb b/lib/arel/predications.rb
index ed083f5402..1d2b0de235 100644
--- a/lib/arel/predications.rb
+++ b/lib/arel/predications.rb
@@ -122,6 +122,10 @@ Passing a range to `#not_in` is deprecated. Call `#not_between`, instead.
       Nodes::Matches.new self, quoted_node(other), escape, case_sensitive
     end
 
+    def matches_regexp other, case_sensitive = true
+      Nodes::Regexp.new self, quoted_node(other), case_sensitive
+    end
+
     def matches_any others, escape = nil, case_sensitive = false
       grouping_any :matches, others, escape, case_sensitive
     end
@@ -134,6 +138,10 @@ Passing a range to `#not_in` is deprecated. Call `#not_between`, instead.
       Nodes::DoesNotMatch.new self, quoted_node(other), escape, case_sensitive
     end
 
+    def does_not_match_regexp other, case_sensitive = true
+      Nodes::NotRegexp.new self, quoted_node(other), case_sensitive
+    end
+
     def does_not_match_any others, escape = nil
       grouping_any :does_not_match, others, escape
     end
-- 
cgit v1.2.3