sea-query icon indicating copy to clipboard operation
sea-query copied to clipboard

[Feature Request] Add ILIKE operator

Open negezor opened this issue 3 years ago • 5 comments

Motivation

https://www.postgresql.org/docs/14/functions-matching.html#FUNCTIONS-LIKE

Proposed Solutions

Expr::col(...).ilike("%pattern%")
// Or
LikeExpr::str("%pattern%").ilike()
// Or
LikeExpr::str("%pattern%").case_insensitive()

Additional Information

This is of course not a standard statement in SQL. But very commonly used in Postgres.

negezor avatar Sep 18 '22 17:09 negezor

@negezor thank you for the issue! Do you want to create PR?)

ikrivosheev avatar Sep 19 '22 08:09 ikrivosheev

Hey @negezor, welcome!! Would you mind sharing your use case? Just show us the resulting SQL :)

Expr::col(...).ilike("%pattern%")

This is already supported in SeaQuery. See https://docs.rs/sea-query/0.26.3/sea_query/expr/struct.Expr.html#method.like

billy1624 avatar Sep 20 '22 05:09 billy1624

@ikrivosheev I'm not so well versed in the internals of the module yet 😅

@tyt2y3 & @billy1624 Difference between LIKE and ILIKE in case sensitivity.

-- Postgres
SELECT * FROM cakes WHERE name ILIKE '%cHocOlate%'

-- MySQL
SELECT * FROM cakes WHERE LOWER(name) LIKE LOWER('%cHocOlate%')

negezor avatar Sep 20 '22 11:09 negezor

Oh, sorry I misunderstand it. I thought it's LIKE but in fact it's ILIKE.

We already support this generic form. i.e. applying LOWER function on a column value then operate LIKE on it. Given the pattern already in lower case.

SELECT * FROM cakes WHERE LOWER(name) LIKE '%lower_case%'

billy1624 avatar Sep 21 '22 04:09 billy1624

@tyt2y3 @billy1624 Well, shall we add or is it too specific for postgres?

ikrivosheev avatar Sep 30 '22 17:09 ikrivosheev

I think it's okay to add ILIKE operator. By default the collation of Postgres is case-sensitive whereas MySQL and SQLite are case-insensitive. That means we can fallback to ordinary LIKE operator on MySQL and SQLite while keeping the behaviour the same - search with a case-insensitive pattern.

billy1624 avatar Oct 07 '22 07:10 billy1624

@billy1624 ~~Hey Billy, I am not sure that SQLite is case-insensitive. https://www.sqlite.org/datatype3.html#collation The default is "BINARY" -- to get case-insensitive you need "NOCASE"~~. I arrived at this issue looking for how to do this with sea-query and couldn't find it :)

Edit: I am totally wrong; although regular comparison like = and < is case-sensitive by default, LIKE is case-insensitive. You were absolutely right.

hut8 avatar Oct 20 '22 14:10 hut8

Hello! I created PR: https://github.com/SeaQL/sea-query/pull/473

ikrivosheev avatar Oct 20 '22 15:10 ikrivosheev