From 193d2ad2147a5cd1de44f2d57f4f3bd65e161293 Mon Sep 17 00:00:00 2001 From: Keenan Brock Date: Sat, 5 Dec 2015 19:13:05 -0500 Subject: [PATCH] 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 ++++-- test/visitors/test_postgres.rb | 14 ++++++++++++++ 5 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 lib/arel/nodes/regexp.rb 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 diff --git a/test/visitors/test_postgres.rb b/test/visitors/test_postgres.rb index d00aa1c100..e6fd4cd0da 100644 --- a/test/visitors/test_postgres.rb +++ b/test/visitors/test_postgres.rb @@ -120,6 +120,13 @@ module Arel } end + it "can handle case insensitive" do + node = Arel::Nodes::Regexp.new(@table[:name], Nodes.build_quoted('foo%'), false) + compile(node).must_be_like %{ + "users"."name" ~* 'foo%' + } + end + it 'can handle subqueries' do subquery = @table.project(:id).where(Arel::Nodes::Regexp.new(@table[:name], Nodes.build_quoted('foo%'))) node = @attr.in subquery @@ -137,6 +144,13 @@ module Arel } end + it "can handle case insensitive" do + node = Arel::Nodes::NotRegexp.new(@table[:name], Nodes.build_quoted('foo%'), false) + compile(node).must_be_like %{ + "users"."name" !~* 'foo%' + } + end + it 'can handle subqueries' do subquery = @table.project(:id).where(Arel::Nodes::NotRegexp.new(@table[:name], Nodes.build_quoted('foo%'))) node = @attr.in subquery