github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/plan/function/operator/case_when_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/matrixorigin/matrixone/pkg/vm/process" 25 "github.com/stretchr/testify/require" 26 ) 27 28 type arg struct { 29 info string 30 proc *process.Process 31 vs []*vector.Vector 32 match bool // if false, the case shouldn't meet the function requirement 33 err bool 34 expect *vector.Vector 35 } 36 37 func TestCwFn1(t *testing.T) { 38 testCases := []arg{ 39 { 40 info: "when a = 1 then 1, when a = 2 then 2, else 3", proc: testutil.NewProc(), 41 vs: []*vector.Vector{ 42 testutil.MakeBoolVector([]bool{true, true, false, false, false}), // a = 1 43 testutil.MakeScalarInt64(1, 5), // 1 44 testutil.MakeBoolVector([]bool{false, false, false, true, false}), // a = 2 45 testutil.MakeScalarInt64(2, 5), // 2 46 testutil.MakeScalarInt64(3, 5), // 3 47 }, 48 match: true, 49 err: false, 50 expect: testutil.MakeInt64Vector([]int64{1, 1, 3, 2, 3}, nil), 51 }, 52 53 { 54 info: "when a = 1 then 1, when a = 2 then 2, else null", proc: testutil.NewProc(), 55 vs: []*vector.Vector{ 56 testutil.MakeBoolVector([]bool{false, false, false, false}), // a = 1 57 testutil.MakeScalarInt64(1, 4), // 1 58 testutil.MakeBoolVector([]bool{true, false, false, false}), // a = 2 59 testutil.MakeScalarInt64(2, 4), // 2 60 testutil.MakeScalarNull(types.T_int64, 4), 61 }, 62 match: true, 63 err: false, 64 expect: testutil.MakeInt64Vector([]int64{2, 0, 0, 0}, []uint64{1, 2, 3}), 65 }, 66 67 { 68 info: "when a = 1 then 1, when a = 2 then 2", proc: testutil.NewProc(), 69 vs: []*vector.Vector{ 70 testutil.MakeBoolVector([]bool{false, false, false, false}), // a = 1 71 testutil.MakeScalarInt64(1, 4), // 1 72 testutil.MakeBoolVector([]bool{true, false, false, false}), // a = 2 73 testutil.MakeScalarInt64(2, 4), // 2 74 }, 75 match: true, 76 err: false, 77 expect: testutil.MakeInt64Vector([]int64{2, 0, 0, 0}, []uint64{1, 2, 3}), 78 }, 79 80 { 81 info: "when a = 1 then c1, when a = 2 then c2", proc: testutil.NewProc(), 82 vs: []*vector.Vector{ 83 testutil.MakeBoolVector([]bool{true, true, false, false, false}), // a = 1 84 testutil.MakeInt64Vector([]int64{1, 0, 3, 4, 5}, []uint64{1}), // 1, null, 3, 4, 5 85 testutil.MakeBoolVector([]bool{false, false, true, true, false}), // a = 2 86 testutil.MakeInt64Vector([]int64{0, 0, 0, 0, 0}, []uint64{1, 2, 3}), // 0, null, null, null, 0 87 }, 88 match: true, 89 err: false, 90 expect: testutil.MakeInt64Vector([]int64{1, 0, 0, 0, 0}, []uint64{1, 2, 3, 4}), // 1, null, null, null, null 91 }, 92 93 { 94 info: "when a = 1 then c1, when a = 2 then c2", proc: testutil.NewProc(), 95 vs: []*vector.Vector{ 96 testutil.MakeBoolVector([]bool{true, true, false, false, false}), // a = 1 97 testutil.MakeInt64Vector([]int64{1, 0, 3, 4, 5}, []uint64{1}), // 1, null, 3, 4, 5 98 testutil.MakeBoolVector([]bool{false, false, true, true, false}), // a = 2 99 testutil.MakeInt64Vector([]int64{0, 0, 0, 0, 0}, []uint64{1, 2, 3}), // 0, null, null, null, 0 100 }, 101 match: true, 102 err: false, 103 expect: testutil.MakeInt64Vector([]int64{1, 0, 0, 0, 0}, []uint64{1, 2, 3, 4}), // 1, null, null, null, null 104 }, 105 106 { 107 info: "when a = 1 then c1, when a = 2 then c2, else null", proc: testutil.NewProc(), 108 vs: []*vector.Vector{ 109 testutil.MakeBoolVector([]bool{true, true, false, false, false}), // a = 1 110 testutil.MakeInt64Vector([]int64{1, 0, 3, 4, 5}, []uint64{1}), // 1, null, 3, 4, 5 111 testutil.MakeBoolVector([]bool{false, false, true, true, false}), // a = 2 112 testutil.MakeInt64Vector([]int64{0, 0, 0, 0, 0}, []uint64{1, 2, 3}), // 0, null, null, null, 0 113 }, 114 match: true, 115 err: false, 116 expect: testutil.MakeInt64Vector([]int64{1, 0, 0, 0, 0}, []uint64{1, 2, 3, 4}), // 1, null, null, null, null 117 }, 118 119 { 120 info: "when a = 1 then c1, when a = 2 then c2, else c3", proc: testutil.NewProc(), 121 vs: []*vector.Vector{ 122 testutil.MakeBoolVector([]bool{true, true, false, false, false}), // a = 1 123 testutil.MakeInt64Vector([]int64{1, 0, 3, 4, 5}, []uint64{1}), // 1, null, 3, 4, 5 124 testutil.MakeBoolVector([]bool{false, false, true, true, false}), // a = 2 125 testutil.MakeInt64Vector([]int64{0, 0, 0, 0, 0}, []uint64{1, 2, 3}), // 0, null, null, null, 0 126 testutil.MakeInt64Vector([]int64{100, 200, 300, 0, 500}, []uint64{3}), // 100, 200, 300, null, 500 127 }, 128 match: true, 129 err: false, 130 expect: testutil.MakeInt64Vector([]int64{1, 0, 0, 0, 500}, []uint64{1, 2, 3}), // 1, null, null, null, 500 131 }, 132 133 { 134 info: "when true then c1, when false then c2, else null", proc: testutil.NewProc(), 135 vs: []*vector.Vector{ 136 testutil.MakeScalarBool(true, 4), 137 testutil.MakeInt64Vector([]int64{1, 2, 3, 4}, nil), // 1, 2, 3, 4 138 testutil.MakeScalarBool(false, 4), 139 testutil.MakeInt64Vector([]int64{4, 3, 2, 1}, nil), 140 testutil.MakeScalarNull(types.T_int64, 4), 141 }, 142 match: true, 143 err: false, 144 expect: testutil.MakeInt64Vector([]int64{1, 2, 3, 4}, nil), // 1, 2, 3, 4 145 }, 146 147 { 148 info: "when true then 1, when false then 2, else null", proc: testutil.NewProc(), 149 vs: []*vector.Vector{ 150 testutil.MakeScalarBool(true, 4), 151 testutil.MakeScalarInt64(1, 4), 152 testutil.MakeScalarBool(false, 4), 153 testutil.MakeScalarInt64(2, 4), 154 testutil.MakeScalarNull(types.T_int64, 4), 155 }, 156 match: true, 157 err: false, 158 expect: testutil.MakeScalarInt64(1, 4), 159 }, 160 161 { 162 info: "when a = 1 then 10, when a = 2 then true, else null", proc: testutil.NewProc(), 163 vs: []*vector.Vector{ 164 testutil.MakeBoolVector([]bool{false, false, false, false}), 165 testutil.MakeScalarInt64(10, 4), 166 testutil.MakeBoolVector([]bool{false, false, false, false}), 167 testutil.MakeScalarBool(true, 4), 168 testutil.MakeScalarNull(types.T_bool, 4), 169 }, 170 match: false, 171 }, 172 173 { 174 // special case 1 175 info: "when a = 1 then 1, when a = 1 then 2, else null", proc: testutil.NewProc(), 176 vs: []*vector.Vector{ 177 testutil.MakeBoolVector([]bool{true, true, false, false}), 178 testutil.MakeScalarInt64(1, 4), 179 testutil.MakeBoolVector([]bool{false, true, true, false}), 180 testutil.MakeScalarInt64(2, 4), 181 testutil.MakeScalarNull(types.T_int64, 4), 182 }, 183 match: true, 184 err: false, 185 expect: testutil.MakeInt64Vector([]int64{1, 1, 2, 0}, []uint64{3}), 186 }, 187 188 { 189 // special case 2 190 info: "when true then null else null", proc: testutil.NewProc(), 191 vs: []*vector.Vector{ 192 testutil.MakeScalarBool(true, 5), 193 testutil.MakeScalarNull(types.T_any, 5), 194 testutil.MakeScalarNull(types.T_any, 5), 195 }, 196 match: true, 197 err: false, 198 expect: testutil.MakeScalarNull(types.T_any, 5), 199 }, 200 } 201 202 for i, tc := range testCases { 203 t.Run(tc.info, func(t *testing.T) { 204 { 205 inputTypes := make([]types.T, len(tc.vs)) 206 for i := range inputTypes { 207 inputTypes[i] = tc.vs[i].Typ.Oid 208 } 209 b := CwTypeCheckFn(inputTypes, nil, types.T_int64) 210 if !tc.match { 211 require.False(t, b, fmt.Sprintf("case '%s' shouldn't meet the function's requirement but it meets.", tc.info)) 212 return 213 } 214 require.True(t, b) 215 } 216 217 got, ergot := cwGeneral[int64](tc.vs, tc.proc, types.Type{Oid: types.T_int64}) 218 if tc.err { 219 require.Errorf(t, ergot, fmt.Sprintf("case '%d' expected error, but no error happens", i)) 220 } else { 221 require.NoError(t, ergot) 222 require.True(t, testutil.CompareVectors(tc.expect, got), "got vector is different with expected") 223 } 224 }) 225 } 226 }