diff --git a/expression/constant.go b/expression/constant.go index 9531153582dc9..1e5c50a709e9c 100644 --- a/expression/constant.go +++ b/expression/constant.go @@ -25,6 +25,7 @@ import ( "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/codec" + "github.com/pingcap/tidb/util/collate" ) // NewOne stands for a number 1. @@ -345,7 +346,7 @@ func (c *Constant) Equal(ctx sessionctx.Context, b Expression) bool { if err1 != nil || err2 != nil { return false } - con, err := c.Value.CompareDatum(ctx.GetSessionVars().StmtCtx, &y.Value) + con, err := c.Value.Compare(ctx.GetSessionVars().StmtCtx, &y.Value, collate.GetBinaryCollator()) if err != nil || con != 0 { return false } diff --git a/expression/constant_propagation.go b/expression/constant_propagation.go index 70fea317fe57b..5e7374604ac1d 100644 --- a/expression/constant_propagation.go +++ b/expression/constant_propagation.go @@ -21,6 +21,7 @@ import ( "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/chunk" + "github.com/pingcap/tidb/util/collate" "github.com/pingcap/tidb/util/disjointset" "github.com/pingcap/tidb/util/logutil" "go.uber.org/zap" @@ -59,7 +60,8 @@ func (s *basePropConstSolver) tryToUpdateEQList(col *Column, con *Constant) (boo id := s.getColID(col) oldCon := s.eqList[id] if oldCon != nil { - return false, !oldCon.Equal(s.ctx, con) + res, err := oldCon.Value.Compare(s.ctx.GetSessionVars().StmtCtx, &con.Value, collate.GetCollator(col.GetType().Collate)) + return false, res != 0 || err != nil } s.eqList[id] = con return true, false diff --git a/expression/integration_test.go b/expression/integration_test.go index fdf9f7b1d26b3..29dbc7e91bcc9 100644 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -6835,6 +6835,7 @@ func (s *testIntegrationSerialSuite) TestCollateConstantPropagation(c *C) { tk.MustExec("insert into t2 values ('A');") tk.MustExec("set names utf8 collate utf8_general_ci;") tk.MustQuery("select * from t1, t2 where t1.a=t2.a and t1.a= 'a';").Check(testkit.Rows("a A")) + tk.MustQuery("select * from t1 where a='a' and a = 'A'").Check(testkit.Rows("a")) } func (s *testIntegrationSuite2) TestIssue17791(c *C) { diff --git a/expression/partition_pruner.go b/expression/partition_pruner.go index a9cb55cf69915..4ed5c06781164 100644 --- a/expression/partition_pruner.go +++ b/expression/partition_pruner.go @@ -19,6 +19,7 @@ import ( "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/chunk" + "github.com/pingcap/tidb/util/collate" "github.com/pingcap/tidb/util/disjointset" ) @@ -60,8 +61,8 @@ func (p *hashPartitionPruner) reduceColumnEQ() bool { father := p.unionSet.FindRoot(i) if p.constantMap[i] != nil { if p.constantMap[father] != nil { - // May has conflict here. - if !p.constantMap[father].Equal(p.ctx, p.constantMap[i]) { + // May has conflict here. We can choose collation from lhs or rhs, they should be equal. Exception is that `NULL` values. + if eq, err := p.constantMap[father].Value.Compare(p.ctx.GetSessionVars().StmtCtx, &p.constantMap[i].Value, collate.GetCollator(p.constantMap[i].GetType().Collate)); eq != 0 || err != nil { return true } } else { @@ -95,7 +96,8 @@ func (p *hashPartitionPruner) reduceConstantEQ() bool { if col != nil { id := p.getColID(col) if p.constantMap[id] != nil { - if p.constantMap[id].Equal(p.ctx, cond) { + // We can choose collation from lhs or rhs, they should be equal. Exception is that `NULL` values. + if eq, err := p.constantMap[id].Value.Compare(p.ctx.GetSessionVars().StmtCtx, &cond.Value, collate.GetCollator(cond.GetType().Collate)); eq == 0 && err == nil { continue } return true diff --git a/util/collate/collate.go b/util/collate/collate.go index 3cba9d6f572e5..e131134d37739 100644 --- a/util/collate/collate.go +++ b/util/collate/collate.go @@ -143,11 +143,13 @@ func GetCollator(collate string) Collator { if atomic.LoadInt32(&newCollationEnabled) == 1 { ctor, ok := newCollatorMap[collate] if !ok { - logutil.BgLogger().Warn( - "Unable to get collator by name, use binCollator instead.", - zap.String("name", collate), - zap.Stack("stack")) - return newCollatorMap["utf8mb4_bin"] + if collate != "" { + logutil.BgLogger().Warn( + "Unable to get collator by name, use binCollator instead.", + zap.String("name", collate), + zap.Stack("stack")) + } + return newCollatorMap[charset.CollationUTF8MB4] } return ctor }