@@ -38,6 +38,7 @@ import (
38
38
"github.com/pingcap/tidb/pkg/sessionctx/stmtctx"
39
39
"github.com/pingcap/tidb/pkg/types"
40
40
"github.com/pingcap/tidb/pkg/util/chunk"
41
+ "github.com/pingcap/tidb/pkg/util/collate"
41
42
"github.com/pingcap/tipb/go-tipb"
42
43
)
43
44
@@ -288,7 +289,8 @@ func (c *castAsDecimalFunctionClass) getFunction(ctx BuildContext, args []Expres
288
289
type castAsStringFunctionClass struct {
289
290
baseFunctionClass
290
291
291
- tp * types.FieldType
292
+ tp * types.FieldType
293
+ isExplicitCharSet bool
292
294
}
293
295
294
296
func (c * castAsStringFunctionClass ) getFunction (ctx BuildContext , args []Expression ) (sig builtinFunc , err error ) {
@@ -299,6 +301,16 @@ func (c *castAsStringFunctionClass) getFunction(ctx BuildContext, args []Express
299
301
if err != nil {
300
302
return nil , err
301
303
}
304
+ if c .isExplicitCharSet {
305
+ bf .SetCharsetAndCollation (c .tp .GetCharset (), c .tp .GetCollate ())
306
+ bf .setCollator (collate .GetCollator (c .tp .GetCollate ()))
307
+ bf .SetCoercibility (CoercibilityExplicit )
308
+ if c .tp .GetCharset () == charset .CharsetASCII {
309
+ bf .SetRepertoire (ASCII )
310
+ } else {
311
+ bf .SetRepertoire (UNICODE )
312
+ }
313
+ }
302
314
if args [0 ].GetType (ctx .GetEvalCtx ()).Hybrid () {
303
315
sig = & builtinCastStringAsStringSig {bf }
304
316
sig .setPbCode (tipb .ScalarFuncSig_CastStringAsString )
@@ -2265,7 +2277,7 @@ func CanImplicitEvalReal(expr Expression) bool {
2265
2277
// BuildCastFunction4Union build a implicitly CAST ScalarFunction from the Union
2266
2278
// Expression.
2267
2279
func BuildCastFunction4Union (ctx BuildContext , expr Expression , tp * types.FieldType ) (res Expression ) {
2268
- res , err := BuildCastFunctionWithCheck (ctx , expr , tp , true )
2280
+ res , err := BuildCastFunctionWithCheck (ctx , expr , tp , true , false )
2269
2281
terror .Log (err )
2270
2282
return
2271
2283
}
@@ -2302,13 +2314,20 @@ func BuildCastCollationFunction(ctx BuildContext, expr Expression, ec *ExprColla
2302
2314
2303
2315
// BuildCastFunction builds a CAST ScalarFunction from the Expression.
2304
2316
func BuildCastFunction (ctx BuildContext , expr Expression , tp * types.FieldType ) (res Expression ) {
2305
- res , err := BuildCastFunctionWithCheck (ctx , expr , tp , false )
2317
+ res , err := BuildCastFunctionWithCheck (ctx , expr , tp , false , false )
2318
+ terror .Log (err )
2319
+ return
2320
+ }
2321
+
2322
+ // BuildCastFunctionExplicitCharset builds a CAST ScalarFunction from the Expression.
2323
+ func BuildCastFunctionExplicitCharset (ctx BuildContext , expr Expression , tp * types.FieldType ) (res Expression ) {
2324
+ res , err := BuildCastFunctionWithCheck (ctx , expr , tp , false , true )
2306
2325
terror .Log (err )
2307
2326
return
2308
2327
}
2309
2328
2310
2329
// BuildCastFunctionWithCheck builds a CAST ScalarFunction from the Expression and return error if any.
2311
- func BuildCastFunctionWithCheck (ctx BuildContext , expr Expression , tp * types.FieldType , inUnion bool ) (res Expression , err error ) {
2330
+ func BuildCastFunctionWithCheck (ctx BuildContext , expr Expression , tp * types.FieldType , inUnion bool , isExplicitCharSet bool ) (res Expression , err error ) {
2312
2331
argType := expr .GetType (ctx .GetEvalCtx ())
2313
2332
// If source argument's nullable, then target type should be nullable
2314
2333
if ! mysql .HasNotNullFlag (argType .GetFlag ()) {
@@ -2336,7 +2355,7 @@ func BuildCastFunctionWithCheck(ctx BuildContext, expr Expression, tp *types.Fie
2336
2355
case types .ETVectorFloat32 :
2337
2356
fc = & castAsVectorFloat32FunctionClass {baseFunctionClass {ast .Cast , 1 , 1 }, tp }
2338
2357
case types .ETString :
2339
- fc = & castAsStringFunctionClass {baseFunctionClass {ast .Cast , 1 , 1 }, tp }
2358
+ fc = & castAsStringFunctionClass {baseFunctionClass {ast .Cast , 1 , 1 }, tp , isExplicitCharSet }
2340
2359
if expr .GetType (ctx .GetEvalCtx ()).GetType () == mysql .TypeBit {
2341
2360
tp .SetFlen ((expr .GetType (ctx .GetEvalCtx ()).GetFlen () + 7 ) / 8 )
2342
2361
}
0 commit comments