Skip to content

Commit dcff133

Browse files
lcwangchaoti-chi-bot
authored andcommitted
This is an automated cherry-pick of pingcap#57484
Signed-off-by: ti-chi-bot <[email protected]>
1 parent 7365a7b commit dcff133

File tree

9 files changed

+2744
-2
lines changed

9 files changed

+2744
-2
lines changed

expression/builtin_cast.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,10 +284,27 @@ func (c *castAsStringFunctionClass) getFunction(ctx sessionctx.Context, args []E
284284
if err != nil {
285285
return nil, err
286286
}
287+
<<<<<<< HEAD:expression/builtin_cast.go
287288
if args[0].GetType().Hybrid() {
288289
sig = &builtinCastStringAsStringSig{bf}
289290
sig.setPbCode(tipb.ScalarFuncSig_CastStringAsString)
290291
return sig, nil
292+
=======
293+
if ft := args[0].GetType(ctx.GetEvalCtx()); ft.Hybrid() {
294+
castBitAsUnBinary := ft.GetType() == mysql.TypeBit && c.tp.GetCharset() != charset.CharsetBin
295+
if !castBitAsUnBinary {
296+
sig = &builtinCastStringAsStringSig{bf}
297+
sig.setPbCode(tipb.ScalarFuncSig_CastStringAsString)
298+
return sig, nil
299+
}
300+
// for type BIT, it maybe an invalid value for the specified charset, we need to convert it to binary first,
301+
// and then convert it to the specified charset with `HandleBinaryLiteral` in the following code.
302+
tp := types.NewFieldType(mysql.TypeString)
303+
tp.SetCharset(charset.CharsetBin)
304+
tp.SetCollate(charset.CollationBin)
305+
tp.AddFlag(mysql.BinaryFlag)
306+
args[0] = BuildCastFunction(ctx, args[0], tp)
307+
>>>>>>> 38104f4f328 (expression: fix tikv crash when `bool like cast(bit as char)` (#57484)):pkg/expression/builtin_cast.go
291308
}
292309
argTp := args[0].GetType().EvalType()
293310
switch argTp {

expression/builtin_convert_charset.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ type builtinInternalFromBinarySig struct {
166166
func (b *builtinInternalFromBinarySig) Clone() builtinFunc {
167167
newSig := &builtinInternalFromBinarySig{}
168168
newSig.cloneFrom(&b.baseBuiltinFunc)
169+
newSig.cannotConvertStringAsWarning = b.cannotConvertStringAsWarning
169170
return newSig
170171
}
171172

expression/expr_to_pb_test.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1472,7 +1472,9 @@ func TestExprPushDownToTiKV(t *testing.T) {
14721472
require.Len(t, pushed, 0)
14731473
require.Len(t, remained, len(exprs))
14741474

1475-
// Test Conv function
1475+
// Test Conv function, `conv` function for a BIT column should not be pushed down for its special behavior which
1476+
// is only handled in TiDB currently.
1477+
// see issue: https://github.com/pingcap/tidb/issues/51877
14761478
exprs = exprs[:0]
14771479
function, err = NewFunction(mock.NewContext(), ast.Conv, types.NewFieldType(mysql.TypeString), stringColumn, intColumn, intColumn)
14781480
require.NoError(t, err)
@@ -1481,7 +1483,11 @@ func TestExprPushDownToTiKV(t *testing.T) {
14811483
require.Len(t, pushed, len(exprs))
14821484
require.Len(t, remained, 0)
14831485
exprs = exprs[:0]
1484-
castByteAsStringFunc, err := NewFunction(mock.NewContext(), ast.Cast, types.NewFieldType(mysql.TypeString), byteColumn)
1486+
// when conv a column with type BIT, a cast function will be used to cast bit to a binary string
1487+
castTp := types.NewFieldType(mysql.TypeString)
1488+
castTp.SetCharset(charset.CharsetBin)
1489+
castTp.SetCollate(charset.CollationBin)
1490+
castByteAsStringFunc, err := NewFunction(mock.NewContext(), ast.Cast, castTp, byteColumn)
14851491
require.NoError(t, err)
14861492
function, err = NewFunction(mock.NewContext(), ast.Conv, types.NewFieldType(mysql.TypeString), castByteAsStringFunc, intColumn, intColumn)
14871493
require.NoError(t, err)

0 commit comments

Comments
 (0)