From ae80afe90915c8378ef6c1fab72a7b2cf3b8aee0 Mon Sep 17 00:00:00 2001 From: Reminiscent Date: Wed, 2 Nov 2022 20:22:38 +0800 Subject: [PATCH 1/2] planner: treat null as a different type compare to other types --- planner/core/plan_cache_test.go | 27 +++++++++++++++++++++++++++ planner/core/plan_cache_utils.go | 4 +--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/planner/core/plan_cache_test.go b/planner/core/plan_cache_test.go index 919c1b5979ad2..6a97837bb38d4 100644 --- a/planner/core/plan_cache_test.go +++ b/planner/core/plan_cache_test.go @@ -149,3 +149,30 @@ func TestIssue38533(t *testing.T) { tk.MustExec(`execute st using @a, @a`) tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) } + +func TestIssue38710(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("drop table if exists UK_NO_PRECISION_19392;") + tk.MustExec("CREATE TABLE `UK_NO_PRECISION_19392` (\n `COL1` bit(1) DEFAULT NULL,\n `COL2` varchar(20) COLLATE utf8mb4_bin DEFAULT NULL,\n `COL4` datetime DEFAULT NULL,\n `COL3` bigint DEFAULT NULL,\n `COL5` float DEFAULT NULL,\n UNIQUE KEY `UK_COL1` (`COL1`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;") + tk.MustExec("INSERT INTO `UK_NO_PRECISION_19392` VALUES (0x00,'缎馗惫砲兣肬憵急鳸嫅稩邏蠧鄂艘腯灩專妴粈','9294-12-26 06:50:40',-3088380202191555887,-3.33294e38),(NULL,'仲膩蕦圓猴洠飌镂喵疎偌嫺荂踖Ƕ藨蜿諪軁笞','1746-08-30 18:04:04',-4016793239832666288,-2.52633e38),(0x01,'冑溜畁脊乤纊繳蟥哅稐奺躁悼貘飗昹槐速玃沮','1272-01-19 23:03:27',-8014797887128775012,1.48868e38);\n") + tk.MustExec(`prepare stmt from 'select * from UK_NO_PRECISION_19392 where col1 between ? and ? or col3 = ? or col2 in (?, ?, ?);';`) + tk.MustExec("set @a=0x01, @b=0x01, @c=-3088380202191555887, @d=\"缎馗惫砲兣肬憵急鳸嫅稩邏蠧鄂艘腯灩專妴粈\", @e=\"缎馗惫砲兣肬憵急鳸嫅稩邏蠧鄂艘腯灩專妴粈\", @f=\"缎馗惫砲兣肬憵急鳸嫅稩邏蠧鄂艘腯灩專妴粈\";") + rows := tk.MustQuery(`execute stmt using @a,@b,@c,@d,@e,@f;`) // can not be cached because @a = @b + require.Equal(t, 2, len(rows.Rows())) + + tk.MustExec(`set @a=NULL, @b=NULL, @c=-4016793239832666288, @d="缎馗惫砲兣肬憵急鳸嫅稩邏蠧鄂艘腯灩專妴粈", @e="仲膩蕦圓猴洠飌镂喵疎偌嫺荂踖Ƕ藨蜿諪軁笞", @f="缎馗惫砲兣肬憵急鳸嫅稩邏蠧鄂艘腯灩專妴粈";`) + rows = tk.MustQuery(`execute stmt using @a,@b,@c,@d,@e,@f;`) + require.Equal(t, 2, len(rows.Rows())) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) + + rows = tk.MustQuery(`execute stmt using @a,@b,@c,@d,@e,@f;`) + require.Equal(t, 2, len(rows.Rows())) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) + + tk.MustExec(`set @a=0x01, @b=0x01, @c=-3088380202191555887, @d="缎馗惫砲兣肬憵急鳸嫅稩邏蠧鄂艘腯灩專妴粈", @e="缎馗惫砲兣肬憵急鳸嫅稩邏蠧鄂艘腯灩專妴粈", @f="缎馗惫砲兣肬憵急鳸嫅稩邏蠧鄂艘腯灩專妴粈";`) + rows = tk.MustQuery(`execute stmt using @a,@b,@c,@d,@e,@f;`) + require.Equal(t, 2, len(rows.Rows())) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) // can not use the cache because the types for @a and @b are not equal to the cached plan +} diff --git a/planner/core/plan_cache_utils.go b/planner/core/plan_cache_utils.go index 6c4a8298290fd..0abecafaf7ec8 100644 --- a/planner/core/plan_cache_utils.go +++ b/planner/core/plan_cache_utils.go @@ -322,9 +322,7 @@ func (s FieldSlice) CheckTypesCompatibility4PC(tps []*types.FieldType) bool { // string types will show up here, and (2) we don't need flen and decimal to be matched exactly to use plan cache tpEqual := (s[i].GetType() == tps[i].GetType()) || (s[i].GetType() == mysql.TypeVarchar && tps[i].GetType() == mysql.TypeVarString) || - (s[i].GetType() == mysql.TypeVarString && tps[i].GetType() == mysql.TypeVarchar) || - // TypeNull should be considered the same as other types. - (s[i].GetType() == mysql.TypeNull || tps[i].GetType() == mysql.TypeNull) + (s[i].GetType() == mysql.TypeVarString && tps[i].GetType() == mysql.TypeVarchar) if !tpEqual || s[i].GetCharset() != tps[i].GetCharset() || s[i].GetCollate() != tps[i].GetCollate() || (s[i].EvalType() == types.ETInt && mysql.HasUnsignedFlag(s[i].GetFlag()) != mysql.HasUnsignedFlag(tps[i].GetFlag())) { return false From 3e36c0ae2acb8ce713cb3c746cf935103626e688 Mon Sep 17 00:00:00 2001 From: Reminiscent Date: Thu, 3 Nov 2022 10:09:35 +0800 Subject: [PATCH 2/2] fix ut --- executor/prepared_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/executor/prepared_test.go b/executor/prepared_test.go index 2b8b98c246267..5ebc97e9c0dcc 100644 --- a/executor/prepared_test.go +++ b/executor/prepared_test.go @@ -1030,7 +1030,7 @@ func TestPreparePlanCache4Function(t *testing.T) { tk.MustExec("set @a = 0, @b = 1, @c = 2, @d = null;") tk.MustQuery("execute stmt using @a, @b;").Check(testkit.Rows(" 2", "0 0", "1 1", "2 2")) tk.MustQuery("execute stmt using @c, @d;").Check(testkit.Rows(" 1", "0 2", "1 2", "2 0")) - tk.MustQuery("select @@last_plan_from_cache;").Check(testkit.Rows("1")) + tk.MustQuery("select @@last_plan_from_cache;").Check(testkit.Rows("0")) } func TestPreparePlanCache4DifferentSystemVars(t *testing.T) {