github.com/matrixorigin/matrixone@v0.7.0/pkg/vectorize/date_add/date_add.go (about) 1 // Copyright 2021 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 package date_add 15 16 import ( 17 "time" 18 19 "github.com/matrixorigin/matrixone/pkg/common/moerr" 20 "github.com/matrixorigin/matrixone/pkg/container/nulls" 21 "github.com/matrixorigin/matrixone/pkg/container/types" 22 ) 23 24 func DateAdd(xs []types.Date, ys []int64, zs []int64, xns *nulls.Nulls, yns *nulls.Nulls, rns *nulls.Nulls, rs []types.Date) ([]types.Date, error) { 25 if len(ys) == 0 || len(zs) == 0 { 26 for i := range xs { 27 nulls.Add(rns, uint64(i)) 28 } 29 return rs, nil 30 } 31 32 for _, y := range ys { 33 err := types.JudgeIntervalNumOverflow(y, types.IntervalType(zs[0])) 34 if err != nil { 35 return rs, err 36 } 37 } 38 // xs == nil and ys == nil 39 if xs == nil { 40 for i := range ys { 41 nulls.Add(rns, uint64(i)) 42 } 43 } else if len(xs) == len(ys) { 44 for i, d := range xs { 45 if nulls.Contains(xns, uint64(i)) || nulls.Contains(yns, uint64(i)) { 46 nulls.Add(rns, uint64(i)) 47 continue 48 } 49 date, success := d.ToDatetime().AddInterval(ys[i], types.IntervalType(zs[0]), types.DateType) 50 if success { 51 rs[i] = date.ToDate() 52 } else { 53 return rs, moerr.NewOutOfRangeNoCtx("date", "") 54 } 55 } 56 } else if len(xs) == 1 { 57 for i, d := range ys { 58 if nulls.Contains(xns, uint64(0)) || nulls.Contains(yns, uint64(i)) { 59 nulls.Add(rns, uint64(i)) 60 continue 61 } 62 date, success := xs[0].ToDatetime().AddInterval(d, types.IntervalType(zs[0]), types.DateType) 63 if success { 64 rs[i] = date.ToDate() 65 } else { 66 return rs, moerr.NewOutOfRangeNoCtx("date", "") 67 } 68 } 69 } else if len(ys) == 1 { 70 for i, d := range xs { 71 if nulls.Contains(xns, uint64(i)) || nulls.Contains(yns, uint64(0)) { 72 nulls.Add(rns, uint64(i)) 73 continue 74 } 75 date, success := d.ToDatetime().AddInterval(ys[0], types.IntervalType(zs[0]), types.DateType) 76 if success { 77 rs[i] = date.ToDate() 78 } else { 79 return rs, moerr.NewOutOfRangeNoCtx("date", "") 80 } 81 } 82 } 83 return rs, nil 84 } 85 86 func TimeAdd(xs []types.Time, ys []int64, zs []int64, xns *nulls.Nulls, yns *nulls.Nulls, rns *nulls.Nulls, rs []types.Time) ([]types.Time, error) { 87 if len(ys) == 0 || len(zs) == 0 { 88 for i := range xs { 89 nulls.Add(rns, uint64(i)) 90 } 91 return rs, nil 92 } 93 for _, y := range ys { 94 err := types.JudgeIntervalNumOverflow(y, types.IntervalType(zs[0])) 95 if err != nil { 96 return rs, err 97 } 98 } 99 if xs == nil { 100 for i := range ys { 101 nulls.Add(rns, uint64(i)) 102 } 103 } else if len(xs) == len(ys) { 104 for i, t := range xs { 105 if nulls.Contains(xns, uint64(i)) || nulls.Contains(yns, uint64(i)) { 106 nulls.Add(rns, uint64(i)) 107 continue 108 } 109 time, success := t.AddInterval(ys[i], types.IntervalType(zs[0])) 110 if success { 111 rs[i] = time 112 } else { 113 return rs, moerr.NewOutOfRangeNoCtx("time", "") 114 } 115 } 116 } else if len(xs) == 1 { 117 for i, d := range ys { 118 if nulls.Contains(xns, uint64(0)) || nulls.Contains(yns, uint64(i)) { 119 nulls.Add(rns, uint64(i)) 120 continue 121 } 122 time, success := xs[0].AddInterval(d, types.IntervalType(zs[0])) 123 if success { 124 rs[i] = time 125 } else { 126 return rs, moerr.NewOutOfRangeNoCtx("time", "") 127 } 128 } 129 } else if len(ys) == 1 { 130 for i, d := range xs { 131 if nulls.Contains(xns, uint64(i)) || nulls.Contains(yns, uint64(0)) { 132 nulls.Add(rns, uint64(i)) 133 continue 134 } 135 time, success := d.AddInterval(ys[0], types.IntervalType(zs[0])) 136 if success { 137 rs[i] = time 138 } else { 139 return rs, moerr.NewOutOfRangeNoCtx("time", "") 140 } 141 } 142 } 143 return rs, nil 144 } 145 146 func DatetimeAdd(xs []types.Datetime, ys []int64, zs []int64, xns *nulls.Nulls, yns *nulls.Nulls, rns *nulls.Nulls, rs []types.Datetime) ([]types.Datetime, error) { 147 if len(ys) == 0 || len(zs) == 0 { 148 for i := range xs { 149 nulls.Add(rns, uint64(i)) 150 } 151 return rs, nil 152 } 153 for _, y := range ys { 154 err := types.JudgeIntervalNumOverflow(y, types.IntervalType(zs[0])) 155 if err != nil { 156 return rs, err 157 } 158 } 159 if xs == nil { 160 for i := range ys { 161 nulls.Add(rns, uint64(i)) 162 } 163 } else if len(xs) == len(ys) { 164 for i, d := range xs { 165 if nulls.Contains(xns, uint64(i)) || nulls.Contains(yns, uint64(i)) { 166 nulls.Add(rns, uint64(i)) 167 continue 168 } 169 date, success := d.AddInterval(ys[i], types.IntervalType(zs[0]), types.DateTimeType) 170 if success { 171 rs[i] = date 172 } else { 173 return rs, moerr.NewOutOfRangeNoCtx("datetime", "") 174 } 175 } 176 } else if len(xs) == 1 { 177 for i, d := range ys { 178 if nulls.Contains(xns, uint64(0)) || nulls.Contains(yns, uint64(i)) { 179 nulls.Add(rns, uint64(i)) 180 continue 181 } 182 date, success := xs[0].AddInterval(d, types.IntervalType(zs[0]), types.DateTimeType) 183 if success { 184 rs[i] = date 185 } else { 186 return rs, moerr.NewOutOfRangeNoCtx("datetime", "") 187 } 188 } 189 } else if len(ys) == 1 { 190 for i, d := range xs { 191 if nulls.Contains(xns, uint64(i)) || nulls.Contains(yns, uint64(0)) { 192 nulls.Add(rns, uint64(i)) 193 continue 194 } 195 date, success := d.AddInterval(ys[0], types.IntervalType(zs[0]), types.DateTimeType) 196 if success { 197 rs[i] = date 198 } else { 199 return rs, moerr.NewOutOfRangeNoCtx("datetime", "") 200 } 201 } 202 } 203 return rs, nil 204 } 205 206 func DateStringAdd(xs []string, ys []int64, zs []int64, xns *nulls.Nulls, yns *nulls.Nulls, rns *nulls.Nulls, rs []types.Datetime) ([]types.Datetime, error) { 207 if len(ys) == 0 || len(zs) == 0 { 208 for i := range xs { 209 nulls.Add(rns, uint64(i)) 210 rs[i] = 0 211 } 212 return rs, nil 213 } 214 for _, y := range ys { 215 err := types.JudgeIntervalNumOverflow(y, types.IntervalType(zs[0])) 216 if err != nil { 217 return rs, err 218 } 219 } 220 ds := make([]types.Datetime, len(xs)) 221 for i, str := range xs { 222 if nulls.Contains(xns, uint64(i)) { 223 continue 224 } 225 d, e := types.ParseDatetime(str, 6) 226 if e != nil { 227 return rs, e 228 } 229 ds[i] = d 230 } 231 if xs == nil { 232 for i := range ys { 233 nulls.Add(rns, uint64(i)) 234 } 235 return rs, nil 236 } else if len(ds) == len(ys) { 237 for i, d := range ds { 238 if nulls.Contains(xns, uint64(i)) || nulls.Contains(yns, uint64(i)) { 239 nulls.Add(rns, uint64(i)) 240 continue 241 } 242 date, success := d.AddInterval(ys[i], types.IntervalType(zs[0]), types.DateTimeType) 243 if success { 244 rs[i] = date 245 } else { 246 return rs, moerr.NewOutOfRangeNoCtx("datetime", "") 247 } 248 } 249 } else if len(ds) == 1 { 250 for i, d := range ys { 251 if nulls.Contains(xns, uint64(0)) || nulls.Contains(yns, uint64(i)) { 252 nulls.Add(rns, uint64(i)) 253 continue 254 } 255 date, success := ds[0].AddInterval(d, types.IntervalType(zs[0]), types.DateTimeType) 256 if success { 257 rs[i] = date 258 } else { 259 return rs, moerr.NewOutOfRangeNoCtx("datetime", "") 260 } 261 } 262 } else if len(ys) == 1 { 263 for i, d := range ds { 264 if nulls.Contains(xns, uint64(i)) || nulls.Contains(yns, uint64(0)) { 265 nulls.Add(rns, uint64(i)) 266 continue 267 } 268 date, success := d.AddInterval(ys[0], types.IntervalType(zs[0]), types.DateTimeType) 269 if success { 270 rs[i] = date 271 } else { 272 return rs, moerr.NewOutOfRangeNoCtx("datetime", "") 273 } 274 } 275 } 276 return rs, nil 277 } 278 279 func TimestampAdd(loc *time.Location, xs []types.Timestamp, ys []int64, zs []int64, xns *nulls.Nulls, yns *nulls.Nulls, rns *nulls.Nulls, rs []types.Timestamp) ([]types.Timestamp, error) { 280 if len(ys) == 0 || len(zs) == 0 { 281 for i := range xs { 282 nulls.Add(rns, uint64(i)) 283 } 284 return rs, nil 285 } 286 for _, y := range ys { 287 err := types.JudgeIntervalNumOverflow(y, types.IntervalType(zs[0])) 288 if err != nil { 289 return rs, err 290 } 291 } 292 ds := make([]types.Datetime, len(xs)) 293 ds, err := types.TimestampToDatetime(loc, xs, ds) 294 if err != nil { 295 return rs, err 296 } 297 if xs == nil { 298 for i := range ys { 299 nulls.Add(rns, uint64(i)) 300 } 301 } else if len(xs) == len(ys) { 302 for i, d := range ds { 303 if nulls.Contains(xns, uint64(i)) || nulls.Contains(yns, uint64(i)) { 304 nulls.Add(rns, uint64(i)) 305 continue 306 } 307 date, success := d.AddInterval(ys[i], types.IntervalType(zs[0]), types.TimeStampType) 308 if success { 309 ts := date.ToTimestamp(loc) 310 if ts < 0 { 311 return rs, moerr.NewOutOfRangeNoCtx("timestamp", "") 312 } 313 rs[i] = ts 314 } else { 315 return rs, moerr.NewOutOfRangeNoCtx("timestamp", "") 316 } 317 } 318 } else if len(xs) == 1 { 319 for i, d := range ys { 320 if nulls.Contains(xns, uint64(0)) || nulls.Contains(yns, uint64(i)) { 321 nulls.Add(rns, uint64(i)) 322 continue 323 } 324 date, success := ds[0].AddInterval(d, types.IntervalType(zs[0]), types.TimeStampType) 325 if success { 326 ts := date.ToTimestamp(loc) 327 if ts < 0 { 328 return rs, moerr.NewOutOfRangeNoCtx("timestamp", "") 329 } 330 rs[i] = ts 331 } else { 332 return rs, moerr.NewOutOfRangeNoCtx("timestamp", "") 333 } 334 } 335 } else if len(ys) == 1 { 336 for i, d := range ds { 337 if nulls.Contains(xns, uint64(i)) || nulls.Contains(yns, uint64(0)) { 338 nulls.Add(rns, uint64(i)) 339 continue 340 } 341 date, success := d.AddInterval(ys[0], types.IntervalType(zs[0]), types.TimeStampType) 342 if success { 343 ts := date.ToTimestamp(loc) 344 if ts < 0 { 345 return rs, moerr.NewOutOfRangeNoCtx("timestamp", "") 346 } 347 rs[i] = ts 348 } else { 349 return rs, moerr.NewOutOfRangeNoCtx("timestamp", "") 350 } 351 } 352 } 353 return rs, nil 354 }