diff --git a/internal/database/database.go b/internal/database/database.go index b40715d6b52..0ad99623521 100644 --- a/internal/database/database.go +++ b/internal/database/database.go @@ -206,6 +206,7 @@ func (c Config) Type() dialect.DatabaseType { } func EscapeLikeWildcards(value string) string { + value = strings.ReplaceAll(value, "\\", "\\\\") value = strings.ReplaceAll(value, "%", "\\%") value = strings.ReplaceAll(value, "_", "\\_") return value diff --git a/internal/query/search_query.go b/internal/query/search_query.go index 4e0e65c489e..1bd8fc76b1d 100644 --- a/internal/query/search_query.go +++ b/internal/query/search_query.go @@ -288,9 +288,7 @@ func NewTextQuery(col Column, value string, compare TextComparison) (*textQuery, } // handle the comparisons which use (i)like and therefore need to escape potential wildcards in the value switch compare { - case TextEqualsIgnoreCase, - TextNotEqualsIgnoreCase, - TextStartsWith, + case TextStartsWith, TextStartsWithIgnoreCase, TextEndsWith, TextEndsWithIgnoreCase, @@ -300,6 +298,8 @@ func NewTextQuery(col Column, value string, compare TextComparison) (*textQuery, case TextEquals, TextListContains, TextNotEquals, + TextEqualsIgnoreCase, + TextNotEqualsIgnoreCase, textCompareMax: // do nothing } @@ -335,9 +335,9 @@ func (q *textQuery) comp() sq.Sqlizer { case TextNotEquals: return sq.NotEq{q.Column.identifier(): q.Text} case TextEqualsIgnoreCase: - return sq.Like{"LOWER(" + q.Column.identifier() + ")": strings.ToLower(q.Text)} + return sq.Eq{"LOWER(" + q.Column.identifier() + ")": strings.ToLower(q.Text)} case TextNotEqualsIgnoreCase: - return sq.NotLike{"LOWER(" + q.Column.identifier() + ")": strings.ToLower(q.Text)} + return sq.NotEq{"LOWER(" + q.Column.identifier() + ")": strings.ToLower(q.Text)} case TextStartsWith: return sq.Like{q.Column.identifier(): q.Text + "%"} case TextStartsWithIgnoreCase: diff --git a/internal/query/search_query_test.go b/internal/query/search_query_test.go index 7f6672b279a..314eab2213e 100644 --- a/internal/query/search_query_test.go +++ b/internal/query/search_query_test.go @@ -862,7 +862,7 @@ func TestNewTextQuery(t *testing.T) { }, want: &textQuery{ Column: testCol, - Text: "hu\\%rst", + Text: "hu%rst", Compare: TextEqualsIgnoreCase, }, }, @@ -875,7 +875,7 @@ func TestNewTextQuery(t *testing.T) { }, want: &textQuery{ Column: testCol, - Text: "hu\\_rst", + Text: "hu_rst", Compare: TextEqualsIgnoreCase, }, }, @@ -888,7 +888,7 @@ func TestNewTextQuery(t *testing.T) { }, want: &textQuery{ Column: testCol, - Text: "h\\_urst\\%", + Text: "h_urst%", Compare: TextEqualsIgnoreCase, }, }, @@ -914,7 +914,7 @@ func TestNewTextQuery(t *testing.T) { }, want: &textQuery{ Column: testCol, - Text: "h\\_urst\\%", + Text: "h_urst%", Compare: TextNotEqualsIgnoreCase, }, }, @@ -1204,7 +1204,7 @@ func TestTextQuery_comp(t *testing.T) { Compare: TextEqualsIgnoreCase, }, want: want{ - query: sq.Like{"LOWER(test_table.test_col)": "hurst"}, + query: sq.Eq{"LOWER(test_table.test_col)": "hurst"}, }, }, { @@ -1226,7 +1226,7 @@ func TestTextQuery_comp(t *testing.T) { Compare: TextNotEqualsIgnoreCase, }, want: want{ - query: sq.NotLike{"LOWER(test_table.test_col)": "hurst"}, + query: sq.NotEq{"LOWER(test_table.test_col)": "hurst"}, }, }, { @@ -1237,7 +1237,18 @@ func TestTextQuery_comp(t *testing.T) { Compare: TextEqualsIgnoreCase, }, want: want{ - query: sq.Like{"LOWER(test_table.test_col)": "hu\\%\\%rst"}, + query: sq.Eq{"LOWER(test_table.test_col)": "hu%%rst"}, + }, + }, + { + name: "equals ignore case backslash", + fields: fields{ + Column: testCol, + Text: "AD\\Hurst", + Compare: TextEqualsIgnoreCase, + }, + want: want{ + query: sq.Eq{"LOWER(test_table.test_col)": "ad\\hurst"}, }, }, { @@ -1255,11 +1266,11 @@ func TestTextQuery_comp(t *testing.T) { name: "starts with wildcards", fields: fields{ Column: testCol, - Text: "_Hurst%", + Text: "_Hur\\st%", Compare: TextStartsWith, }, want: want{ - query: sq.Like{"test_table.test_col": "\\_Hurst\\%%"}, + query: sq.Like{"test_table.test_col": "\\_Hur\\\\st\\%%"}, }, }, {