Skip to content

Commit

Permalink
expression: fix reverse function on bit type column (#50146) (#51131
Browse files Browse the repository at this point in the history
)

close #49566, close #50850, close #50855
  • Loading branch information
ti-chi-bot authored Feb 19, 2024
1 parent ceffebe commit 6d13674
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 1 deletion.
4 changes: 4 additions & 0 deletions expression/builtin_cast.go
Original file line number Diff line number Diff line change
Expand Up @@ -2254,6 +2254,10 @@ func WrapWithCastAsString(ctx sessionctx.Context, expr Expression) Expression {
charset, collate := expr.CharsetAndCollation()
tp.SetCharset(charset)
tp.SetCollate(collate)
} else if exprTp.GetType() == mysql.TypeBit {
// Implicitly casting BIT to string will make it a binary
tp.SetCharset(charset.CharsetBin)
tp.SetCollate(charset.CollationBin)
} else {
charset, collate := ctx.GetSessionVars().GetCharsetInfo()
tp.SetCharset(charset)
Expand Down
2 changes: 1 addition & 1 deletion expression/builtin_string.go
Original file line number Diff line number Diff line change
Expand Up @@ -768,7 +768,7 @@ func (c *reverseFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
bf.tp.SetFlen(args[0].GetType().GetFlen())
addBinFlag(bf.tp)
var sig builtinFunc
if types.IsBinaryStr(argTp) {
if types.IsBinaryStr(argTp) || types.IsTypeBit(argTp) {
sig = &builtinReverseSig{bf}
sig.setPbCode(tipb.ScalarFuncSig_Reverse)
} else {
Expand Down
6 changes: 6 additions & 0 deletions expression/collation.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ func deriveCoercibilityForColumn(c *Column) Coercibility {
// For specified type null, it should return CoercibilityIgnorable, which means it got the lowest priority in DeriveCollationFromExprs.
if c.RetType.GetType() == mysql.TypeNull {
return CoercibilityIgnorable
} else if types.IsTypeBit(c.RetType) {
return CoercibilityImplicit
}

switch c.RetType.EvalType() {
Expand Down Expand Up @@ -374,6 +376,8 @@ func inferCollation(exprs ...Expression) *ExprCollation {
dstCharset, dstCollation := exprs[0].GetType().GetCharset(), exprs[0].GetType().GetCollate()
if exprs[0].GetType().EvalType() == types.ETJson {
dstCharset, dstCollation = charset.CharsetUTF8MB4, charset.CollationUTF8MB4
} else if types.IsTypeBit(exprs[0].GetType()) {
dstCharset, dstCollation = charset.CharsetBin, charset.CollationBin
}
unknownCS := false

Expand All @@ -384,6 +388,8 @@ func inferCollation(exprs ...Expression) *ExprCollation {
// see details https://github.com/pingcap/tidb/issues/31320#issuecomment-1010599311
if arg.GetType().EvalType() == types.ETJson {
argCharset, argCollation = charset.CharsetUTF8MB4, charset.CollationUTF8MB4
} else if types.IsTypeBit(arg.GetType()) {
argCharset, argCollation = charset.CharsetBin, charset.CollationBin
}
// If one of the arguments is binary charset, we allow it can be used with other charsets.
// If they have the same coercibility, let the binary charset one to be the winner because binary has more precedence.
Expand Down
43 changes: 43 additions & 0 deletions expression/integration_test/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7982,3 +7982,46 @@ func TestIssue49526(t *testing.T) {
}
tk.MustQuery("select null as a union all select 'a' as a;").Sort().Check(testkit.Rows("<nil>", "a"))
}

func TestIssue49566(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)

tk.MustExec("use test")
tk.MustExec("drop table if exists t;")
tk.MustExec("create table t (col bit(37) NOT NULL);")
tk.MustExec("insert into t (col) values(x'05d3a46d88'), (x'04dba3570c'), (x'0ed284dfee'), (x'12657141bf');")
tk.MustQuery("select hex(col), hex(reverse(col)) from t order by reverse(col);").Check(
testkit.Rows("4DBA3570C 0C57A3DB04", "5D3A46D88 886DA4D305", "12657141BF BF41716512", "ED284DFEE EEDF84D20E"))
tk.MustExec("drop table if exists t;")
}

func TestIssue50855(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)

tk.MustExec("use test")
tk.MustExec("drop table if exists t2;")
tk.MustExec("create table t2 (col bit(45) NOT NULL);")
tk.MustExec("insert into t2 (col) values(x'09a1441d083c');")
tk.MustQuery("select hex(r) from (select reverse(col) as r from t2 group by reverse(col)) as t;").Check(testkit.Rows("3C081D44A109"))
tk.MustQuery("select hex(r) from (select distinct reverse(col) as r from t2) as t;").Check(testkit.Rows("3C081D44A109"))
tk.MustExec("drop table if exists t2;")
}

func TestIssue50850(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)

tk.MustExec("use test")
tk.MustExec("drop table if exists t3;")
tk.MustExec("create table t3 (col1 double not null, col2 bit(8) NOT NULL);")
tk.MustExec("insert into t3 (col1, col2) values (2306.9705216860984, x'31'), (6779.239615471537, x'65'), (7601.530447792593, x'd5'), " +
"(7058.842877388801, x'a5'), (615.6011553350702, x'34'), (5613.036187642952, x'01'), (7047.649466854864, x'a6'), (8632.659024782468, x'5d'), " +
"(9546.629394674586, x'ff'), (2972.7118048537704, x'b1');")
tk.MustQuery("select hex(r) as r0 from (select ELT(2, col1, col2) as r from t3 group by ELT(2, col1, col2)) as t order by r0;").Check(
testkit.Rows("01", "31", "34", "5D", "65", "A5", "A6", "B1", "D5", "FF"))
tk.MustQuery("select hex(r) as r0 from (select distinct ELT(2, col1, col2) as r from t3) as t order by r0;").Check(
testkit.Rows("01", "31", "34", "5D", "65", "A5", "A6", "B1", "D5", "FF"))
tk.MustExec("drop table if exists t3;")
}

0 comments on commit 6d13674

Please sign in to comment.