From 6fb071cf377a9662d063b082ca20c73db65cbec3 Mon Sep 17 00:00:00 2001 From: Srikanth Chekuri Date: Fri, 18 Aug 2023 15:52:59 +0530 Subject: [PATCH] fix: escape quote and backslash for ClickHouse value (#3377) --- pkg/query-service/utils/format.go | 11 +++++++++-- pkg/query-service/utils/format_test.go | 13 +++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/pkg/query-service/utils/format.go b/pkg/query-service/utils/format.go index 0730d96b9f..5d2ef618d4 100644 --- a/pkg/query-service/utils/format.go +++ b/pkg/query-service/utils/format.go @@ -141,6 +141,13 @@ func ValidateAndCastValue(v interface{}, dataType v3.AttributeKeyDataType) (inte } } +func quoteEscapedString(str string) string { + // https://clickhouse.com/docs/en/sql-reference/syntax#string + str = strings.ReplaceAll(str, `\`, `\\`) + str = strings.ReplaceAll(str, `'`, `\'`) + return str +} + // ClickHouseFormattedValue formats the value to be used in clickhouse query func ClickHouseFormattedValue(v interface{}) string { // if it's pointer convert it to a value @@ -152,7 +159,7 @@ func ClickHouseFormattedValue(v interface{}) string { case float32, float64: return fmt.Sprintf("%f", x) case string: - return fmt.Sprintf("'%s'", x) + return fmt.Sprintf("'%s'", quoteEscapedString(x)) case bool: return fmt.Sprintf("%v", x) @@ -164,7 +171,7 @@ func ClickHouseFormattedValue(v interface{}) string { case string: str := "[" for idx, sVal := range x { - str += fmt.Sprintf("'%s'", sVal) + str += fmt.Sprintf("'%s'", quoteEscapedString(sVal.(string))) if idx != len(x)-1 { str += "," } diff --git a/pkg/query-service/utils/format_test.go b/pkg/query-service/utils/format_test.go index b4b652fe6e..594e544ce1 100644 --- a/pkg/query-service/utils/format_test.go +++ b/pkg/query-service/utils/format_test.go @@ -362,6 +362,19 @@ var testClickHouseFormattedValueData = []struct { value: []interface{}{&one, &one}, want: "[1,1]", }, + { + name: "string with single quote", + value: "test'1", + want: "'test\\'1'", + }, + { + name: "[]interface{} with string with single quote", + value: []interface{}{ + "test'1", + "test'2", + }, + want: "['test\\'1','test\\'2']", + }, } func TestClickHouseFormattedValue(t *testing.T) {