Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: issues with like and ilike fixed in v4 qb #6018

Merged
merged 1 commit into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions pkg/query-service/app/logs/v4/query_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,21 +146,23 @@ func buildAttributeFilter(item v3.FilterItem) (string, error) {

return fmt.Sprintf(logsOp, keyName, fmtVal), nil
case v3.FilterOperatorContains, v3.FilterOperatorNotContains:
// we also want to treat %, _ as literals for contains
val := utils.QuoteEscapedStringForContains(fmt.Sprintf("%s", item.Value))
// for body the contains is case insensitive
if keyName == BODY {
return fmt.Sprintf("lower(%s) %s lower('%%%s%%')", keyName, logsOp, val), nil
} else {
return fmt.Sprintf("%s %s '%%%s%%'", keyName, logsOp, val), nil
}
default:
// for use lower for like and ilike
if op == v3.FilterOperatorLike || op == v3.FilterOperatorNotLike {
if keyName == BODY {
keyName = fmt.Sprintf("lower(%s)", keyName)
fmtVal = fmt.Sprintf("lower(%s)", fmtVal)
}
case v3.FilterOperatorLike, v3.FilterOperatorNotLike:
// for body use lower for like and ilike
val := utils.QuoteEscapedString(fmt.Sprintf("%s", item.Value))
if keyName == BODY {
return fmt.Sprintf("lower(%s) %s lower('%s')", keyName, logsOp, val), nil
} else {
return fmt.Sprintf("%s %s '%s'", keyName, logsOp, val), nil
}
default:
return fmt.Sprintf("%s %s %s", keyName, logsOp, fmtVal), nil
}
} else {
Expand Down
4 changes: 2 additions & 2 deletions pkg/query-service/app/logs/v4/query_builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,10 +277,10 @@ func Test_buildAttributeFilter(t *testing.T) {
Type: v3.AttributeKeyTypeResource,
},
Operator: v3.FilterOperatorLike,
Value: "test",
Value: "test%",
},
},
want: "resources_string['service.name'] LIKE 'test'",
want: "resources_string['service.name'] LIKE 'test%'",
},
{
name: "build attribute filter like-body",
Expand Down
17 changes: 14 additions & 3 deletions pkg/query-service/app/logs/v4/resource_query_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,13 @@ func buildResourceFilter(logsOp string, key string, op v3.FilterOperator, value
return fmt.Sprintf(logsOp, searchKey, chFmtVal)
case v3.FilterOperatorContains, v3.FilterOperatorNotContains:
// this is required as clickhouseFormattedValue add's quotes to the string
// we also want to treat %, _ as literals for contains
escapedStringValue := utils.QuoteEscapedStringForContains(fmt.Sprintf("%s", value))
return fmt.Sprintf("%s %s '%%%s%%'", searchKey, logsOp, escapedStringValue)
case v3.FilterOperatorLike, v3.FilterOperatorNotLike:
// this is required as clickhouseFormattedValue add's quotes to the string
escapedStringValue := utils.QuoteEscapedString(fmt.Sprintf("%s", value))
return fmt.Sprintf("%s %s '%s'", searchKey, logsOp, escapedStringValue)
default:
return fmt.Sprintf("%s %s %s", searchKey, logsOp, chFmtVal)
}
Expand Down Expand Up @@ -74,13 +79,19 @@ func buildIndexFilterForInOperator(key string, op v3.FilterOperator, value inter
// example:= x like '%john%' = labels like '%x%john%'
func buildResourceIndexFilter(key string, op v3.FilterOperator, value interface{}) string {
// not using clickhouseFormattedValue as we don't wan't the quotes
formattedValueEscaped := utils.QuoteEscapedStringForContains(fmt.Sprintf("%s", value))
strVal := fmt.Sprintf("%s", value)
formattedValueEscapedForContains := utils.QuoteEscapedStringForContains(strVal)
formattedValueEscaped := utils.QuoteEscapedString(strVal)

// add index filters
switch op {
case v3.FilterOperatorContains, v3.FilterOperatorEqual, v3.FilterOperatorLike:
case v3.FilterOperatorContains:
return fmt.Sprintf("labels like '%%%s%%%s%%'", key, formattedValueEscapedForContains)
case v3.FilterOperatorNotContains:
return fmt.Sprintf("labels not like '%%%s%%%s%%'", key, formattedValueEscapedForContains)
case v3.FilterOperatorLike, v3.FilterOperatorEqual:
return fmt.Sprintf("labels like '%%%s%%%s%%'", key, formattedValueEscaped)
case v3.FilterOperatorNotContains, v3.FilterOperatorNotEqual, v3.FilterOperatorNotLike:
case v3.FilterOperatorNotLike, v3.FilterOperatorNotEqual:
return fmt.Sprintf("labels not like '%%%s%%%s%%'", key, formattedValueEscaped)
case v3.FilterOperatorNotRegex:
return fmt.Sprintf("labels not like '%%%s%%'", key)
Expand Down
27 changes: 23 additions & 4 deletions pkg/query-service/app/logs/v4/resource_query_builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ func Test_buildResourceFilter(t *testing.T) {
logsOp: "=",
key: "service.name",
op: v3.FilterOperatorEqual,
value: "Application",
value: "Application%",
},
want: `simpleJSONExtractString(labels, 'service.name') = 'Application'`,
want: `simpleJSONExtractString(labels, 'service.name') = 'Application%'`,
},
{
name: "test value with quotes",
Expand All @@ -75,6 +75,16 @@ func Test_buildResourceFilter(t *testing.T) {
},
want: `simpleJSONExtractString(labels, 'service.name') = 'Application\'s'`,
},
{
name: "test like",
args: args{
logsOp: "LIKE",
key: "service.name",
op: v3.FilterOperatorLike,
value: "Application%_",
},
want: `simpleJSONExtractString(labels, 'service.name') LIKE 'Application%_'`,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down Expand Up @@ -119,9 +129,9 @@ func Test_buildIndexFilterForInOperator(t *testing.T) {
args: args{
key: "service.name",
op: v3.FilterOperatorIn,
value: "application",
value: "application%",
},
want: `(labels like '%"service.name":"application"%')`,
want: `(labels like '%"service.name":"application\%"%')`,
},
{
name: "test nin string",
Expand Down Expand Up @@ -180,6 +190,15 @@ func Test_buildResourceIndexFilter(t *testing.T) {
},
want: `labels not like '%service.name%application\%\_test%'`,
},
{
name: "test like with % and _",
args: args{
key: "service.name",
op: v3.FilterOperatorLike,
value: "application%_test",
},
want: `labels like '%service.name%application%_test%'`,
},
{
name: "test not regex",
args: args{
Expand Down
Loading