orm: ilike for case insensitive text search

This commit is contained in:
Alexander Medvednikov 2024-06-10 11:54:15 +03:00
parent ef918082b4
commit b5b57a2e07
5 changed files with 22 additions and 2 deletions

View File

@ -63,6 +63,7 @@ pub enum OperationKind {
ge // >=
le // <=
orm_like // LIKE
orm_ilike // ILIKE
is_null // IS NULL
is_not_null // IS NOT NULL
}
@ -101,6 +102,7 @@ fn (kind OperationKind) to_str() string {
.ge { '>=' }
.le { '<=' }
.orm_like { 'LIKE' }
.orm_ilike { 'ILIKE' }
.is_null { 'IS NULL' }
.is_not_null { 'IS NOT NULL' }
}

View File

@ -522,6 +522,11 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
return c.check_like_operator(node)
}
.key_ilike {
node.promoted_type = ast.bool_type
return c.check_like_operator(node)
}
.left_shift {
if left_final_sym.kind == .array
|| c.table.sym(c.unwrap_generic(left_type)).kind == .array {

View File

@ -747,6 +747,9 @@ fn (mut g Gen) write_orm_where_expr(expr ast.Expr, mut fields []string, mut pare
.key_like {
'orm__OperationKind__orm_like'
}
.key_ilike {
'orm__OperationKind__orm_ilike'
}
.key_is {
'orm__OperationKind__is_null'
}

View File

@ -842,12 +842,18 @@ fn (mut p Parser) process_custom_orm_operators() {
}
is_like_operator := p.tok.kind == .name && p.tok.lit == 'like'
is_ilike_operator := p.tok.kind == .name && p.tok.lit == 'ilike'
if is_like_operator {
p.tok = token.Token{
...p.tok
kind: .key_like
}
} else if is_ilike_operator {
p.tok = token.Token{
...p.tok
kind: .key_ilike
}
}
}

View File

@ -3,7 +3,7 @@
// that can be found in the LICENSE file.
module token
const orm_custom_operators = ['like']
const orm_custom_operators = ['like', 'ilike']
@[minify]
pub struct Token {
@ -118,6 +118,7 @@ pub enum Kind {
key_return
key_select
key_like
key_ilike
key_sizeof
key_isreftype
key_likely
@ -327,6 +328,7 @@ fn build_token_str() []string {
s[Kind.key_match] = 'match'
s[Kind.key_select] = 'select'
s[Kind.key_like] = 'like'
s[Kind.key_ilike] = 'ilike'
s[Kind.key_none] = 'none'
s[Kind.key_nil] = 'nil'
s[Kind.key_offsetof] = '__offsetof'
@ -451,6 +453,7 @@ pub fn build_precedences() []Precedence {
p[Kind.gt] = .eq
p[Kind.ge] = .eq
p[Kind.key_like] = .eq
p[Kind.key_ilike] = .eq
// `=` | `+=` | ...
p[Kind.assign] = .assign
p[Kind.plus_assign] = .assign
@ -522,7 +525,7 @@ pub fn (kind Kind) is_prefix() bool {
pub fn (kind Kind) is_infix() bool {
return kind in [.plus, .minus, .mod, .mul, .div, .eq, .ne, .gt, .lt, .key_in, .key_as, .ge,
.le, .logical_or, .xor, .not_in, .key_is, .not_is, .and, .dot, .pipe, .amp, .left_shift,
.right_shift, .unsigned_right_shift, .arrow, .key_like]
.right_shift, .unsigned_right_shift, .arrow, .key_like, .key_ilike]
}
@[inline]
@ -630,6 +633,7 @@ pub fn kind_to_string(k Kind) string {
.key_return { 'key_return' }
.key_select { 'key_select' }
.key_like { 'key_like' }
.key_ilike { 'key_ilike' }
.key_sizeof { 'key_sizeof' }
.key_isreftype { 'key_isreftype' }
.key_likely { 'key_likely' }