Skip to content

Commit

Permalink
This is an automated cherry-pick of #53126
Browse files Browse the repository at this point in the history
Signed-off-by: ti-chi-bot <ti-community-prow-bot@tidb.io>
  • Loading branch information
YangKeao authored and ti-chi-bot committed May 11, 2024
1 parent a3c139d commit 84d9f72
Show file tree
Hide file tree
Showing 6 changed files with 2,994 additions and 8 deletions.
18 changes: 18 additions & 0 deletions expression/builtin_ilike.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ func (b *builtinIlikeSig) evalInt(row chunk.Row) (int64, bool, error) {
valStr = string(valStrBytes)
patternStr = string(patternStrBytes)

<<<<<<< HEAD:expression/builtin_ilike.go
memorization := func() {
if b.pattern == nil {
b.pattern = collate.ConvertAndGetBinCollation(b.collation).Pattern()
Expand All @@ -107,6 +108,23 @@ func (b *builtinIlikeSig) evalInt(row chunk.Row) (int64, bool, error) {
b.isMemorizedPattern = true
}
}
=======
var pattern collate.WildcardPattern
if b.args[1].ConstLevel() >= ConstOnlyInContext && b.args[2].ConstLevel() >= ConstOnlyInContext {
pattern, err = b.patternCache.getOrInitCache(ctx, func() (collate.WildcardPattern, error) {
ret := collate.ConvertAndGetBinCollator(b.collation).Pattern()
ret.Compile(patternStr, byte(escape))
return ret, nil
})

intest.AssertNoError(err)
if err != nil {
return 0, true, err
}
} else {
pattern = collate.ConvertAndGetBinCollator(b.collation).Pattern()
pattern.Compile(patternStr, byte(escape))
>>>>>>> dcd1fa9d967 (expression: fix the collation of functions with json arguments (#53126)):pkg/expression/builtin_ilike.go
}
// Only be executed once to achieve thread-safe
b.once.Do(memorization)
Expand Down
19 changes: 19 additions & 0 deletions expression/builtin_ilike_vec.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,24 @@ func (b *builtinIlikeSig) tryToMemorize(param *funcParam, escape int64) {
return
}

<<<<<<< HEAD:expression/builtin_ilike_vec.go
memorization := func() {
if b.pattern == nil {
b.pattern = collate.ConvertAndGetBinCollation(b.collation).Pattern()
b.pattern.Compile(param.getStringVal(0), byte(escape))
b.isMemorizedPattern = true
}
=======
pattern, err := b.patternCache.getOrInitCache(ctx, func() (collate.WildcardPattern, error) {
pattern := collate.ConvertAndGetBinCollator(b.collation).Pattern()
pattern.Compile(param.getStringVal(0), byte(escape))
return pattern, nil
})

intest.AssertNoError(err)
if err != nil {
return nil, false
>>>>>>> dcd1fa9d967 (expression: fix the collation of functions with json arguments (#53126)):pkg/expression/builtin_ilike_vec.go
}

// Only be executed once to achieve thread-safe
Expand Down Expand Up @@ -196,10 +208,17 @@ func (b *builtinIlikeSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) e
b.lowerExpr(params[0], rowNum)
escape = b.lowerPattern(params[1], rowNum, escape)

<<<<<<< HEAD:expression/builtin_ilike_vec.go
b.tryToMemorize(params[1], escape)
if !b.isMemorizedPattern {
b.pattern = collate.ConvertAndGetBinCollation(b.collation).Pattern()
return b.ilikeWithoutMemorization(params, rowNum, escape, result)
=======
pattern, ok := b.tryToVecMemorize(ctx, params[1], escape)
if !ok {
pattern = collate.ConvertAndGetBinCollator(b.collation).Pattern()
return b.ilikeWithoutMemorization(pattern, params, rowNum, escape, result)
>>>>>>> dcd1fa9d967 (expression: fix the collation of functions with json arguments (#53126)):pkg/expression/builtin_ilike_vec.go
}

return b.ilikeWithMemorization(params[0], rowNum, result)
Expand Down
40 changes: 39 additions & 1 deletion expression/collation.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,45 @@ func CheckAndDeriveCollationFromExprs(ctx sessionctx.Context, funcName string, e
return nil, illegalMixCollationErr(funcName, args)
}

return ec, nil
return fixStringTypeForMaxLength(funcName, args, ec), nil
}

// fixStringTypeForMaxLength changes the type of string from `VARCHAR` to `MEDIUM BLOB` or `LONG BLOB` according to the max length of
// the argument. However, as TiDB doesn't have `MaxLength` for `FieldType`, this function handles the logic manually for different types. Now it only
// handles the `JSON` type, because in MySQL, `JSON` type has a big max length and will lead to `LONG BLOB` in many situations.
// To learn more about this case, read the discussion under https://github.com/pingcap/tidb/issues/52833
//
// TODO: also consider types other than `JSON`. And also think about when it'll become `MEDIUM BLOB`. This function only handles the collation, but
// not change the type and binary flag.
// TODO: some function will generate big values, like `repeat` and `space`. They should be handled according to the argument if it's a constant.
func fixStringTypeForMaxLength(funcName string, args []Expression, ec *ExprCollation) *ExprCollation {
// Be careful that the `args` is not all arguments of the `funcName`. You should check `deriveCollation` function to see which arguments are passed
// to the `CheckAndDeriveCollationFromExprs` function, and then passed here.
shouldChangeToBin := false

switch funcName {
case ast.Reverse, ast.Lower, ast.Upper, ast.SubstringIndex, ast.Trim, ast.Quote, ast.InsertFunc, ast.Substr, ast.Repeat, ast.Replace:
shouldChangeToBin = args[0].GetType().EvalType() == types.ETJson
case ast.Concat, ast.ConcatWS, ast.Elt, ast.MakeSet:
for _, arg := range args {
if arg.GetType().EvalType() == types.ETJson {
shouldChangeToBin = true
break
}
}
case ast.ExportSet:
if len(args) >= 2 {
shouldChangeToBin = args[0].GetType().EvalType() == types.ETJson || args[1].GetType().EvalType() == types.ETJson
}
if len(args) >= 3 {
shouldChangeToBin = shouldChangeToBin || args[2].GetType().EvalType() == types.ETJson
}
}

if shouldChangeToBin {
ec.Collation = collate.ConvertAndGetBinCollation(ec.Collation)
}
return ec
}

func safeConvert(ctx sessionctx.Context, ec *ExprCollation, args ...Expression) bool {
Expand Down
Loading

0 comments on commit 84d9f72

Please sign in to comment.