mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-06-04 11:25:52 +08:00
fix: escape string for contains and ncontains (#5083)
* fix: escape string for contains and ncontains * fix: add changes to json and traces builder --------- Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
This commit is contained in:
parent
749fba67cb
commit
ab444af8e6
@ -144,7 +144,8 @@ func GetJSONFilter(item v3.FilterItem) (string, error) {
|
||||
fmtVal := utils.ClickHouseFormattedValue(value)
|
||||
filter = fmt.Sprintf(logsOp, key, fmtVal)
|
||||
case v3.FilterOperatorContains, v3.FilterOperatorNotContains:
|
||||
filter = fmt.Sprintf("%s %s '%%%s%%'", key, logsOp, item.Value)
|
||||
val := utils.QuoteEscapedString(fmt.Sprintf("%v", item.Value))
|
||||
filter = fmt.Sprintf("%s %s '%%%s%%'", key, logsOp, val)
|
||||
default:
|
||||
fmtVal := utils.ClickHouseFormattedValue(value)
|
||||
filter = fmt.Sprintf("%s %s %s", key, logsOp, fmtVal)
|
||||
|
@ -300,6 +300,19 @@ var testGetJSONFilterData = []struct {
|
||||
},
|
||||
Filter: "JSON_EXISTS(body, '$.\"message\"') AND JSON_VALUE(body, '$.\"message\"') ILIKE '%a%'",
|
||||
},
|
||||
{
|
||||
Name: "contains operator with quotes",
|
||||
FilterItem: v3.FilterItem{
|
||||
Key: v3.AttributeKey{
|
||||
Key: "body.message",
|
||||
DataType: "string",
|
||||
IsJSON: true,
|
||||
},
|
||||
Operator: "contains",
|
||||
Value: "hello 'world'",
|
||||
},
|
||||
Filter: "JSON_EXISTS(body, '$.\"message\"') AND JSON_VALUE(body, '$.\"message\"') ILIKE '%hello \\'world\\'%'",
|
||||
},
|
||||
{
|
||||
Name: "exists",
|
||||
FilterItem: v3.FilterItem{
|
||||
|
@ -192,7 +192,8 @@ func buildLogsTimeSeriesFilterQuery(fs *v3.FilterSet, groupBy []v3.AttributeKey,
|
||||
conditions = append(conditions, fmt.Sprintf(logsOp, columnName, fmtVal))
|
||||
case v3.FilterOperatorContains, v3.FilterOperatorNotContains:
|
||||
columnName := getClickhouseColumnName(item.Key)
|
||||
conditions = append(conditions, fmt.Sprintf("%s %s '%%%s%%'", columnName, logsOp, item.Value))
|
||||
val := utils.QuoteEscapedString(fmt.Sprintf("%v", item.Value))
|
||||
conditions = append(conditions, fmt.Sprintf("%s %s '%%%s%%'", columnName, logsOp, val))
|
||||
default:
|
||||
columnName := getClickhouseColumnName(item.Key)
|
||||
fmtVal := utils.ClickHouseFormattedValue(value)
|
||||
|
@ -187,6 +187,13 @@ var timeSeriesFilterQueryData = []struct {
|
||||
}},
|
||||
ExpectedFilter: "attributes_string_value[indexOf(attributes_string_key, 'host')] ILIKE '%102.%'",
|
||||
},
|
||||
{
|
||||
Name: "Test contains with single quotes",
|
||||
FilterSet: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{
|
||||
{Key: v3.AttributeKey{Key: "message", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, Value: "hello 'world'", Operator: "contains"},
|
||||
}},
|
||||
ExpectedFilter: "attributes_string_value[indexOf(attributes_string_key, 'message')] ILIKE '%hello \\'world\\'%'",
|
||||
},
|
||||
{
|
||||
Name: "Test not contains",
|
||||
FilterSet: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{
|
||||
@ -280,7 +287,6 @@ var timeSeriesFilterQueryData = []struct {
|
||||
}},
|
||||
ExpectedFilter: "`attribute_int64_status_exists`=false",
|
||||
},
|
||||
// add new tests
|
||||
}
|
||||
|
||||
func TestBuildLogsTimeSeriesFilterQuery(t *testing.T) {
|
||||
|
@ -174,7 +174,8 @@ func buildTracesFilterQuery(fs *v3.FilterSet, keys map[string]v3.AttributeKey) (
|
||||
if operator, ok := tracesOperatorMappingV3[item.Operator]; ok {
|
||||
switch item.Operator {
|
||||
case v3.FilterOperatorContains, v3.FilterOperatorNotContains:
|
||||
conditions = append(conditions, fmt.Sprintf("%s %s '%%%s%%'", columnName, operator, item.Value))
|
||||
val = utils.QuoteEscapedString(fmt.Sprintf("%v", item.Value))
|
||||
conditions = append(conditions, fmt.Sprintf("%s %s '%%%s%%'", columnName, operator, val))
|
||||
case v3.FilterOperatorRegex, v3.FilterOperatorNotRegex:
|
||||
conditions = append(conditions, fmt.Sprintf(operator, columnName, fmtVal))
|
||||
case v3.FilterOperatorExists, v3.FilterOperatorNotExists:
|
||||
@ -263,7 +264,7 @@ func buildTracesQuery(start, end, step int64, mq *v3.BuilderQuery, tableName str
|
||||
queryTmpl =
|
||||
"SELECT now() as ts,"
|
||||
// step or aggregate interval is whole time period in case of table panel
|
||||
step = (end*getZerosForEpochNano(end) - start*getZerosForEpochNano(start))/1000000000
|
||||
step = (end*getZerosForEpochNano(end) - start*getZerosForEpochNano(start)) / 1000000000
|
||||
} else if panelType == v3.PanelTypeGraph || panelType == v3.PanelTypeValue {
|
||||
// Select the aggregate value for interval
|
||||
queryTmpl =
|
||||
|
@ -100,6 +100,13 @@ var buildFilterQueryData = []struct {
|
||||
}},
|
||||
ExpectedFilter: " AND stringTagMap['host'] ILIKE '%102.%'",
|
||||
},
|
||||
{
|
||||
Name: "Test contains with quotes",
|
||||
FilterSet: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{
|
||||
{Key: v3.AttributeKey{Key: "message", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag}, Value: "Hello 'world'", Operator: "contains"},
|
||||
}},
|
||||
ExpectedFilter: " AND stringTagMap['message'] ILIKE '%Hello \\'world\\'%'",
|
||||
},
|
||||
{
|
||||
Name: "Test not contains",
|
||||
FilterSet: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{
|
||||
|
@ -143,7 +143,7 @@ func ValidateAndCastValue(v interface{}, dataType v3.AttributeKeyDataType) (inte
|
||||
}
|
||||
}
|
||||
|
||||
func quoteEscapedString(str string) string {
|
||||
func QuoteEscapedString(str string) string {
|
||||
// https://clickhouse.com/docs/en/sql-reference/syntax#string
|
||||
str = strings.ReplaceAll(str, `\`, `\\`)
|
||||
str = strings.ReplaceAll(str, `'`, `\'`)
|
||||
@ -161,7 +161,7 @@ func ClickHouseFormattedValue(v interface{}) string {
|
||||
case float32, float64:
|
||||
return fmt.Sprintf("%f", x)
|
||||
case string:
|
||||
return fmt.Sprintf("'%s'", quoteEscapedString(x))
|
||||
return fmt.Sprintf("'%s'", QuoteEscapedString(x))
|
||||
case bool:
|
||||
return fmt.Sprintf("%v", x)
|
||||
|
||||
@ -173,7 +173,7 @@ func ClickHouseFormattedValue(v interface{}) string {
|
||||
case string:
|
||||
str := "["
|
||||
for idx, sVal := range x {
|
||||
str += fmt.Sprintf("'%s'", quoteEscapedString(sVal.(string)))
|
||||
str += fmt.Sprintf("'%s'", QuoteEscapedString(sVal.(string)))
|
||||
if idx != len(x)-1 {
|
||||
str += ","
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user