github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/plan/function/operator/coalesce_test.go (about) 1 // Copyright 2022 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package operator 16 17 import ( 18 "fmt" 19 "testing" 20 21 "github.com/matrixorigin/matrixone/pkg/container/types" 22 "github.com/matrixorigin/matrixone/pkg/container/vector" 23 "github.com/matrixorigin/matrixone/pkg/testutil" 24 "github.com/stretchr/testify/require" 25 ) 26 27 func TestCoalesceGeneral(t *testing.T) { 28 testCases := []arg{ 29 { 30 info: "coalesce(null, 1)", proc: testutil.NewProc(), 31 vs: []*vector.Vector{ 32 testutil.MakeScalarNull(types.T_any, 1), 33 testutil.MakeScalarInt64(1, 1), 34 }, 35 match: true, 36 err: false, 37 expect: testutil.MakeScalarInt64(1, 1), 38 }, 39 40 { 41 info: "coalesce(null, 1, null, 3)", proc: testutil.NewProc(), 42 vs: []*vector.Vector{ 43 testutil.MakeScalarNull(types.T_any, 1), 44 testutil.MakeScalarInt64(1, 1), 45 testutil.MakeScalarNull(types.T_any, 1), 46 testutil.MakeScalarInt64(1, 3), 47 }, 48 match: true, 49 err: false, 50 expect: testutil.MakeScalarInt64(1, 1), 51 }, 52 53 { 54 info: "coalesce(a, 1, null, 3)", proc: testutil.NewProc(), 55 vs: []*vector.Vector{ 56 testutil.MakeInt64Vector([]int64{1, 0, 3, 0}, []uint64{1, 3}), 57 testutil.MakeScalarInt64(1, 1), 58 testutil.MakeScalarNull(types.T_any, 1), 59 testutil.MakeScalarInt64(1, 3), 60 }, 61 match: true, 62 err: false, 63 expect: testutil.MakeInt64Vector([]int64{1, 1, 3, 1}, nil), 64 }, 65 66 { 67 info: "coalesce(a, null, b)", proc: testutil.NewProc(), 68 vs: []*vector.Vector{ 69 testutil.MakeInt64Vector([]int64{1, 0, 3, 0}, []uint64{1, 3}), 70 testutil.MakeScalarNull(types.T_any, 1), 71 testutil.MakeInt64Vector([]int64{1, 11, 3, 0}, []uint64{3}), 72 }, 73 match: true, 74 err: false, 75 expect: testutil.MakeInt64Vector([]int64{1, 11, 3, 0}, []uint64{3}), 76 }, 77 78 { 79 info: "coalesce(a, null, 33)", proc: testutil.NewProc(), 80 vs: []*vector.Vector{ 81 testutil.MakeInt64Vector([]int64{1, 0, 3, 0}, []uint64{1, 3}), 82 testutil.MakeScalarNull(types.T_any, 1), 83 testutil.MakeScalarInt64(33, 4), 84 }, 85 match: true, 86 err: false, 87 expect: testutil.MakeInt64Vector([]int64{1, 33, 3, 33}, nil), 88 }, 89 } 90 91 for i, tc := range testCases { 92 t.Run(tc.info, func(t *testing.T) { 93 { 94 inputTypes := make([]types.T, len(tc.vs)) 95 for i := range inputTypes { 96 inputTypes[i] = tc.vs[i].Typ.Oid 97 } 98 b := CoalesceTypeCheckFn(inputTypes, nil, types.T_int64) 99 if !tc.match { 100 require.False(t, b, fmt.Sprintf("case '%s' shouldn't meet the function's requirement but it meets.", tc.info)) 101 return 102 } 103 require.True(t, b) 104 } 105 106 got, ergot := coalesceGeneral[int64](tc.vs, tc.proc, types.Type{Oid: types.T_int64}) 107 if tc.err { 108 require.Errorf(t, ergot, fmt.Sprintf("case '%d' expected error, but no error happens", i)) 109 } else { 110 require.NoError(t, ergot) 111 require.True(t, testutil.CompareVectors(tc.expect, got), "got vector is different with expected") 112 } 113 }) 114 } 115 } 116 117 func TestCoalesceString(t *testing.T) { 118 testCases := []arg{ 119 { 120 info: "coalesce(null, 'a', null, 'b')", proc: testutil.NewProc(), 121 vs: []*vector.Vector{ 122 testutil.MakeScalarNull(types.T_any, 1), 123 testutil.MakeScalarVarchar("a", 1), 124 testutil.MakeScalarNull(types.T_any, 1), 125 testutil.MakeScalarVarchar("b", 1), 126 }, 127 match: true, 128 err: false, 129 expect: testutil.MakeScalarVarchar("a", 1), 130 }, 131 132 { 133 info: "coalesce(a, 'a')", proc: testutil.NewProc(), 134 vs: []*vector.Vector{ 135 testutil.MakeVarcharVector([]string{"x", "y", "z"}, nil), 136 testutil.MakeScalarVarchar("a", 1), 137 }, 138 match: true, 139 err: false, 140 expect: testutil.MakeVarcharVector([]string{"x", "y", "z"}, nil), 141 }, 142 143 { 144 info: "coalesce(a, 'a', null, 'b')", proc: testutil.NewProc(), 145 vs: []*vector.Vector{ 146 testutil.MakeVarcharVector([]string{"kk", "", "ss", ""}, []uint64{1, 3}), 147 testutil.MakeScalarVarchar("a", 1), 148 testutil.MakeScalarNull(types.T_any, 1), 149 testutil.MakeScalarVarchar("b", 1), 150 }, 151 match: true, 152 err: false, 153 expect: testutil.MakeVarcharVector([]string{"kk", "a", "ss", "a"}, nil), 154 }, 155 156 { 157 info: "coalesce(a, null, 'b')", proc: testutil.NewProc(), 158 vs: []*vector.Vector{ 159 testutil.MakeVarcharVector([]string{"kk", "", "ss", ""}, []uint64{1, 3}), 160 testutil.MakeScalarNull(types.T_any, 1), 161 testutil.MakeScalarVarchar("b", 1), 162 }, 163 match: true, 164 err: false, 165 expect: testutil.MakeVarcharVector([]string{"kk", "b", "ss", "b"}, nil), 166 }, 167 168 { 169 info: "coalesce(a, null, b)", proc: testutil.NewProc(), 170 vs: []*vector.Vector{ 171 testutil.MakeVarcharVector([]string{"a1", "", "a2", ""}, []uint64{1, 3}), 172 testutil.MakeScalarNull(types.T_any, 1), 173 testutil.MakeVarcharVector([]string{"b1", "b2", "", ""}, []uint64{2, 3}), 174 }, 175 match: true, 176 err: false, 177 expect: testutil.MakeVarcharVector([]string{"a1", "b2", "a2", ""}, []uint64{3}), 178 }, 179 } 180 181 for i, tc := range testCases { 182 t.Run(tc.info, func(t *testing.T) { 183 { 184 inputTypes := make([]types.T, len(tc.vs)) 185 for i := range inputTypes { 186 inputTypes[i] = tc.vs[i].Typ.Oid 187 } 188 b := CoalesceTypeCheckFn(inputTypes, nil, types.T_varchar) 189 if !tc.match { 190 require.False(t, b, fmt.Sprintf("case '%s' shouldn't meet the function's requirement but it meets.", tc.info)) 191 return 192 } 193 require.True(t, b) 194 } 195 196 got, ergot := coalesceString(tc.vs, tc.proc, types.Type{Oid: types.T_varchar, Width: types.MaxVarcharLen}) 197 if tc.err { 198 require.Errorf(t, ergot, fmt.Sprintf("case '%d' expected error, but no error happens", i)) 199 } else { 200 require.NoError(t, ergot) 201 require.True(t, testutil.CompareVectors(tc.expect, got), "got vector is different with expected") 202 } 203 }) 204 } 205 }