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  }