From a21a6f0bcce120dce8865dcee38413019bf51aae Mon Sep 17 00:00:00 2001 From: guo-shaoge Date: Sun, 28 Nov 2021 01:10:50 +0800 Subject: [PATCH] add more case Signed-off-by: guo-shaoge --- expression/builtin_string.go | 1 + expression/distsql_builtin.go | 2 ++ expression/expression.go | 2 +- planner/core/integration_test.go | 57 ++++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/expression/builtin_string.go b/expression/builtin_string.go index d7afdc3f1c1a7..69c99e7f8715c 100644 --- a/expression/builtin_string.go +++ b/expression/builtin_string.go @@ -131,6 +131,7 @@ var ( _ builtinFunc = &builtinBitLengthSig{} _ builtinFunc = &builtinCharSig{} _ builtinFunc = &builtinCharLengthUTF8Sig{} + _ builtinFunc = &builtinCharLengthBinarySig{} _ builtinFunc = &builtinFindInSetSig{} _ builtinFunc = &builtinMakeSetSig{} _ builtinFunc = &builtinOctIntSig{} diff --git a/expression/distsql_builtin.go b/expression/distsql_builtin.go index 7fd61b30fa3fa..2e29a588ba252 100644 --- a/expression/distsql_builtin.go +++ b/expression/distsql_builtin.go @@ -932,6 +932,8 @@ func getSignatureByPB(ctx sessionctx.Context, sigCode tipb.ScalarFuncSig, tp *ti f = &builtinCharSig{base} case tipb.ScalarFuncSig_CharLengthUTF8: f = &builtinCharLengthUTF8Sig{base} + case tipb.ScalarFuncSig_CharLength: + f = &builtinCharLengthBinarySig{base} case tipb.ScalarFuncSig_Concat: f = &builtinConcatSig{base, maxAllowedPacket} case tipb.ScalarFuncSig_ConcatWS: diff --git a/expression/expression.go b/expression/expression.go index 9adb5cf77a5fa..c057eac08144a 100644 --- a/expression/expression.go +++ b/expression/expression.go @@ -955,7 +955,7 @@ func scalarExprSupportedByTiKV(sf *ScalarFunction) bool { // string functions. ast.Length, ast.BitLength, ast.Concat, ast.ConcatWS /*ast.Locate,*/, ast.Replace, ast.ASCII, ast.Hex, - ast.Reverse, ast.LTrim, ast.RTrim /*ast.Left,*/, ast.Strcmp, ast.Space, ast.Elt, ast.Field, ast.Substring, + ast.Reverse, ast.LTrim, ast.RTrim /*ast.Left,*/, ast.Strcmp, ast.Space, ast.Elt, ast.Field, ast.Substring, ast.CharLength, // json functions. ast.JSONType, ast.JSONExtract, ast.JSONObject, ast.JSONArray, ast.JSONMerge, ast.JSONSet, diff --git a/planner/core/integration_test.go b/planner/core/integration_test.go index 2ad2a529e85fa..cb68446dea0f0 100644 --- a/planner/core/integration_test.go +++ b/planner/core/integration_test.go @@ -4087,3 +4087,60 @@ func (s *testIntegrationSuite) TestIssues27130(c *C) { " └─IndexRangeScan 10.00 cop[tikv] table:t3, index:a(a, b, c) range:[1,1], keep order:false, stats:pseudo", )) } + +func (s *testIntegrationSuite) TestIndexMergeExprs(c *C) { + tk := testkit.NewTestKitWithInit(c, s.store) + // varbinary and binary can be used in IndexMerge. + tk.MustExec("drop table if exists t1;") + tk.MustExec("create table t1(c1 varchar(100), c2 varchar(100), c3 varbinary(100), c4 binary(100), key(c1), key(c2));") + tk.MustExec("insert into t1 values('ab', '10', '10', '10');") + tk.MustQuery("explain select /*+ use_index_merge(t1) */ * from t1 where c1 = 'de' or c2 = '10' and substring(c3, 10) = 10;").Check(testkit.Rows( + "IndexMerge_9 0.04 root ", + "├─IndexRangeScan_5(Build) 10.00 cop[tikv] table:t1, index:c1(c1) range:[\"de\",\"de\"], keep order:false, stats:pseudo", + "├─IndexRangeScan_6(Build) 10.00 cop[tikv] table:t1, index:c2(c2) range:[\"10\",\"10\"], keep order:false, stats:pseudo", + "└─Selection_8(Probe) 0.04 cop[tikv] or(eq(test.t1.c1, \"de\"), and(eq(test.t1.c2, \"10\"), eq(cast(substring(test.t1.c3, 10), double BINARY), 10)))", + " └─TableRowIDScan_7 19.99 cop[tikv] table:t1 keep order:false, stats:pseudo")) + tk.MustQuery("explain select /*+ use_index_merge(t1) */ * from t1 where c1 = 'de' or c2 = '10' and substring(c4, 10) = 10;").Check(testkit.Rows( + "IndexMerge_9 0.04 root ", + "├─IndexRangeScan_5(Build) 10.00 cop[tikv] table:t1, index:c1(c1) range:[\"de\",\"de\"], keep order:false, stats:pseudo", + "├─IndexRangeScan_6(Build) 10.00 cop[tikv] table:t1, index:c2(c2) range:[\"10\",\"10\"], keep order:false, stats:pseudo", + "└─Selection_8(Probe) 0.04 cop[tikv] or(eq(test.t1.c1, \"de\"), and(eq(test.t1.c2, \"10\"), eq(cast(substring(test.t1.c4, 10), double BINARY), 10)))", + " └─TableRowIDScan_7 19.99 cop[tikv] table:t1 keep order:false, stats:pseudo")) + + tk.MustQuery("select /*+ use_index_merge(t1) */ 1 from t1 where c1 = 'de' or c2 = '10' and substring(c3, 1) = 10;").Check(testkit.Rows("1")) + tk.MustQuery("select /*+ use_index_merge(t1) */ 1 from t1 where c1 = 'de' or c2 = '10' and substring(c4, 1) = 10;").Check(testkit.Rows("1")) + tk.MustQuery("select /*+ use_index_merge(t1) */ 1 from t1 where c1 = 'de' or c2 = '10' and substring(c3, 1) = 1;").Check(testkit.Rows()) + tk.MustQuery("select /*+ use_index_merge(t1) */ 1 from t1 where c1 = 'de' or c2 = '10' and substring(c4, 1) = 1;").Check(testkit.Rows()) + + // Test char_length. + tk.MustExec("insert into t1 values('ab', '10', '1234567ab', '1234567ab');") + tk.MustQuery("explain select /*+ use_index_merge(t1) */ * from t1 where c1 = 'de' or c2 = '10' and substring(c3, char_length(c3) - 5) = '567ab';").Check(testkit.Rows( + "IndexMerge_9 0.04 root ", + "├─IndexRangeScan_5(Build) 10.00 cop[tikv] table:t1, index:c1(c1) range:[\"de\",\"de\"], keep order:false, stats:pseudo", + "├─IndexRangeScan_6(Build) 10.00 cop[tikv] table:t1, index:c2(c2) range:[\"10\",\"10\"], keep order:false, stats:pseudo", + "└─Selection_8(Probe) 0.04 cop[tikv] or(eq(test.t1.c1, \"de\"), and(eq(test.t1.c2, \"10\"), eq(substring(test.t1.c3, minus(char_length(test.t1.c3), 5)), \"567ab\")))", + " └─TableRowIDScan_7 19.99 cop[tikv] table:t1 keep order:false, stats:pseudo")) + tk.MustQuery("explain select /*+ use_index_merge(t1) */ * from t1 where c1 = 'de' or c2 = '10' and substring(c3, char_length(c4) - 5) = '567ab';").Check(testkit.Rows( + "IndexMerge_9 0.04 root ", + "├─IndexRangeScan_5(Build) 10.00 cop[tikv] table:t1, index:c1(c1) range:[\"de\",\"de\"], keep order:false, stats:pseudo", + "├─IndexRangeScan_6(Build) 10.00 cop[tikv] table:t1, index:c2(c2) range:[\"10\",\"10\"], keep order:false, stats:pseudo", + "└─Selection_8(Probe) 0.04 cop[tikv] or(eq(test.t1.c1, \"de\"), and(eq(test.t1.c2, \"10\"), eq(substring(test.t1.c3, minus(char_length(test.t1.c4), 5)), \"567ab\")))", + " └─TableRowIDScan_7 19.99 cop[tikv] table:t1 keep order:false, stats:pseudo")) + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where c1 = 'de' or c2 = '10' and substring(c3, char_length(c3) - 5) = '4567ab';").Check(testkit.Rows("1")) + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where c1 = 'de' or c2 = '10' and substring(c3, char_length(c4) - 5) = '4567ab';").Check(testkit.Rows("1")) + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where c1 = 'de' or c2 = '10' and substring(c3, char_length(c3) - 5) = '123';").Check(testkit.Rows("")) + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where c1 = 'de' or c2 = '10' and substring(c3, char_length(c4) - 5) = '123';").Check(testkit.Rows("")) + + // varchar can be used in IndexMerge. + tk.MustExec("drop table if exists t1;") + tk.MustExec("create table t1(c1 varchar(100), c2 varchar(100), c3 varchar(100), key(c1), key(c2));") + tk.MustExec("insert into t1 values('ab', '10', '10');") + tk.MustQuery("explain select /*+ use_index_merge(t1) */ * from t1 where c1 = 'de' or c2 = '10' and substring(c3, 10) = 10;").Check(testkit.Rows( + "IndexMerge_9 0.04 root ", + "├─IndexRangeScan_5(Build) 10.00 cop[tikv] table:t1, index:c1(c1) range:[\"de\",\"de\"], keep order:false, stats:pseudo", + "├─IndexRangeScan_6(Build) 10.00 cop[tikv] table:t1, index:c2(c2) range:[\"10\",\"10\"], keep order:false, stats:pseudo", + "└─Selection_8(Probe) 0.04 cop[tikv] or(eq(test.t1.c1, \"de\"), and(eq(test.t1.c2, \"10\"), eq(cast(substring(test.t1.c3, 10), double BINARY), 10)))", + " └─TableRowIDScan_7 19.99 cop[tikv] table:t1 keep order:false, stats:pseudo")) + tk.MustQuery("select /*+ use_index_merge(t1) */ 1 from t1 where c1 = 'de' or c2 = '10' and substring(c3, 1) = 10;").Check(testkit.Rows("1")) + tk.MustQuery("select /*+ use_index_merge(t1) */ 1 from t1 where c1 = 'de' or c2 = '10' and substring(c3, 1) = 1;").Check(testkit.Rows()) +}