github.com/matrixorigin/matrixone@v0.7.0/pkg/vectorize/date_sub/date_sub.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_sub 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 DateSub(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 if xs == nil { 39 for i := range ys { 40 nulls.Add(rns, uint64(i)) 41 } 42 } else if len(xs) == len(ys) { 43 for i, d := range xs { 44 if nulls.Contains(xns, uint64(i)) || nulls.Contains(yns, uint64(i)) { 45 nulls.Add(rns, uint64(i)) 46 continue 47 } 48 date, success := d.ToDatetime().AddInterval(-ys[i], types.IntervalType(zs[0]), types.DateType) 49 if success { 50 rs[i] = date.ToDate() 51 } else { 52 return rs, moerr.NewOutOfRangeNoCtx("date", "") 53 } 54 } 55 } else if len(xs) == 1 { 56 for i, d := range ys { 57 if nulls.Contains(xns, uint64(0)) || nulls.Contains(yns, uint64(i)) { 58 nulls.Add(rns, uint64(i)) 59 continue 60 } 61 date, success := xs[0].ToDatetime().AddInterval(-d, types.IntervalType(zs[0]), types.DateType) 62 if success { 63 rs[i] = date.ToDate() 64 } else { 65 return rs, moerr.NewOutOfRangeNoCtx("date", "") 66 } 67 } 68 } else if len(ys) == 1 { 69 for i, d := range xs { 70 if nulls.Contains(xns, uint64(i)) || nulls.Contains(yns, uint64(0)) { 71 nulls.Add(rns, uint64(i)) 72 continue 73 } 74 date, success := d.ToDatetime().AddInterval(-ys[0], types.IntervalType(zs[0]), types.DateType) 75 if success { 76 rs[i] = date.ToDate() 77 } else { 78 return rs, moerr.NewOutOfRangeNoCtx("date", "") 79 } 80 } 81 } 82 return rs, nil 83 } 84 85 func DatetimeSub(xs []types.Datetime, ys []int64, zs []int64, xns *nulls.Nulls, yns *nulls.Nulls, rns *nulls.Nulls, rs []types.Datetime) ([]types.Datetime, error) { 86 if len(ys) == 0 || len(zs) == 0 { 87 for i := range xs { 88 nulls.Add(rns, uint64(i)) 89 } 90 return rs, nil 91 } 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, d := range xs { 105 if nulls.Contains(xns, uint64(i)) || nulls.Contains(yns, uint64(i)) { 106 nulls.Add(rns, uint64(i)) 107 continue 108 } 109 date, success := d.AddInterval(-ys[i], types.IntervalType(zs[0]), types.DateTimeType) 110 if success { 111 rs[i] = date 112 } else { 113 return rs, moerr.NewOutOfRangeNoCtx("datetime", "") 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 date, success := xs[0].AddInterval(-d, types.IntervalType(zs[0]), types.DateTimeType) 123 if success { 124 rs[i] = date 125 } else { 126 return rs, moerr.NewOutOfRangeNoCtx("datetime", "") 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 date, success := d.AddInterval(-ys[0], types.IntervalType(zs[0]), types.DateTimeType) 136 if success { 137 rs[i] = date 138 } else { 139 return rs, moerr.NewOutOfRangeNoCtx("datetime", "") 140 } 141 } 142 } 143 return rs, nil 144 } 145 146 func DateStringSub(xs []string, 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 rs[i] = 0 151 } 152 return rs, nil 153 } 154 for _, y := range ys { 155 err := types.JudgeIntervalNumOverflow(y, types.IntervalType(zs[0])) 156 if err != nil { 157 return rs, err 158 } 159 } 160 ds := make([]types.Datetime, len(xs)) 161 for i, str := range xs { 162 if nulls.Contains(xns, uint64(i)) { 163 continue 164 } 165 d, e := types.ParseDatetime(str, 6) 166 if e != nil { 167 return rs, e 168 } 169 ds[i] = d 170 } 171 if xs == nil { 172 for i := range ys { 173 nulls.Add(rns, uint64(i)) 174 } 175 return rs, nil 176 } else if len(ds) == len(ys) { 177 for i, d := range ds { 178 if nulls.Contains(xns, uint64(i)) || nulls.Contains(yns, uint64(i)) { 179 nulls.Add(rns, uint64(i)) 180 continue 181 } 182 date, success := d.AddInterval(-ys[i], 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(ds) == 1 { 190 for i, d := range ys { 191 if nulls.Contains(xns, uint64(0)) || nulls.Contains(yns, uint64(i)) { 192 nulls.Add(rns, uint64(i)) 193 continue 194 } 195 date, success := ds[0].AddInterval(-d, types.IntervalType(zs[0]), types.DateTimeType) 196 if success { 197 rs[i] = date 198 } else { 199 return rs, moerr.NewOutOfRangeNoCtx("datetime", "") 200 } 201 } 202 } else if len(ys) == 1 { 203 for i, d := range ds { 204 if nulls.Contains(xns, uint64(i)) || nulls.Contains(yns, uint64(0)) { 205 nulls.Add(rns, uint64(i)) 206 continue 207 } 208 date, success := d.AddInterval(-ys[0], types.IntervalType(zs[0]), types.DateTimeType) 209 if success { 210 rs[i] = date 211 } else { 212 return rs, moerr.NewOutOfRangeNoCtx("datetime", "") 213 } 214 } 215 } 216 return rs, nil 217 } 218 219 func TimestampSub(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) { 220 if len(ys) == 0 || len(zs) == 0 { 221 for i := range xs { 222 nulls.Add(rns, uint64(i)) 223 } 224 return rs, nil 225 } 226 for _, y := range ys { 227 err := types.JudgeIntervalNumOverflow(y, types.IntervalType(zs[0])) 228 if err != nil { 229 return rs, err 230 } 231 } 232 ds := make([]types.Datetime, len(xs)) 233 ds, err := types.TimestampToDatetime(loc, xs, ds) 234 if err != nil { 235 return rs, err 236 } 237 if xs == nil { 238 for i := range ys { 239 nulls.Add(rns, uint64(i)) 240 } 241 } else if len(xs) == len(ys) { 242 for i, d := range ds { 243 if nulls.Contains(xns, uint64(i)) || nulls.Contains(yns, uint64(i)) { 244 nulls.Add(rns, uint64(i)) 245 continue 246 } 247 date, success := d.AddInterval(-ys[i], types.IntervalType(zs[0]), types.TimeStampType) 248 if success { 249 ts := date.ToTimestamp(loc) 250 if ts < 0 { 251 return rs, moerr.NewOutOfRangeNoCtx("timestamp", "") 252 } 253 rs[i] = ts 254 } else { 255 return rs, moerr.NewOutOfRangeNoCtx("timestamp", "") 256 } 257 } 258 } else if len(xs) == 1 { 259 for i, d := range ys { 260 if nulls.Contains(xns, uint64(0)) || nulls.Contains(yns, uint64(i)) { 261 nulls.Add(rns, uint64(i)) 262 continue 263 } 264 date, success := ds[0].AddInterval(-d, types.IntervalType(zs[0]), types.TimeStampType) 265 if success { 266 ts := date.ToTimestamp(loc) 267 if ts < 0 { 268 return rs, moerr.NewOutOfRangeNoCtx("timestamp", "") 269 } 270 rs[i] = ts 271 } else { 272 return rs, moerr.NewOutOfRangeNoCtx("timestamp", "") 273 } 274 } 275 } else if len(ys) == 1 { 276 for i, d := range ds { 277 if nulls.Contains(xns, uint64(i)) || nulls.Contains(yns, uint64(0)) { 278 nulls.Add(rns, uint64(i)) 279 continue 280 } 281 date, success := d.AddInterval(-ys[0], types.IntervalType(zs[0]), types.TimeStampType) 282 if success { 283 ts := date.ToTimestamp(loc) 284 if ts < 0 { 285 return rs, moerr.NewOutOfRangeNoCtx("timestamp", "") 286 } 287 rs[i] = ts 288 } else { 289 return rs, moerr.NewOutOfRangeNoCtx("timestamp", "") 290 } 291 } 292 } 293 return rs, nil 294 }