From 97328f6295277d7df8354626e625747ecb8770bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Garc=C3=ADa=20Montoro?= Date: Thu, 12 Sep 2019 19:17:22 +0200 Subject: [PATCH] Convert LIKE patterns to specific Go regexes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Alejandro GarcĂ­a Montoro --- sql/expression/like.go | 7 ++++--- sql/expression/like_test.go | 26 +++++++++++++------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/sql/expression/like.go b/sql/expression/like.go index 1fcf08bf8..7913eb22c 100644 --- a/sql/expression/like.go +++ b/sql/expression/like.go @@ -68,11 +68,11 @@ func (l *Like) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { if err != nil { return nil, err } - right = patternToRegex(v.(string)) + right = patternToGoRegex(v.(string)) } // for non-cached regex every time create a new matcher if !l.cached { - matcher, disposer, err = regex.New(regex.Default(), right) + matcher, disposer, err = regex.New("go", right) } else { if l.pool == nil { l.pool = &sync.Pool{ @@ -115,8 +115,9 @@ func (l *Like) WithChildren(children ...sql.Expression) (sql.Expression, error) return NewLike(children[0], children[1]), nil } -func patternToRegex(pattern string) string { +func patternToGoRegex(pattern string) string { var buf bytes.Buffer + buf.WriteString("(?s)") buf.WriteRune('^') var escaped bool for _, r := range strings.Replace(regexp.QuoteMeta(pattern), `\\`, `\`, -1) { diff --git a/sql/expression/like_test.go b/sql/expression/like_test.go index 0f5dcae9b..78b768bec 100644 --- a/sql/expression/like_test.go +++ b/sql/expression/like_test.go @@ -12,23 +12,23 @@ func TestPatternToRegex(t *testing.T) { testCases := []struct { in, out string }{ - {`__`, `^..$`}, - {`_%_`, `^..*.$`}, - {`%_`, `^.*.$`}, - {`_%`, `^..*$`}, - {`a_b`, `^a.b$`}, - {`a%b`, `^a.*b$`}, - {`a.%b`, `^a\..*b$`}, - {`a\%b`, `^a%b$`}, - {`a\_b`, `^a_b$`}, - {`a\\b`, `^a\\b$`}, - {`a\\\_b`, `^a\\_b$`}, - {`(ab)`, `^\(ab\)$`}, + {`__`, `(?s)^..$`}, + {`_%_`, `(?s)^..*.$`}, + {`%_`, `(?s)^.*.$`}, + {`_%`, `(?s)^..*$`}, + {`a_b`, `(?s)^a.b$`}, + {`a%b`, `(?s)^a.*b$`}, + {`a.%b`, `(?s)^a\..*b$`}, + {`a\%b`, `(?s)^a%b$`}, + {`a\_b`, `(?s)^a_b$`}, + {`a\\b`, `(?s)^a\\b$`}, + {`a\\\_b`, `(?s)^a\\_b$`}, + {`(ab)`, `(?s)^\(ab\)$`}, } for _, tt := range testCases { t.Run(tt.in, func(t *testing.T) { - require.Equal(t, tt.out, patternToRegex(tt.in)) + require.Equal(t, tt.out, patternToGoRegex(tt.in)) }) } }