Skip to content

Commit

Permalink
expression: fix 2 unstable test cases (#35371)
Browse files Browse the repository at this point in the history
close #29283
  • Loading branch information
bb7133 committed Jun 16, 2022
1 parent 108a601 commit bae61dc
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 133 deletions.
102 changes: 102 additions & 0 deletions expression/builtin_string_serial_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Copyright 2021 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package expression

import (
"testing"
"unicode/utf8"

"github.com/pingcap/tidb/parser/ast"
"github.com/pingcap/tidb/types"
"github.com/pingcap/tidb/util/chunk"
"github.com/pingcap/tidb/util/collate"
"github.com/stretchr/testify/require"
)

func TestCIWeightString(t *testing.T) {
ctx := createContext(t)
collate.SetNewCollationEnabledForTest(true)
defer collate.SetNewCollationEnabledForTest(false)

type weightStringTest struct {
str string
padding string
length int
expect interface{}
}

checkResult := func(collation string, tests []weightStringTest) {
fc := funcs[ast.WeightString]
for _, test := range tests {
str := types.NewCollationStringDatum(test.str, collation, utf8.RuneCountInString(test.str))
var f builtinFunc
var err error
if test.padding == "NONE" {
f, err = fc.getFunction(ctx, datumsToConstants([]types.Datum{str}))
} else {
padding := types.NewDatum(test.padding)
length := types.NewDatum(test.length)
f, err = fc.getFunction(ctx, datumsToConstants([]types.Datum{str, padding, length}))
}
require.NoError(t, err)
result, err := evalBuiltinFunc(f, chunk.Row{})
require.NoError(t, err)
if result.IsNull() {
require.Nil(t, test.expect)
continue
}
res, err := result.ToString()
require.NoError(t, err)
require.Equal(t, test.expect, res)
}
}

generalTests := []weightStringTest{
{"aAÁàãăâ", "NONE", 0, "\x00A\x00A\x00A\x00A\x00A\x00A\x00A"},
{"中", "NONE", 0, "\x4E\x2D"},
{"a", "CHAR", 5, "\x00A"},
{"a ", "CHAR", 5, "\x00A"},
{"中", "CHAR", 5, "\x4E\x2D"},
{"中 ", "CHAR", 5, "\x4E\x2D"},
{"a", "BINARY", 1, "a"},
{"ab", "BINARY", 1, "a"},
{"a", "BINARY", 5, "a\x00\x00\x00\x00"},
{"a ", "BINARY", 5, "a \x00\x00\x00"},
{"中", "BINARY", 1, "\xe4"},
{"中", "BINARY", 2, "\xe4\xb8"},
{"中", "BINARY", 3, "中"},
{"中", "BINARY", 5, "中\x00\x00"},
}

unicodeTests := []weightStringTest{
{"aAÁàãăâ", "NONE", 0, "\x0e3\x0e3\x0e3\x0e3\x0e3\x0e3\x0e3"},
{"中", "NONE", 0, "\xfb\x40\xce\x2d"},
{"a", "CHAR", 5, "\x0e3"},
{"a ", "CHAR", 5, "\x0e3"},
{"中", "CHAR", 5, "\xfb\x40\xce\x2d"},
{"中 ", "CHAR", 5, "\xfb\x40\xce\x2d"},
{"a", "BINARY", 1, "a"},
{"ab", "BINARY", 1, "a"},
{"a", "BINARY", 5, "a\x00\x00\x00\x00"},
{"a ", "BINARY", 5, "a \x00\x00\x00"},
{"中", "BINARY", 1, "\xe4"},
{"中", "BINARY", 2, "\xe4\xb8"},
{"中", "BINARY", 3, "中"},
{"中", "BINARY", 5, "中\x00\x00"},
}

checkResult("utf8mb4_general_ci", generalTests)
checkResult("utf8mb4_unicode_ci", unicodeTests)
}
79 changes: 0 additions & 79 deletions expression/builtin_string_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"strings"
"testing"
"time"
"unicode/utf8"

"github.com/pingcap/errors"
"github.com/pingcap/tidb/errno"
Expand All @@ -33,7 +32,6 @@ import (
"github.com/pingcap/tidb/testkit/trequire"
"github.com/pingcap/tidb/types"
"github.com/pingcap/tidb/util/chunk"
"github.com/pingcap/tidb/util/collate"
"github.com/pingcap/tidb/util/mock"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -2646,83 +2644,6 @@ func TestWeightString(t *testing.T) {
}
}

func TestCIWeightString(t *testing.T) {
t.Parallel()
ctx := createContext(t)
collate.SetNewCollationEnabledForTest(true)
defer collate.SetNewCollationEnabledForTest(false)

type weightStringTest struct {
str string
padding string
length int
expect interface{}
}

checkResult := func(collation string, tests []weightStringTest) {
fc := funcs[ast.WeightString]
for _, test := range tests {
str := types.NewCollationStringDatum(test.str, collation, utf8.RuneCountInString(test.str))
var f builtinFunc
var err error
if test.padding == "NONE" {
f, err = fc.getFunction(ctx, datumsToConstants([]types.Datum{str}))
} else {
padding := types.NewDatum(test.padding)
length := types.NewDatum(test.length)
f, err = fc.getFunction(ctx, datumsToConstants([]types.Datum{str, padding, length}))
}
require.NoError(t, err)
result, err := evalBuiltinFunc(f, chunk.Row{})
require.NoError(t, err)
if result.IsNull() {
require.Nil(t, test.expect)
continue
}
res, err := result.ToString()
require.NoError(t, err)
require.Equal(t, test.expect, res)
}
}

generalTests := []weightStringTest{
{"aAÁàãăâ", "NONE", 0, "\x00A\x00A\x00A\x00A\x00A\x00A\x00A"},
{"中", "NONE", 0, "\x4E\x2D"},
{"a", "CHAR", 5, "\x00A"},
{"a ", "CHAR", 5, "\x00A"},
{"中", "CHAR", 5, "\x4E\x2D"},
{"中 ", "CHAR", 5, "\x4E\x2D"},
{"a", "BINARY", 1, "a"},
{"ab", "BINARY", 1, "a"},
{"a", "BINARY", 5, "a\x00\x00\x00\x00"},
{"a ", "BINARY", 5, "a \x00\x00\x00"},
{"中", "BINARY", 1, "\xe4"},
{"中", "BINARY", 2, "\xe4\xb8"},
{"中", "BINARY", 3, "中"},
{"中", "BINARY", 5, "中\x00\x00"},
}

unicodeTests := []weightStringTest{
{"aAÁàãăâ", "NONE", 0, "\x0e3\x0e3\x0e3\x0e3\x0e3\x0e3\x0e3"},
{"中", "NONE", 0, "\xfb\x40\xce\x2d"},
{"a", "CHAR", 5, "\x0e3"},
{"a ", "CHAR", 5, "\x0e3"},
{"中", "CHAR", 5, "\xfb\x40\xce\x2d"},
{"中 ", "CHAR", 5, "\xfb\x40\xce\x2d"},
{"a", "BINARY", 1, "a"},
{"ab", "BINARY", 1, "a"},
{"a", "BINARY", 5, "a\x00\x00\x00\x00"},
{"a ", "BINARY", 5, "a \x00\x00\x00"},
{"中", "BINARY", 1, "\xe4"},
{"中", "BINARY", 2, "\xe4\xb8"},
{"中", "BINARY", 3, "中"},
{"中", "BINARY", 5, "中\x00\x00"},
}

checkResult("utf8mb4_general_ci", generalTests)
checkResult("utf8mb4_unicode_ci", unicodeTests)
}

func TestTranslate(t *testing.T) {
t.Parallel()
ctx := createContext(t)
Expand Down
76 changes: 76 additions & 0 deletions expression/collation_serial_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Copyright 2022 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package expression

import (
"testing"

"github.com/pingcap/tidb/parser/mysql"
"github.com/pingcap/tidb/types"
"github.com/pingcap/tidb/util/chunk"
"github.com/pingcap/tidb/util/collate"
"github.com/pingcap/tidb/util/mock"
"github.com/stretchr/testify/require"
)

func TestCompareString(t *testing.T) {
collate.SetNewCollationEnabledForTest(true)
defer collate.SetNewCollationEnabledForTest(false)

require.Equal(t, 0, types.CompareString("a", "A", "utf8_general_ci"))
require.Equal(t, 0, types.CompareString("À", "A", "utf8_general_ci"))
require.Equal(t, 0, types.CompareString("😜", "😃", "utf8_general_ci"))
require.Equal(t, 0, types.CompareString("a ", "a ", "utf8_general_ci"))
require.Equal(t, 0, types.CompareString("ß", "s", "utf8_general_ci"))
require.NotEqual(t, 0, types.CompareString("ß", "ss", "utf8_general_ci"))

require.Equal(t, 0, types.CompareString("a", "A", "utf8_unicode_ci"))
require.Equal(t, 0, types.CompareString("À", "A", "utf8_unicode_ci"))
require.Equal(t, 0, types.CompareString("😜", "😃", "utf8_unicode_ci"))
require.Equal(t, 0, types.CompareString("a ", "a ", "utf8_unicode_ci"))
require.NotEqual(t, 0, types.CompareString("ß", "s", "utf8_unicode_ci"))
require.Equal(t, 0, types.CompareString("ß", "ss", "utf8_unicode_ci"))

require.NotEqual(t, 0, types.CompareString("a", "A", "binary"))
require.NotEqual(t, 0, types.CompareString("À", "A", "binary"))
require.NotEqual(t, 0, types.CompareString("😜", "😃", "binary"))
require.NotEqual(t, 0, types.CompareString("a ", "a ", "binary"))

ctx := mock.NewContext()
ft := types.NewFieldType(mysql.TypeVarString)
col1 := &Column{
RetType: ft,
Index: 0,
}
col2 := &Column{
RetType: ft,
Index: 1,
}
chk := chunk.NewChunkWithCapacity([]*types.FieldType{ft, ft}, 4)
chk.Column(0).AppendString("a")
chk.Column(1).AppendString("A")
chk.Column(0).AppendString("À")
chk.Column(1).AppendString("A")
chk.Column(0).AppendString("😜")
chk.Column(1).AppendString("😃")
chk.Column(0).AppendString("a ")
chk.Column(1).AppendString("a ")
for i := 0; i < 4; i++ {
v, isNull, err := CompareStringWithCollationInfo(ctx, col1, col2, chk.GetRow(0), chk.GetRow(0), "utf8_general_ci")
require.NoError(t, err)
require.False(t, isNull)
require.Equal(t, int64(0), v)
}
}
54 changes: 0 additions & 54 deletions expression/collation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,63 +23,9 @@ import (
"github.com/pingcap/tidb/parser/charset"
"github.com/pingcap/tidb/parser/mysql"
"github.com/pingcap/tidb/types"
"github.com/pingcap/tidb/util/chunk"
"github.com/pingcap/tidb/util/collate"
"github.com/pingcap/tidb/util/mock"
)

func TestCompareString(t *testing.T) {
t.Parallel()

collate.SetNewCollationEnabledForTest(true)
defer collate.SetNewCollationEnabledForTest(false)

require.Equal(t, 0, types.CompareString("a", "A", "utf8_general_ci"))
require.Equal(t, 0, types.CompareString("À", "A", "utf8_general_ci"))
require.Equal(t, 0, types.CompareString("😜", "😃", "utf8_general_ci"))
require.Equal(t, 0, types.CompareString("a ", "a ", "utf8_general_ci"))
require.Equal(t, 0, types.CompareString("ß", "s", "utf8_general_ci"))
require.NotEqual(t, 0, types.CompareString("ß", "ss", "utf8_general_ci"))

require.Equal(t, 0, types.CompareString("a", "A", "utf8_unicode_ci"))
require.Equal(t, 0, types.CompareString("À", "A", "utf8_unicode_ci"))
require.Equal(t, 0, types.CompareString("😜", "😃", "utf8_unicode_ci"))
require.Equal(t, 0, types.CompareString("a ", "a ", "utf8_unicode_ci"))
require.NotEqual(t, 0, types.CompareString("ß", "s", "utf8_unicode_ci"))
require.Equal(t, 0, types.CompareString("ß", "ss", "utf8_unicode_ci"))

require.NotEqual(t, 0, types.CompareString("a", "A", "binary"))
require.NotEqual(t, 0, types.CompareString("À", "A", "binary"))
require.NotEqual(t, 0, types.CompareString("😜", "😃", "binary"))
require.NotEqual(t, 0, types.CompareString("a ", "a ", "binary"))

ctx := mock.NewContext()
ft := types.NewFieldType(mysql.TypeVarString)
col1 := &Column{
RetType: ft,
Index: 0,
}
col2 := &Column{
RetType: ft,
Index: 1,
}
chk := chunk.NewChunkWithCapacity([]*types.FieldType{ft, ft}, 4)
chk.Column(0).AppendString("a")
chk.Column(1).AppendString("A")
chk.Column(0).AppendString("À")
chk.Column(1).AppendString("A")
chk.Column(0).AppendString("😜")
chk.Column(1).AppendString("😃")
chk.Column(0).AppendString("a ")
chk.Column(1).AppendString("a ")
for i := 0; i < 4; i++ {
v, isNull, err := CompareStringWithCollationInfo(ctx, col1, col2, chk.GetRow(0), chk.GetRow(0), "utf8_general_ci")
require.NoError(t, err)
require.False(t, isNull)
require.Equal(t, int64(0), v)
}
}

func newExpression(coercibility Coercibility, repertoire Repertoire, chs, coll string) Expression {
constant := &Constant{RetType: &types.FieldType{Tp: mysql.TypeString, Charset: chs, Collate: coll}}
constant.SetCoercibility(coercibility)
Expand Down

0 comments on commit bae61dc

Please sign in to comment.