From 996a72be4b8aeb4a5da4dabd23dbceac31cb55d9 Mon Sep 17 00:00:00 2001 From: sylzd Date: Mon, 6 Dec 2021 19:19:22 +0800 Subject: [PATCH 1/6] init complete --- expression/builtin_convert_charset.go | 5 +++++ expression/integration_test.go | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/expression/builtin_convert_charset.go b/expression/builtin_convert_charset.go index aac9d1680ddda..5715f063f2517 100644 --- a/expression/builtin_convert_charset.go +++ b/expression/builtin_convert_charset.go @@ -22,6 +22,7 @@ import ( "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/charset" "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/chunk" @@ -65,6 +66,10 @@ func (c *tidbToBinaryFunctionClass) getFunction(ctx sessionctx.Context, args []E return nil, err } bf.tp = args[0].GetType().Clone() + // adjust enum type + if bf.tp.Equal(types.NewFieldType(mysql.TypeEnum)) && !mysql.HasEnumSetAsIntFlag(bf.tp.Flag) { + bf.tp = types.NewFieldType(mysql.TypeString) + } bf.tp.Charset, bf.tp.Collate = charset.CharsetBin, charset.CollationBin sig = &builtinInternalToBinarySig{bf} sig.setPbCode(tipb.ScalarFuncSig_ToBinary) diff --git a/expression/integration_test.go b/expression/integration_test.go index 29dbc7e91bcc9..f9957021ac2d2 100644 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -9900,6 +9900,15 @@ func (s *testIntegrationSuite) TestEnumIndex(c *C) { testkit.Rows(" ")) tk.MustQuery("select /*+ inl_hash_join(t1,t2) */ * from t t1 join t t2 on t1.e=t2.e;").Check( testkit.Rows(" ")) + + // issue30174 + tk.MustExec("drop table if exists t1,t2;") + tk.MustExec("CREATE TABLE `t1` (\n `c1` enum('Alice','Bob','Charlie','David') NOT NULL,\n `c2` blob NOT NULL,\n PRIMARY KEY (`c2`(5)),\n UNIQUE KEY `idx_89` (`c1`)\n);") + tk.MustExec("CREATE TABLE `t2` (\n `c1` enum('Alice','Bob','Charlie','David') NOT NULL DEFAULT 'Alice',\n `c2` enum('Alice','Bob','Charlie','David') NOT NULL DEFAULT 'David',\n `c3` enum('Alice','Bob','Charlie','David') NOT NULL,\n PRIMARY KEY (`c3`,`c2`)\n);") + tk.MustExec("insert into t1 values('Charlie','');") + tk.MustExec("insert into t2 values('Charlie','Charlie','Alice');") + tk.MustQuery("select * from t2 where c3 in (select c2 from t1);").Check( + testkit.Rows()) } // Previously global values were cached. This is incorrect. From d1a9b03bda50c59eb407b4aa7cc8df9191511f77 Mon Sep 17 00:00:00 2001 From: sylzd Date: Mon, 6 Dec 2021 19:47:46 +0800 Subject: [PATCH 2/6] fix --- expression/builtin_convert_charset.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/expression/builtin_convert_charset.go b/expression/builtin_convert_charset.go index 5715f063f2517..6aad18dbcdc8a 100644 --- a/expression/builtin_convert_charset.go +++ b/expression/builtin_convert_charset.go @@ -67,7 +67,7 @@ func (c *tidbToBinaryFunctionClass) getFunction(ctx sessionctx.Context, args []E } bf.tp = args[0].GetType().Clone() // adjust enum type - if bf.tp.Equal(types.NewFieldType(mysql.TypeEnum)) && !mysql.HasEnumSetAsIntFlag(bf.tp.Flag) { + if bf.tp.Tp == mysql.TypeEnum && !mysql.HasEnumSetAsIntFlag(bf.tp.Flag) { bf.tp = types.NewFieldType(mysql.TypeString) } bf.tp.Charset, bf.tp.Collate = charset.CharsetBin, charset.CollationBin From 6d94a0f6d44bc09cb5c2cfeb8b3abd640c23fd89 Mon Sep 17 00:00:00 2001 From: sylzd Date: Thu, 9 Dec 2021 17:25:04 +0800 Subject: [PATCH 3/6] add set type --- expression/builtin_convert_charset.go | 4 ++-- expression/integration_test.go | 21 ++++++++++++--------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/expression/builtin_convert_charset.go b/expression/builtin_convert_charset.go index 6aad18dbcdc8a..226fe79aefcef 100644 --- a/expression/builtin_convert_charset.go +++ b/expression/builtin_convert_charset.go @@ -66,8 +66,8 @@ func (c *tidbToBinaryFunctionClass) getFunction(ctx sessionctx.Context, args []E return nil, err } bf.tp = args[0].GetType().Clone() - // adjust enum type - if bf.tp.Tp == mysql.TypeEnum && !mysql.HasEnumSetAsIntFlag(bf.tp.Flag) { + // adjust enum/set type + if bf.tp.Tp == mysql.TypeEnum || bf.tp.Tp == mysql.TypeSet { bf.tp = types.NewFieldType(mysql.TypeString) } bf.tp.Charset, bf.tp.Collate = charset.CharsetBin, charset.CollationBin diff --git a/expression/integration_test.go b/expression/integration_test.go index f9957021ac2d2..499810910bd53 100644 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -9900,15 +9900,6 @@ func (s *testIntegrationSuite) TestEnumIndex(c *C) { testkit.Rows(" ")) tk.MustQuery("select /*+ inl_hash_join(t1,t2) */ * from t t1 join t t2 on t1.e=t2.e;").Check( testkit.Rows(" ")) - - // issue30174 - tk.MustExec("drop table if exists t1,t2;") - tk.MustExec("CREATE TABLE `t1` (\n `c1` enum('Alice','Bob','Charlie','David') NOT NULL,\n `c2` blob NOT NULL,\n PRIMARY KEY (`c2`(5)),\n UNIQUE KEY `idx_89` (`c1`)\n);") - tk.MustExec("CREATE TABLE `t2` (\n `c1` enum('Alice','Bob','Charlie','David') NOT NULL DEFAULT 'Alice',\n `c2` enum('Alice','Bob','Charlie','David') NOT NULL DEFAULT 'David',\n `c3` enum('Alice','Bob','Charlie','David') NOT NULL,\n PRIMARY KEY (`c3`,`c2`)\n);") - tk.MustExec("insert into t1 values('Charlie','');") - tk.MustExec("insert into t2 values('Charlie','Charlie','Alice');") - tk.MustQuery("select * from t2 where c3 in (select c2 from t1);").Check( - testkit.Rows()) } // Previously global values were cached. This is incorrect. @@ -10657,3 +10648,15 @@ func (s *testIntegrationSuite) TestIssue29513(c *C) { tk.MustQuery("select '123' union select cast(a as char) from t;").Sort().Check(testkit.Rows("123", "45678")) tk.MustQuery("select '123' union select cast(a as char(2)) from t;").Sort().Check(testkit.Rows("123", "45")) } + +func (s *testIntegrationSuite) TestIssue30174(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t1,t2;") + tk.MustExec("CREATE TABLE `t1` (\n `c1` enum('Alice','Bob','Charlie','David') NOT NULL,\n `c2` blob NOT NULL,\n PRIMARY KEY (`c2`(5)),\n UNIQUE KEY `idx_89` (`c1`)\n);") + tk.MustExec("CREATE TABLE `t2` (\n `c1` enum('Alice','Bob','Charlie','David') NOT NULL DEFAULT 'Alice',\n `c2` set('Alice','Bob','Charlie','David') NOT NULL DEFAULT 'David',\n `c3` enum('Alice','Bob','Charlie','David') NOT NULL,\n PRIMARY KEY (`c3`,`c2`)\n);") + tk.MustExec("insert into t1 values('Charlie','');") + tk.MustExec("insert into t2 values('Charlie','Charlie','Alice');") + tk.MustQuery("select * from t2 where c3 in (select c2 from t1);").Check(testkit.Rows()) + tk.MustQuery("select * from t2 where c2 in (select c2 from t1);").Check(testkit.Rows()) +} From dea0746cccef3785e74ecaf2ecdfc9c88808510b Mon Sep 17 00:00:00 2001 From: sylzd Date: Thu, 9 Dec 2021 17:30:04 +0800 Subject: [PATCH 4/6] fix --- expression/builtin_convert_charset.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/expression/builtin_convert_charset.go b/expression/builtin_convert_charset.go index 295f965886ac5..4805a676ee6b9 100644 --- a/expression/builtin_convert_charset.go +++ b/expression/builtin_convert_charset.go @@ -68,7 +68,7 @@ func (c *tidbToBinaryFunctionClass) getFunction(ctx sessionctx.Context, args []E bf.tp = args[0].GetType().Clone() // adjust enum/set type if bf.tp.Tp == mysql.TypeEnum || bf.tp.Tp == mysql.TypeSet { - bf.tp = types.NewFieldType(mysql.TypeString) + bf.tp.Tp = mysql.TypeString } bf.tp.Charset, bf.tp.Collate = charset.CharsetBin, charset.CollationBin sig = &builtinInternalToBinarySig{bf} From dae086362c28c8ec8fc6fed1e27f4cfabbb7c166 Mon Sep 17 00:00:00 2001 From: sylzd Date: Wed, 15 Dec 2021 12:16:16 +0800 Subject: [PATCH 5/6] Update expression/builtin_convert_charset.go to_binary should always return string type Co-authored-by: xiongjiwei --- expression/builtin_convert_charset.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/expression/builtin_convert_charset.go b/expression/builtin_convert_charset.go index 4805a676ee6b9..fc709cc7c61f0 100644 --- a/expression/builtin_convert_charset.go +++ b/expression/builtin_convert_charset.go @@ -66,10 +66,7 @@ func (c *tidbToBinaryFunctionClass) getFunction(ctx sessionctx.Context, args []E return nil, err } bf.tp = args[0].GetType().Clone() - // adjust enum/set type - if bf.tp.Tp == mysql.TypeEnum || bf.tp.Tp == mysql.TypeSet { - bf.tp.Tp = mysql.TypeString - } + bf.tp.Tp = mysql.TypeVarString bf.tp.Charset, bf.tp.Collate = charset.CharsetBin, charset.CollationBin sig = &builtinInternalToBinarySig{bf} sig.setPbCode(tipb.ScalarFuncSig_ToBinary) From 74359d36ae50fa3db579221a77b97ab67c514184 Mon Sep 17 00:00:00 2001 From: xiongjiwei Date: Wed, 15 Dec 2021 14:03:23 +0800 Subject: [PATCH 6/6] Update expression/integration_test.go --- expression/integration_test.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/expression/integration_test.go b/expression/integration_test.go index 2f5ce4b216adc..79cb81daf90f6 100644 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -6896,8 +6896,10 @@ func TestIssue30326(t *testing.T) { require.Error(t, err, "[executor:1242]Subquery returns more than 1 row") } -func (s *testIntegrationSuite) TestIssue30174(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestIssue30174(t *testing.T) { + store, clean := testkit.CreateMockStore(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test") tk.MustExec("drop table if exists t1,t2;") tk.MustExec("CREATE TABLE `t1` (\n `c1` enum('Alice','Bob','Charlie','David') NOT NULL,\n `c2` blob NOT NULL,\n PRIMARY KEY (`c2`(5)),\n UNIQUE KEY `idx_89` (`c1`)\n);")