Skip to content

Commit

Permalink
mysql,pg: fix find_in_set to accept strings
Browse files Browse the repository at this point in the history
  • Loading branch information
stackmystack authored and jdelporte committed Jan 22, 2025
1 parent 9d4c79a commit 9483659
Show file tree
Hide file tree
Showing 5 changed files with 14 additions and 7 deletions.
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## [unreleased]

- Fix the `&` operator which does `find_in_set` for mysql and postgres, accepting strings and integers.

## Release v2.3.2/v1.5.2 (02-01-2025)

- Fix a subtle bug on table access as in `table[:col]` in certain situations.
Expand Down
7 changes: 3 additions & 4 deletions init/postgresql.sql
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
CREATE OR REPLACE FUNCTION public.find_in_set(n INTEGER, s TEXT)
CREATE OR REPLACE FUNCTION public.find_in_set(n TEXT, s TEXT)
RETURNS INT4
LANGUAGE sql
AS $function$
SELECT * FROM (
select int4(z.row_number) from (
select row_number() over(), y.x
from (select unnest(('{' || $2 || '}')::int[]) as x) as y
from (select unnest(regexp_split_to_array($2, ',')) as x) as y -- use string_to_array if on pg 14+.
) as z
where z.x = $1
UNION ALL
SELECT 0) z
LIMIT 1
$function$
;
$function$;

CREATE OR REPLACE FUNCTION public.levenshtein_distance(s text, t text)
RETURNS integer AS $$
Expand Down
5 changes: 4 additions & 1 deletion lib/arel_extensions/string_functions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ module ArelExtensions
module StringFunctions
# *FindInSet function .......
def &(other)
ArelExtensions::Nodes::FindInSet.new [other, self]
ArelExtensions::Nodes::FindInSet.new [
Arel.quoted(other.is_a?(Integer) ? other.to_s : other),
self,
]
end

# LENGTH function returns the length (bytewise) of the value in a text field.
Expand Down
2 changes: 1 addition & 1 deletion test/visitors/test_to_sql.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def compile node
# puts (c.length.round + 42).inspect
_(compile(c.length.round + 42)).must_be_like %{(ROUND(LENGTH("users"."name")) + 42)}
_(compile(c.locate('test'))).must_be_like %{LOCATE('test', "users"."name")}
_(compile(c & 42)).must_be_like %{FIND_IN_SET(42, "users"."name")}
_(compile(c & 42)).must_be_like %{FIND_IN_SET('42', "users"."name")}

_(compile((c >= 'test').as('new_name'))).must_be_like %{("users"."name" >= 'test') AS new_name}
_(compile(c <= @table[:comments])).must_be_like %{"users"."name" <= "users"."comments"}
Expand Down
5 changes: 4 additions & 1 deletion test/with_ar/all_agnostic_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def setup
@laure = User.where(id: u.id)
u = User.create age: nil, name: 'Test', created_at: d, score: 1.62, other: 'toto'
@test = User.where(id: u.id)
u = User.create age: -42, name: 'Negatif', comments: '1,22,3,42,2', created_at: d, updated_at: d.to_time, score: 0.17
u = User.create age: -42, name: 'Negatif', comments: '1,22,3,42,2', created_at: d, updated_at: d.to_time, score: 0.17, other: '2'
@neg = User.where(id: u.id)
u = User.create age: 15, name: 'Justin', created_at: d, score: 11.0
@justin = User.where(id: u.id)
Expand Down Expand Up @@ -297,6 +297,9 @@ def test_find_in_set
skip 'SQL Server does not know about FIND_IN_SET' if @env_db == 'mssql'
assert_equal 5, t(@neg, @comments & 2)
assert_equal 0, t(@neg, @comments & 6) # not found
assert_equal 5, t(@neg, @comments & '2')
assert_equal 0, t(@neg, @comments & '6') # not found
assert_equal 5, t(@neg, @comments & @other)
end

def test_string_comparators
Expand Down

0 comments on commit 9483659

Please sign in to comment.