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  }