github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/plan/function/operator/coalesce.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 "github.com/matrixorigin/matrixone/pkg/container/nulls" 19 "github.com/matrixorigin/matrixone/pkg/container/types" 20 "github.com/matrixorigin/matrixone/pkg/container/vector" 21 "github.com/matrixorigin/matrixone/pkg/vm/process" 22 ) 23 24 var ( 25 CoalesceUint8 = func(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 26 return coalesceGeneral[uint8](vs, proc, types.Type{Oid: types.T_uint8}) 27 } 28 29 CoalesceUint16 = func(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 30 return coalesceGeneral[uint16](vs, proc, types.Type{Oid: types.T_uint16}) 31 } 32 33 CoalesceUint32 = func(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 34 return coalesceGeneral[uint32](vs, proc, types.Type{Oid: types.T_uint32}) 35 } 36 37 CoalesceUint64 = func(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 38 return coalesceGeneral[uint64](vs, proc, types.Type{Oid: types.T_uint64}) 39 } 40 41 CoalesceInt8 = func(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 42 return coalesceGeneral[int8](vs, proc, types.Type{Oid: types.T_int8}) 43 } 44 45 CoalesceInt16 = func(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 46 return coalesceGeneral[int16](vs, proc, types.Type{Oid: types.T_int16}) 47 } 48 49 CoalesceInt32 = func(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 50 return coalesceGeneral[int32](vs, proc, types.Type{Oid: types.T_int32}) 51 } 52 53 CoalesceInt64 = func(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 54 return coalesceGeneral[int64](vs, proc, types.Type{Oid: types.T_int64}) 55 } 56 57 CoalesceFloat32 = func(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 58 return coalesceGeneral[float32](vs, proc, types.Type{Oid: types.T_float32}) 59 } 60 61 CoalesceFloat64 = func(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 62 return coalesceGeneral[float64](vs, proc, types.Type{Oid: types.T_float64}) 63 } 64 65 CoalesceBool = func(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 66 return coalesceGeneral[bool](vs, proc, types.Type{Oid: types.T_bool}) 67 } 68 69 CoalesceDate = func(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 70 return coalesceGeneral[types.Date](vs, proc, types.Type{Oid: types.T_date}) 71 } 72 73 CoalesceTime = func(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 74 return coalesceGeneral[types.Time](vs, proc, types.Type{Oid: types.T_time}) 75 } 76 77 CoalesceDateTime = func(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 78 return coalesceGeneral[types.Datetime](vs, proc, types.Type{Oid: types.T_datetime}) 79 } 80 81 CoalesceVarchar = func(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 82 return coalesceString(vs, proc, types.Type{Oid: types.T_varchar, Width: types.MaxVarcharLen}) 83 } 84 85 CoalesceChar = func(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 86 return coalesceString(vs, proc, types.Type{Oid: types.T_char}) 87 } 88 89 CoalesceJson = func(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 90 return coalesceString(vs, proc, types.Type{Oid: types.T_json.ToType().Oid}) 91 } 92 93 CoalesceBlob = func(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 94 return coalesceString(vs, proc, types.Type{Oid: types.T_blob.ToType().Oid}) 95 } 96 97 CoalesceText = func(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 98 return coalesceString(vs, proc, types.Type{Oid: types.T_text.ToType().Oid}) 99 } 100 101 CoalesceDecimal64 = func(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 102 return coalesceGeneral[types.Decimal64](vs, proc, types.Type{Oid: types.T_decimal64}) 103 } 104 105 CoalesceDecimal128 = func(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 106 return coalesceGeneral[types.Decimal128](vs, proc, types.Type{Oid: types.T_decimal128}) 107 } 108 109 CoalesceTimestamp = func(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 110 return coalesceGeneral[types.Timestamp](vs, proc, types.Type{Oid: types.T_timestamp}) 111 } 112 113 CoalesceUuid = func(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 114 return coalesceGeneral[types.Uuid](vs, proc, types.Type{Oid: types.T_uuid}) 115 } 116 ) 117 118 // CoalesceTypeCheckFn is type check function for coalesce operator 119 func CoalesceTypeCheckFn(inputTypes []types.T, _ []types.T, ret types.T) bool { 120 l := len(inputTypes) 121 for i := 0; i < l; i++ { 122 if inputTypes[i] != ret && inputTypes[i] != types.T_any { 123 return false 124 } 125 } 126 return true 127 } 128 129 // coalesceGeneral is a general evaluate function for coalesce operator 130 // when return type is uint / int / float / bool / date / datetime 131 func coalesceGeneral[T NormalType](vs []*vector.Vector, proc *process.Process, t types.Type) (*vector.Vector, error) { 132 vecLen := vector.Length(vs[0]) 133 startIdx := 0 134 for i := 0; i < len(vs); i++ { 135 input := vs[i] 136 if input.IsScalar() { 137 if !input.IsScalarNull() { 138 cols := vector.MustTCols[T](input) 139 r := proc.AllocScalarVector(t) 140 r.Typ.Precision = input.Typ.Precision 141 r.Typ.Width = input.Typ.Width 142 r.Typ.Scale = input.Typ.Scale 143 r.Col = make([]T, 1) 144 r.Col.([]T)[0] = cols[0] 145 return r, nil 146 } 147 } else { 148 startIdx = i 149 break 150 } 151 } 152 153 rs, err := proc.AllocVector(t, int64(vecLen*t.Oid.TypeLen())) 154 if err != nil { 155 return nil, err 156 } 157 rs.Col = vector.DecodeFixedCol[T](rs, t.Oid.TypeLen()) 158 rs.Col = rs.Col.([]T)[:vecLen] 159 rsCols := rs.Col.([]T) 160 161 rs.Nsp = nulls.NewWithSize(vecLen) 162 rs.Nsp.Np.AddRange(0, uint64(vecLen)) 163 164 for i := startIdx; i < len(vs); i++ { 165 input := vs[i] 166 if input.Typ.Oid != types.T_any { 167 rs.Typ = input.Typ 168 } 169 cols := vector.MustTCols[T](input) 170 if input.IsScalar() { 171 if input.IsScalarNull() { 172 continue 173 } 174 175 for j := 0; j < vecLen; j++ { 176 if rs.Nsp.Contains(uint64(j)) { 177 rsCols[j] = cols[0] 178 } 179 } 180 rs.Nsp.Np = nil 181 return rs, nil 182 } else { 183 nullsLength := nulls.Length(input.Nsp) 184 if nullsLength == vecLen { 185 // all null do nothing 186 continue 187 } else if nullsLength == 0 { 188 // all not null 189 for j := 0; j < vecLen; j++ { 190 if rs.Nsp.Contains(uint64(j)) { 191 rsCols[j] = cols[j] 192 } 193 } 194 rs.Nsp.Np = nil 195 return rs, nil 196 } else { 197 // some nulls 198 for j := 0; j < vecLen; j++ { 199 if rs.Nsp.Contains(uint64(j)) && !input.Nsp.Contains(uint64(j)) { 200 rsCols[j] = cols[j] 201 rs.Nsp.Np.Remove(uint64(j)) 202 } 203 } 204 205 if rs.Nsp.Np.IsEmpty() { 206 rs.Nsp.Np = nil 207 return rs, nil 208 } 209 } 210 } 211 } 212 213 return rs, nil 214 } 215 216 // coalesceGeneral is a general evaluate function for coalesce operator 217 // when return type is char / varchar 218 func coalesceString(vs []*vector.Vector, proc *process.Process, typ types.Type) (*vector.Vector, error) { 219 vecLen := vector.Length(vs[0]) 220 startIdx := 0 221 222 // If leading expressions are non null scalar, return. Otherwise startIdx 223 // is positioned at the first non scalar vector. 224 for i := 0; i < len(vs); i++ { 225 input := vs[i] 226 if input.IsScalar() { 227 if !input.IsScalarNull() { 228 cols := vector.MustStrCols(input) 229 return vector.NewConstString(typ, input.Length(), cols[0], proc.Mp()), nil 230 } 231 } else { 232 startIdx = i 233 break 234 } 235 } 236 237 rs := make([]string, vecLen) 238 nsp := nulls.NewWithSize(vecLen) 239 nsp.Np.AddRange(0, uint64(vecLen)) 240 241 for i := startIdx; i < len(vs); i++ { 242 input := vs[i] 243 cols := vector.MustStrCols(input) 244 if input.IsScalar() { 245 if input.IsScalarNull() { 246 continue 247 } 248 for j := 0; j < vecLen; j++ { 249 if nsp.Contains(uint64(j)) { 250 rs[j] = cols[0] 251 } 252 } 253 nsp = nil 254 break 255 } else { 256 nullsLength := nulls.Length(input.Nsp) 257 if nullsLength == vecLen { 258 // all null do nothing 259 continue 260 } else if nullsLength == 0 { 261 // all not null 262 for j := 0; j < vecLen; j++ { 263 if nsp.Contains(uint64(j)) { 264 rs[j] = cols[j] 265 } 266 } 267 nsp = nil 268 break 269 } else { 270 // some nulls 271 for j := 0; j < vecLen; j++ { 272 if nsp.Contains(uint64(j)) && !input.Nsp.Contains(uint64(j)) { 273 rs[j] = cols[j] 274 nsp.Np.Remove(uint64(j)) 275 } 276 } 277 278 // now if is empty, break 279 if nsp.Np.IsEmpty() { 280 nsp = nil 281 break 282 } 283 } 284 } 285 } 286 287 return vector.NewWithStrings(typ, rs, nsp, proc.Mp()), nil 288 }