github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/plan/function/builtin/multi/from_unixtime.go (about)

     1  // Copyright 2021 - 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  package multi
    15  
    16  import (
    17  	"math"
    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  	"github.com/matrixorigin/matrixone/pkg/container/vector"
    23  	"github.com/matrixorigin/matrixone/pkg/sql/plan/function/builtin/binary"
    24  	"github.com/matrixorigin/matrixone/pkg/vectorize/fromunixtime"
    25  	"github.com/matrixorigin/matrixone/pkg/vm/process"
    26  )
    27  
    28  const (
    29  	max_unix_timestamp_int = 32536771199
    30  )
    31  
    32  func FromUnixTimeInt64(lv []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
    33  	inVec := lv[0]
    34  	times := vector.MustTCols[int64](inVec)
    35  	if inVec.IsScalarNull() {
    36  		return proc.AllocScalarNullVector(types.T_datetime.ToType()), nil
    37  	}
    38  
    39  	if inVec.IsScalar() {
    40  		rs := make([]types.Datetime, 1)
    41  		fromunixtime.UnixToDatetime(proc.SessionInfo.TimeZone, times, rs)
    42  
    43  		vec := vector.NewConstFixed(types.T_datetime.ToType(), 1, rs[0], proc.Mp())
    44  		if times[0] < 0 || times[0] > max_unix_timestamp_int {
    45  			nulls.Add(vec.Nsp, 0)
    46  		}
    47  		nulls.Set(vec.Nsp, inVec.Nsp)
    48  		return vec, nil
    49  	} else {
    50  		rs := make([]types.Datetime, len(times))
    51  		fromunixtime.UnixToDatetime(proc.SessionInfo.TimeZone, times, rs)
    52  		vec := vector.NewWithFixed(types.T_datetime.ToType(), rs, nulls.NewWithSize(len(rs)), proc.Mp())
    53  		for i := 0; i < len(times); i++ {
    54  			if times[i] < 0 || times[i] > max_unix_timestamp_int {
    55  				nulls.Add(vec.Nsp, uint64(i))
    56  			}
    57  		}
    58  		nulls.Set(vec.Nsp, inVec.Nsp)
    59  		return vec, nil
    60  	}
    61  }
    62  
    63  func FromUnixTimeFloat64(lv []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
    64  	inVec := lv[0]
    65  	times := vector.MustTCols[float64](inVec)
    66  	size := types.T(types.T_datetime).TypeLen()
    67  	if inVec.IsScalarNull() {
    68  		return proc.AllocScalarNullVector(types.T_datetime.ToType()), nil
    69  	}
    70  	if inVec.IsScalar() {
    71  		rs := make([]types.Datetime, 1)
    72  		ints, fracs := splitDecimalToIntAndFrac(times)
    73  		fromunixtime.UnixToDateTimeWithNsec(proc.SessionInfo.TimeZone, ints, fracs, rs)
    74  
    75  		t := types.Type{Oid: types.T_datetime, Size: int32(size), Precision: 6}
    76  		vec := vector.NewConstFixed(t, 1, rs[0], proc.Mp())
    77  		if times[0] < 0 || times[0] > max_unix_timestamp_int {
    78  			nulls.Add(vec.Nsp, 0)
    79  		}
    80  		nulls.Set(vec.Nsp, inVec.Nsp)
    81  		return vec, nil
    82  	} else {
    83  		rs := make([]types.Datetime, len(times))
    84  		ints, fracs := splitDecimalToIntAndFrac(times)
    85  		fromunixtime.UnixToDateTimeWithNsec(proc.SessionInfo.TimeZone, ints, fracs, rs)
    86  		t := types.Type{Oid: types.T_datetime, Size: int32(size), Precision: 6}
    87  		vec := vector.NewWithFixed(t, rs, nulls.NewWithSize(len(rs)), proc.Mp())
    88  		for i := 0; i < len(times); i++ {
    89  			if times[i] < 0 || times[i] > max_unix_timestamp_int {
    90  				nulls.Add(vec.Nsp, uint64(i))
    91  			}
    92  		}
    93  		nulls.Set(vec.Nsp, inVec.Nsp)
    94  		return vec, nil
    95  	}
    96  }
    97  
    98  func FromUnixTimeInt64Format(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
    99  	inVec := vs[0]
   100  	formatVec := vs[1]
   101  	resultType := types.T_varchar.ToType()
   102  	if !formatVec.IsScalar() {
   103  		return nil, moerr.NewInvalidArg(proc.Ctx, "from_unixtime format", "not constant")
   104  	}
   105  	if inVec.IsScalarNull() || formatVec.IsScalarNull() {
   106  		return proc.AllocScalarNullVector(resultType), nil
   107  	}
   108  
   109  	formatMask := formatVec.GetString(0)
   110  	if inVec.IsScalar() {
   111  		times := vector.MustTCols[int64](inVec)
   112  		rs := make([]types.Datetime, 1)
   113  		fromunixtime.UnixToDatetime(proc.SessionInfo.TimeZone, times, rs)
   114  		resCol, err := binary.CalcDateFromat(proc.Ctx, rs, formatMask, inVec.Nsp)
   115  		if err != nil {
   116  			return nil, err
   117  		}
   118  		vec := vector.NewConstString(resultType, 1, resCol[0], proc.Mp())
   119  		if times[0] < 0 || times[0] > max_unix_timestamp_int {
   120  			nulls.Add(vec.Nsp, 0)
   121  		}
   122  		nulls.Set(vec.Nsp, inVec.Nsp)
   123  		return vec, nil
   124  	} else {
   125  		times := vector.MustTCols[int64](inVec)
   126  		rs := make([]types.Datetime, len(times))
   127  		fromunixtime.UnixToDatetime(proc.SessionInfo.TimeZone, times, rs)
   128  		resCol, err := binary.CalcDateFromat(proc.Ctx, rs, formatMask, inVec.Nsp)
   129  		if err != nil {
   130  			return nil, err
   131  		}
   132  		vec := vector.NewWithStrings(resultType, resCol, inVec.Nsp, proc.Mp())
   133  		for i := 0; i < len(times); i++ {
   134  			if times[i] < 0 || times[i] > max_unix_timestamp_int {
   135  				nulls.Add(vec.Nsp, uint64(i))
   136  			}
   137  		}
   138  		nulls.Set(vec.Nsp, inVec.Nsp)
   139  		return vec, nil
   140  	}
   141  }
   142  
   143  func FromUnixTimeFloat64Format(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
   144  	inVec := vs[0]
   145  	formatVec := vs[1]
   146  	resultType := types.T_varchar.ToType()
   147  	if !formatVec.IsScalar() {
   148  		return nil, moerr.NewInvalidArg(proc.Ctx, "from_unixtime format", "not constant")
   149  	}
   150  	if inVec.IsScalarNull() || formatVec.IsScalarNull() {
   151  		return proc.AllocScalarNullVector(resultType), nil
   152  	}
   153  
   154  	formatMask := formatVec.GetString(0)
   155  	if inVec.IsScalar() {
   156  		times := vector.MustTCols[float64](inVec)
   157  		rs := make([]types.Datetime, 1)
   158  		ints, fracs := splitDecimalToIntAndFrac(times)
   159  		fromunixtime.UnixToDateTimeWithNsec(proc.SessionInfo.TimeZone, ints, fracs, rs)
   160  		resCol, err := binary.CalcDateFromat(proc.Ctx, rs, formatMask, inVec.Nsp)
   161  		if err != nil {
   162  			return nil, err
   163  		}
   164  		vec := vector.NewConstString(resultType, 1, resCol[0], proc.Mp())
   165  		if times[0] < 0 || times[0] > max_unix_timestamp_int {
   166  			nulls.Add(vec.Nsp, 0)
   167  		}
   168  		nulls.Set(vec.Nsp, inVec.Nsp)
   169  		return vec, nil
   170  	} else {
   171  		times := vector.MustTCols[float64](inVec)
   172  		rs := make([]types.Datetime, len(times))
   173  		ints, fracs := splitDecimalToIntAndFrac(times)
   174  		fromunixtime.UnixToDateTimeWithNsec(proc.SessionInfo.TimeZone, ints, fracs, rs)
   175  		resCol, err := binary.CalcDateFromat(proc.Ctx, rs, formatMask, inVec.Nsp)
   176  		if err != nil {
   177  			return nil, err
   178  		}
   179  
   180  		vec := vector.NewWithStrings(resultType, resCol, inVec.Nsp, proc.Mp())
   181  		for i := 0; i < len(times); i++ {
   182  			if times[i] < 0 || times[i] > max_unix_timestamp_int {
   183  				nulls.Add(vec.Nsp, uint64(i))
   184  			}
   185  		}
   186  		nulls.Set(vec.Nsp, inVec.Nsp)
   187  		return vec, nil
   188  	}
   189  }
   190  
   191  func splitDecimalToIntAndFrac(floats []float64) ([]int64, []int64) {
   192  	ints := make([]int64, len(floats))
   193  	fracs := make([]int64, len(floats))
   194  	for i, f := range floats {
   195  		intPart := int64(f)
   196  		nano := (f - float64(intPart)) * math.Pow10(9)
   197  		fracPart := int64(nano)
   198  		ints[i] = intPart
   199  		fracs[i] = fracPart
   200  	}
   201  	return ints, fracs
   202  }
   203  
   204  func FromUnixTimeUint64(lv []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
   205  	uint64ToInt64 := func(from []uint64) []int64 {
   206  		to := make([]int64, len(from))
   207  		for i := range from {
   208  			to[i] = int64(from[i])
   209  		}
   210  		return to
   211  	}
   212  	inVec := lv[0]
   213  	times := vector.MustTCols[uint64](inVec)
   214  	if inVec.IsScalarNull() {
   215  		return proc.AllocScalarNullVector(types.T_datetime.ToType()), nil
   216  	}
   217  	if inVec.IsScalar() {
   218  		rs := make([]types.Datetime, 1)
   219  		fromunixtime.UnixToDatetime(proc.SessionInfo.TimeZone, uint64ToInt64(times), rs)
   220  		vec := vector.NewConstFixed(types.T_datetime.ToType(), 1, rs[0], proc.Mp())
   221  
   222  		if times[0] > max_unix_timestamp_int {
   223  			nulls.Add(vec.Nsp, 0)
   224  		}
   225  		nulls.Set(vec.Nsp, inVec.Nsp)
   226  		return vec, nil
   227  	} else {
   228  		rs := make([]types.Datetime, len(times))
   229  		fromunixtime.UnixToDatetime(proc.SessionInfo.TimeZone, uint64ToInt64(times), rs)
   230  		vec := vector.NewWithFixed(types.T_datetime.ToType(), rs, nulls.NewWithSize(len(rs)), proc.Mp())
   231  
   232  		for i := 0; i < len(times); i++ {
   233  			if times[i] > max_unix_timestamp_int {
   234  				nulls.Add(vec.Nsp, uint64(i))
   235  			}
   236  		}
   237  		nulls.Set(vec.Nsp, inVec.Nsp)
   238  		return vec, nil
   239  	}
   240  }
   241  
   242  func FromUnixTimeUint64Format(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
   243  	uint64ToInt64 := func(from []uint64) []int64 {
   244  		to := make([]int64, len(from))
   245  		for i := range from {
   246  			to[i] = int64(from[i])
   247  		}
   248  		return to
   249  	}
   250  
   251  	inVec := vs[0]
   252  	formatVec := vs[1]
   253  	resultType := types.T_varchar.ToType()
   254  	if !formatVec.IsScalar() {
   255  		return nil, moerr.NewInvalidArg(proc.Ctx, "from_unixtime format", "not constant")
   256  	}
   257  	if inVec.IsScalarNull() || formatVec.IsScalarNull() {
   258  		return proc.AllocScalarNullVector(resultType), nil
   259  	}
   260  
   261  	formatMask := formatVec.GetString(0)
   262  	if inVec.IsScalar() {
   263  		times := vector.MustTCols[uint64](inVec)
   264  		rs := make([]types.Datetime, 1)
   265  		fromunixtime.UnixToDatetime(proc.SessionInfo.TimeZone, uint64ToInt64(times), rs)
   266  		resCol, err := binary.CalcDateFromat(proc.Ctx, rs, formatMask, inVec.Nsp)
   267  		if err != nil {
   268  			return nil, err
   269  		}
   270  		vec := vector.NewConstString(resultType, 1, resCol[0], proc.Mp())
   271  		if times[0] > max_unix_timestamp_int {
   272  			nulls.Add(vec.Nsp, 0)
   273  		}
   274  		nulls.Set(vec.Nsp, inVec.Nsp)
   275  		return vec, nil
   276  	} else {
   277  		times := vector.MustTCols[uint64](inVec)
   278  		rs := make([]types.Datetime, len(times))
   279  		fromunixtime.UnixToDatetime(proc.SessionInfo.TimeZone, uint64ToInt64(times), rs)
   280  		resCol, err := binary.CalcDateFromat(proc.Ctx, rs, formatMask, inVec.Nsp)
   281  		if err != nil {
   282  			return nil, err
   283  		}
   284  		vec := vector.NewWithStrings(resultType, resCol, inVec.Nsp, proc.Mp())
   285  		for i := 0; i < len(times); i++ {
   286  			if times[i] > max_unix_timestamp_int {
   287  				nulls.Add(vec.Nsp, uint64(i))
   288  			}
   289  		}
   290  		nulls.Set(vec.Nsp, inVec.Nsp)
   291  		return vec, nil
   292  	}
   293  }