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

expression: support collation for REGEXP function #17255

Merged
merged 6 commits into from
Jun 2, 2020
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
11 changes: 8 additions & 3 deletions expression/builtin_like.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"regexp"
"sync"

"github.com/pingcap/parser/charset"
"github.com/pingcap/tidb/sessionctx"
"github.com/pingcap/tidb/types"
"github.com/pingcap/tidb/util/chunk"
Expand Down Expand Up @@ -121,7 +122,7 @@ func (c *regexpFunctionClass) getFunction(ctx sessionctx.Context, args []Express
}
bf.tp.Flen = 1
var sig builtinFunc
if types.IsBinaryStr(args[0].GetType()) || types.IsBinaryStr(args[1].GetType()) {
if bf.collation == charset.CollationBin {
sig = newBuiltinRegexpSig(bf)
sig.setPbCode(tipb.ScalarFuncSig_RegexpSig)
} else {
Expand Down Expand Up @@ -189,8 +190,12 @@ type builtinRegexpUTF8Sig struct {

func newBuiltinRegexpUTF8Sig(bf baseBuiltinFunc) *builtinRegexpUTF8Sig {
shared := builtinRegexpSharedSig{baseBuiltinFunc: bf}
shared.compile = func(pat string) (*regexp.Regexp, error) {
return regexp.Compile("(?i)" + pat)
if collate.IsCICollation(bf.collation) {
shared.compile = func(pat string) (*regexp.Regexp, error) {
return regexp.Compile("(?i)" + pat)
}
} else {
shared.compile = regexp.Compile
}
return &builtinRegexpUTF8Sig{builtinRegexpSharedSig: shared}
}
Expand Down
41 changes: 34 additions & 7 deletions expression/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -938,7 +938,7 @@ func (s *testIntegrationSuite2) TestStringBuiltin(c *C) {
tk.MustQuery(`select quote(null) REGEXP binary 'null'`).Check(testkit.Rows(`0`))
tk.MustQuery(`select quote(null) REGEXP binary 'NULL'`).Check(testkit.Rows(`1`))
tk.MustQuery(`select quote(null) REGEXP 'NULL'`).Check(testkit.Rows(`1`))
tk.MustQuery(`select quote(null) REGEXP 'null'`).Check(testkit.Rows(`1`))
tk.MustQuery(`select quote(null) REGEXP 'null'`).Check(testkit.Rows(`0`))
wshwsh12 marked this conversation as resolved.
Show resolved Hide resolved

// for convert
result = tk.MustQuery(`select convert("123" using "binary"), convert("中文" using "binary"), convert("中文" using "utf8"), convert("中文" using "utf8mb4"), convert(cast("中文" as binary) using "utf8");`)
Expand Down Expand Up @@ -2783,28 +2783,28 @@ func (s *testIntegrationSuite2) TestBuiltin(c *C) {
tk.MustExec(`drop table if exists t;`)
tk.MustExec(`create table t (a char(10), b varchar(10), c binary(10), d varbinary(10));`)
tk.MustExec(`insert into t values ('text','text','text','text');`)
result = tk.MustQuery(`select a regexp 'Xt' from t;`)
result = tk.MustQuery(`select a regexp 'xt' from t;`)
result.Check(testkit.Rows("1"))
result = tk.MustQuery(`select b regexp 'Xt' from t;`)
result = tk.MustQuery(`select b regexp 'xt' from t;`)
result.Check(testkit.Rows("1"))
result = tk.MustQuery(`select b regexp binary 'Xt' from t;`)
result.Check(testkit.Rows("0"))
result = tk.MustQuery(`select c regexp 'Xt' from t;`)
result.Check(testkit.Rows("0"))
result = tk.MustQuery(`select d regexp 'Xt' from t;`)
result.Check(testkit.Rows("0"))
result = tk.MustQuery(`select a rlike 'Xt' from t;`)
result = tk.MustQuery(`select a rlike 'xt' from t;`)
result.Check(testkit.Rows("1"))
result = tk.MustQuery(`select a rlike binary 'Xt' from t;`)
result.Check(testkit.Rows("0"))
result = tk.MustQuery(`select b rlike 'Xt' from t;`)
result = tk.MustQuery(`select b rlike 'xt' from t;`)
result.Check(testkit.Rows("1"))
result = tk.MustQuery(`select c rlike 'Xt' from t;`)
result.Check(testkit.Rows("0"))
result = tk.MustQuery(`select d rlike 'Xt' from t;`)
result.Check(testkit.Rows("0"))
result = tk.MustQuery(`select 'a' regexp 'A', 'a' regexp binary 'A'`)
result.Check(testkit.Rows("1 0"))
result.Check(testkit.Rows("0 0"))

// testCase is for like and regexp
type testCase struct {
Expand Down Expand Up @@ -6162,7 +6162,7 @@ func (s *testIntegrationSerialSuite) TestCollateStringFunction(c *C) {
tk.MustQuery("select INSTR(p4,n4) from t1;").Check(testkit.Rows("1"))

tk.MustExec("truncate table t1;")
tk.MustExec("insert into t1 (a,p1,p2,p3,p4,n1,n2,n3,n4) values (2,'0aA1!测试テストמבחן ','0aA1!测试テストמבחן ','0aA1!测试テストמבחן ','0aA1!测试テストמבחן ','0Aa1!测试テストמבחן','0Aa1!测试テストמבחן','0Aa1!测试テストמבחן','0Aa1!测试テストמבחן');")
tk.MustExec("insert into t1 (a,p1,p2,p3,p4,n1,n2,n3,n4) values (1,'0aA1!测试テストמבחן ','0aA1!测试テストמבחן ','0aA1!测试テストמבחן ','0aA1!测试テストמבחן ','0Aa1!测试テストמבחן','0Aa1!测试テストמבחן','0Aa1!测试テストמבחן','0Aa1!测试テストמבחן');")
tk.MustExec("insert into t1 (a,p1,p2,p3,p4,n1,n2,n3,n4) values (2,'0aA1!测试テストמבחן','0aA1!测试テストמבחן','0aA1!测试テストמבחן','0aA1!测试テストמבחן','0Aa1!测试テストמבחן','0Aa1!测试テストמבחן','0Aa1!测试テストמבחן','0Aa1!测试テストמבחן');")
tk.MustExec("insert into t1 (a,p1,p2,p3,p4,n1,n2,n3,n4) values (3,'0aA1!测试テストמבחן','0aA1!测试テストמבחן','0aA1!测试テストמבחן','0aA1!测试テストמבחן','0Aa1!测试テストמבחן ','0Aa1!测试テストמבחן ','0Aa1!测试テストמבחן ','0Aa1!测试テストמבחן ');")

Expand All @@ -6183,6 +6183,33 @@ func (s *testIntegrationSerialSuite) TestCollateStringFunction(c *C) {
tk.MustQuery("select LOCATE(p4,n3) from t1;").Check(testkit.Rows("0", "0", "0"))
tk.MustQuery("select LOCATE(p4,n4) from t1;").Check(testkit.Rows("0", "1", "1"))

tk.MustExec("truncate table t1;")
tk.MustExec("insert into t1 (a) values (1);")
tk.MustExec("insert into t1 (a,p1,p2,p3,p4,n1,n2,n3,n4) values (2,'0aA1!测试テストמבחן ','0aA1!测试テストמבחן ','0aA1!测试テストמבחן ','0aA1!测试テストמבחן ','0Aa1!测试テストמבחן','0Aa1!测试テストמבחן','0Aa1!测试テストמבחן','0Aa1!测试テストמבחן');")
tk.MustExec("insert into t1 (a,p1,p2,p3,p4,n1,n2,n3,n4) values (3,'0aA1!测试テストמבחן','0aA1!测试テストמבחן','0aA1!测试テストמבחן','0aA1!测试テストמבחן','0Aa1!测试テストמבחן','0Aa1!测试テストמבחן','0Aa1!测试テストמבחן','0Aa1!测试テストמבחן');")
tk.MustExec("insert into t1 (a,p1,p2,p3,p4,n1,n2,n3,n4) values (4,'0aA1!测试テストמבחן','0aA1!测试テストמבחן','0aA1!测试テストמבחן','0aA1!测试テストמבחן','0Aa1!测试テストמבחן ','0Aa1!测试テストמבחן ','0Aa1!测试テストמבחן ','0Aa1!测试テストמבחן ');")
tk.MustExec("insert into t1 (a,p1,p2,p3,p4,n1,n2,n3,n4) values (5,'0aA1!测试テストמבחן0aA1!测试','0aA1!测试テストמבחן0aA1!测试','0aA1!测试テストמבחן0aA1!测试','0aA1!测试テストמבחן0aA1!测试','0Aa1!测试','0Aa1!测试','0Aa1!测试','0Aa1!测试');")
tk.MustExec("insert into t1 (a,p1,p2,p3,p4,n1,n2,n3,n4) values (6,'0aA1!测试テストמבחן0aA1!测试','0aA1!测试テストמבחן0aA1!测试','0aA1!测试テストמבחן0aA1!测试','0aA1!测试テストמבחן0aA1!测试','0aA1!测试','0aA1!测试','0aA1!测试','0aA1!测试');")
tk.MustExec("insert into t1 (a,p1,p2,p3,p4,n1,n2,n3,n4) values (7,'0aA1!测试テストמבחן ','0aA1!测试テストמבחן ','0aA1!测试テストמבחן ','0aA1!测试テストמבחן ','0aA1!测试テストמבחן','0aA1!测试テストמבחן','0aA1!测试テストמבחן','0aA1!测试テストמבחן');")
tk.MustExec("insert into t1 (a,p1,p2,p3,p4,n1,n2,n3,n4) values (8,'0aA1!测试テストמבחן','0aA1!测试テストמבחן','0aA1!测试テストמבחן','0aA1!测试テストמבחן','0aA1!测试テストמבחן ','0aA1!测试テストמבחן ','0aA1!测试テストמבחן ','0aA1!测试テストמבחן ');")

tk.MustQuery("select p1 REGEXP n1 from t1;").Check(testkit.Rows("<nil>", "0", "0", "0", "0", "1", "1", "0"))
tk.MustQuery("select p1 REGEXP n2 from t1;").Check(testkit.Rows("<nil>", "0", "0", "0", "0", "1", "1", "0"))
tk.MustQuery("select p1 REGEXP n3 from t1;").Check(testkit.Rows("<nil>", "0", "0", "0", "0", "1", "1", "0"))
tk.MustQuery("select p1 REGEXP n4 from t1;").Check(testkit.Rows("<nil>", "1", "1", "0", "1", "1", "1", "0"))
tk.MustQuery("select p2 REGEXP n1 from t1;").Check(testkit.Rows("<nil>", "0", "0", "0", "0", "1", "1", "0"))
tk.MustQuery("select p2 REGEXP n2 from t1;").Check(testkit.Rows("<nil>", "1", "1", "0", "1", "1", "1", "0"))
tk.MustQuery("select p2 REGEXP n3 from t1;").Check(testkit.Rows("<nil>", "0", "0", "0", "0", "1", "1", "0"))
tk.MustQuery("select p2 REGEXP n4 from t1;").Check(testkit.Rows("<nil>", "1", "1", "0", "1", "1", "1", "0"))
tk.MustQuery("select p3 REGEXP n1 from t1;").Check(testkit.Rows("<nil>", "0", "0", "0", "0", "1", "1", "0"))
tk.MustQuery("select p3 REGEXP n2 from t1;").Check(testkit.Rows("<nil>", "0", "0", "0", "0", "1", "1", "0"))
tk.MustQuery("select p3 REGEXP n3 from t1;").Check(testkit.Rows("<nil>", "0", "0", "0", "0", "1", "1", "0"))
tk.MustQuery("select p3 REGEXP n4 from t1;").Check(testkit.Rows("<nil>", "0", "0", "0", "0", "1", "1", "0"))
tk.MustQuery("select p4 REGEXP n1 from t1;").Check(testkit.Rows("<nil>", "1", "1", "0", "1", "1", "1", "0"))
tk.MustQuery("select p4 REGEXP n2 from t1;").Check(testkit.Rows("<nil>", "1", "1", "0", "1", "1", "1", "0"))
tk.MustQuery("select p4 REGEXP n3 from t1;").Check(testkit.Rows("<nil>", "0", "0", "0", "0", "1", "1", "0"))
tk.MustQuery("select p4 REGEXP n4 from t1;").Check(testkit.Rows("<nil>", "1", "1", "0", "1", "1", "1", "0"))

tk.MustExec("drop table t1;")
}

Expand Down