From b63268559f0501eb24a86d9c5f451941e3a11541 Mon Sep 17 00:00:00 2001 From: Gani Georgiev Date: Sun, 11 Dec 2022 17:30:25 +0200 Subject: [PATCH] [#1231] fixed like escape expr --- tools/search/filter.go | 10 +++++----- tools/search/filter_test.go | 22 +++++++++++----------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tools/search/filter.go b/tools/search/filter.go index 516a79946..3135f58ef 100644 --- a/tools/search/filter.go +++ b/tools/search/filter.go @@ -97,23 +97,23 @@ func (f FilterData) resolveTokenizedExpr(expr fexpr.Expr, fieldResolver FieldRes case fexpr.SignLike: // the right side is a column and therefor wrap it with "%" for contains like behavior if len(rParams) == 0 { - return dbx.NewExp(fmt.Sprintf("%s LIKE ('%%' || %s || '%%')", lName, rName), lParams), nil + return dbx.NewExp(fmt.Sprintf("%s LIKE ('%%' || %s || '%%') ESCAPE '\\'", lName, rName), lParams), nil } - return dbx.NewExp(fmt.Sprintf("%s LIKE %s", lName, rName), mergeParams(lParams, wrapLikeParams(rParams))), nil + return dbx.NewExp(fmt.Sprintf("%s LIKE %s ESCAPE '\\'", lName, rName), mergeParams(lParams, wrapLikeParams(rParams))), nil case fexpr.SignNlike: // the right side is a column and therefor wrap it with "%" for not-contains like behavior if len(rParams) == 0 { - return dbx.NewExp(fmt.Sprintf("%s NOT LIKE ('%%' || %s || '%%')", lName, rName), lParams), nil + return dbx.NewExp(fmt.Sprintf("%s NOT LIKE ('%%' || %s || '%%') ESCAPE '\\'", lName, rName), lParams), nil } // normalize operands and switch sides if the left operand is a number/text, but the right one is a column // (usually this shouldn't be needed, but it's kept for backward compatibility) if len(lParams) > 0 && len(rParams) == 0 { - return dbx.NewExp(fmt.Sprintf("%s NOT LIKE %s", rName, lName), wrapLikeParams(lParams)), nil + return dbx.NewExp(fmt.Sprintf("%s NOT LIKE %s ESCAPE '\\'", rName, lName), wrapLikeParams(lParams)), nil } - return dbx.NewExp(fmt.Sprintf("%s NOT LIKE %s", lName, rName), mergeParams(lParams, wrapLikeParams(rParams))), nil + return dbx.NewExp(fmt.Sprintf("%s NOT LIKE %s ESCAPE '\\'", lName, rName), mergeParams(lParams, wrapLikeParams(rParams))), nil case fexpr.SignLt: return dbx.NewExp(fmt.Sprintf("%s < %s", lName, rName), mergeParams(lParams, rParams)), nil case fexpr.SignLte: diff --git a/tools/search/filter_test.go b/tools/search/filter_test.go index 98a8c23c7..cfdc21de3 100644 --- a/tools/search/filter_test.go +++ b/tools/search/filter_test.go @@ -35,7 +35,7 @@ func TestFilterDataBuildExpr(t *testing.T) { // like with 2 columns {"test1 ~ test2", false, "^" + - regexp.QuoteMeta("[[test1]] LIKE ('%' || [[test2]] || '%')") + + regexp.QuoteMeta("[[test1]] LIKE ('%' || [[test2]] || '%') ESCAPE '\\'") + "$", }, // like with right column operand @@ -43,7 +43,7 @@ func TestFilterDataBuildExpr(t *testing.T) { "^" + regexp.QuoteMeta("{:") + ".+" + - regexp.QuoteMeta("} LIKE ('%' || [[test1]] || '%')") + + regexp.QuoteMeta("} LIKE ('%' || [[test1]] || '%') ESCAPE '\\'") + "$", }, // like with left column operand and text as right operand @@ -51,13 +51,13 @@ func TestFilterDataBuildExpr(t *testing.T) { "^" + regexp.QuoteMeta("[[test1]] LIKE {:") + ".+" + - regexp.QuoteMeta("}") + + regexp.QuoteMeta("} ESCAPE '\\'") + "$", }, // not like with 2 columns {"test1 !~ test2", false, "^" + - regexp.QuoteMeta("[[test1]] NOT LIKE ('%' || [[test2]] || '%')") + + regexp.QuoteMeta("[[test1]] NOT LIKE ('%' || [[test2]] || '%') ESCAPE '\\'") + "$", }, // not like with right column operand @@ -65,7 +65,7 @@ func TestFilterDataBuildExpr(t *testing.T) { "^" + regexp.QuoteMeta("{:") + ".+" + - regexp.QuoteMeta("} NOT LIKE ('%' || [[test1]] || '%')") + + regexp.QuoteMeta("} NOT LIKE ('%' || [[test1]] || '%') ESCAPE '\\'") + "$", }, // like with left column operand and text as right operand @@ -73,7 +73,7 @@ func TestFilterDataBuildExpr(t *testing.T) { "^" + regexp.QuoteMeta("[[test1]] NOT LIKE {:") + ".+" + - regexp.QuoteMeta("}") + + regexp.QuoteMeta("} ESCAPE '\\'") + "$", }, // current datetime constant @@ -95,7 +95,7 @@ func TestFilterDataBuildExpr(t *testing.T) { ".+" + regexp.QuoteMeta("}, ''))) AND ([[test3]] LIKE {:") + ".+" + - regexp.QuoteMeta("})) AND (COALESCE([[test4.sub]], '') = COALESCE(NULL, ''))") + + regexp.QuoteMeta("} ESCAPE '\\')) AND (COALESCE([[test4.sub]], '') = COALESCE(NULL, ''))") + "$", }, // combination of special literals (null, true, false) @@ -111,13 +111,13 @@ func TestFilterDataBuildExpr(t *testing.T) { "^" + regexp.QuoteMeta("((((((((COALESCE([[test1]], '') = COALESCE([[test2]], '')) OR (COALESCE([[test2]], '') != COALESCE([[test3]], ''))) AND (([[test2]] LIKE {:") + ".+" + - regexp.QuoteMeta("}) OR ([[test2]] NOT LIKE {:") + + regexp.QuoteMeta("} ESCAPE '\\') OR ([[test2]] NOT LIKE {:") + ".+" + - regexp.QuoteMeta("}))) AND ({:") + + regexp.QuoteMeta("} ESCAPE '\\'))) AND ({:") + ".+" + - regexp.QuoteMeta("} LIKE ('%' || [[test1]] || '%'))) AND ({:") + + regexp.QuoteMeta("} LIKE ('%' || [[test1]] || '%') ESCAPE '\\')) AND ({:") + ".+" + - regexp.QuoteMeta("} NOT LIKE ('%' || [[test2]] || '%'))) AND ([[test3]] > {:") + + regexp.QuoteMeta("} NOT LIKE ('%' || [[test2]] || '%') ESCAPE '\\')) AND ([[test3]] > {:") + ".+" + regexp.QuoteMeta("})) AND ([[test3]] >= {:") + ".+" +