Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request]: strcmp function #18483

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
14 changes: 14 additions & 0 deletions pkg/sql/plan/function/func_binary.go
Original file line number Diff line number Diff line change
Expand Up @@ -2198,6 +2198,20 @@ func EndsWith(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc
return opBinaryBytesBytesToFixed[bool](ivecs, result, proc, length, bytes.HasSuffix, selectList)
}

func Strcmp(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int, _ *FunctionSelectList) (err error) {
return opBinaryStrStrToFixed[int8](ivecs, result, proc, length, strcmp, nil)
}

func strcmp(s1, s2 string) int8 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why use int8 instead of int32? the function signature said int32.

if s1 == s2 {
return 0
}
if s1 < s2 {
return -1
}
return 1
}

// https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html#function_sha2
func SHA2Func(args []*vector.Vector, result vector.FunctionResultWrapper, _ *process.Process, length int, selectList *FunctionSelectList) (err error) {
res := vector.MustFunctionResult[types.Varlena](result)
Expand Down
55 changes: 55 additions & 0 deletions pkg/sql/plan/function/func_binary_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2166,6 +2166,61 @@ func TestInstr(t *testing.T) {
}
}

// STRCMP
func initStrcmpTestCase() []tcTemp {
cases := []struct {
s1 string
s2 string
wants int8
}{
{"", "", 0},
{"", "a", -1},
{"a", "", 1},
{"0", "0", 0},
{"0", "1", -1},
{"0", "-1", 1},
{"ab", "abc", -1},
{"abcd", "abc", 1},
{"abce", "abcd", 1},
{"abce", "abcda", 1},
{"我们", "我", 1},
{"我们", "wo", 1},
{"我们", "woo", 1},
{"我们", "我们", 0},
{"我 们", "我们", -1},
{"-ae", "我", -1},
{":=符号只允许在函数中使用,即只能在声明局部变量的时候使用,而var没有这个限制", "a b cd ", -1},
{"符号只允许在函数中使用,即只能在声明局部变量的时候使用,而var没有这个限制", "a b cd ", 1},
{"符号只允许在函数中使用,即只能在声明局部变量的时候使用,而var没有这个限制", "符号只允许在函数中使用,即只能在声明局部变量的时候使用,而var没有这个限制", 0},
}

var testInputs = make([]tcTemp, 0, len(cases))
for _, c := range cases {
testInputs = append(testInputs, tcTemp{
info: "test strcmp ",
inputs: []FunctionTestInput{
// Create a input entry <str, str>
NewFunctionTestInput(types.T_varchar.ToType(), []string{c.s1}, []bool{}),
NewFunctionTestInput(types.T_varchar.ToType(), []string{c.s2}, []bool{}),
},
expect: NewFunctionTestResult(types.T_int8.ToType(), false, []int8{c.wants}, []bool{}),
})
}

return testInputs
}

func TestStrcmp(t *testing.T) {
testCases := initStrcmpTestCase()

proc := testutil.NewProcess()
for _, tc := range testCases {
fcTC := NewFunctionTestCase(proc, tc.inputs, tc.expect, Strcmp)
s, info := fcTC.Run()
require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info))
}
}

// Left
func initLeftTestCase() []tcTemp {
cases := []struct {
Expand Down
2 changes: 2 additions & 0 deletions pkg/sql/plan/function/function_id.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ const (
STARTSWITH
STDDEV_POP
STDDEV_SAMPLE
STRCMP
SUBSTR
SUM
SYSDATE
Expand Down Expand Up @@ -539,6 +540,7 @@ var functionIdRegister = map[string]int32{
"sin": SIN,
"sinh": SINH,
"space": SPACE,
"strcmp": STRCMP,
"tan": TAN,
"week": WEEK,
"weekday": WEEKDAY,
Expand Down
21 changes: 21 additions & 0 deletions pkg/sql/plan/function/list_builtIn.go
Original file line number Diff line number Diff line change
Expand Up @@ -1517,6 +1517,27 @@ var supportedStringBuiltIns = []FuncNew{
},
},

// function `strcmp`
{
functionId: STRCMP,
class: plan.Function_STRICT,
layout: STANDARD_FUNCTION,
checkFn: fixedTypeMatch,

Overloads: []overload{
{
overloadId: 0,
args: []types.T{types.T_varchar, types.T_varchar},
retType: func(parameters []types.Type) types.Type {
return types.T_int32.ToType()
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

int32 here.

newOp: func() executeLogicOfOverload {
return Strcmp
},
},
},
},

// function `prefix_eq`
{
functionId: PREFIX_EQ,
Expand Down
Loading