github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/plan/function/builtin/unary/time_of_day_test.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  
    15  package unary
    16  
    17  import (
    18  	"testing"
    19  
    20  	"github.com/matrixorigin/matrixone/pkg/common/mpool"
    21  	"github.com/matrixorigin/matrixone/pkg/container/batch"
    22  	"github.com/matrixorigin/matrixone/pkg/container/types"
    23  	"github.com/matrixorigin/matrixone/pkg/container/vector"
    24  	"github.com/matrixorigin/matrixone/pkg/testutil"
    25  	"github.com/matrixorigin/matrixone/pkg/vm/process"
    26  	"github.com/smartystreets/goconvey/convey"
    27  	"github.com/stretchr/testify/require"
    28  )
    29  
    30  type testPair struct {
    31  	s    string
    32  	want uint8
    33  }
    34  
    35  const (
    36  	Rows = 8000 // default test rows
    37  )
    38  
    39  func TestTimeOfDay(t *testing.T) {
    40  	convey.Convey("HourOfDayDatetimeCase", t, func() {
    41  
    42  		pairs := []testPair{
    43  			{
    44  				s:    "2004-04-03 10:20:00",
    45  				want: 10,
    46  			},
    47  			{
    48  				s:    "2004-08-03 01:01:37",
    49  				want: 1,
    50  			},
    51  			{
    52  				s:    "2004-01-03",
    53  				want: 0,
    54  			},
    55  		}
    56  
    57  		var inStrs []string
    58  		var wantUint8 []uint8
    59  		for _, k := range pairs {
    60  			inStrs = append(inStrs, k.s)
    61  			wantUint8 = append(wantUint8, k.want)
    62  		}
    63  
    64  		inVector := testutil.MakeDateTimeVector(inStrs, nil)
    65  		wantVector := testutil.MakeUint8Vector(wantUint8, nil)
    66  		proc := testutil.NewProc()
    67  		res, err := DatetimeToHour([]*vector.Vector{inVector}, proc)
    68  		convey.So(err, convey.ShouldBeNil)
    69  		compare := testutil.CompareVectors(wantVector, res)
    70  		convey.So(compare, convey.ShouldBeTrue)
    71  	})
    72  	convey.Convey("HourOfDayTimestampCase", t, func() {
    73  
    74  		pairs := []testPair{
    75  			{
    76  				s:    "2004-04-03 10:20:00",
    77  				want: 10,
    78  			},
    79  			{
    80  				s:    "2004-08-03 01:01:37",
    81  				want: 1,
    82  			},
    83  			{
    84  				s:    "2004-01-03",
    85  				want: 0,
    86  			},
    87  		}
    88  
    89  		var inStrs []string
    90  		var wantUint8 []uint8
    91  		for _, k := range pairs {
    92  			inStrs = append(inStrs, k.s)
    93  			wantUint8 = append(wantUint8, k.want)
    94  		}
    95  
    96  		inVector := testutil.MakeTimeStampVector(inStrs, nil)
    97  		wantVector := testutil.MakeUint8Vector(wantUint8, nil)
    98  		proc := testutil.NewProc()
    99  		res, err := TimestampToHour([]*vector.Vector{inVector}, proc)
   100  		convey.So(err, convey.ShouldBeNil)
   101  		compare := testutil.CompareVectors(wantVector, res)
   102  		convey.So(compare, convey.ShouldBeTrue)
   103  	})
   104  	convey.Convey("MinuteOfDayDatetimeCase", t, func() {
   105  
   106  		pairs := []testPair{
   107  			{
   108  				s:    "2004-04-03 10:20:00",
   109  				want: 20,
   110  			},
   111  			{
   112  				s:    "2004-08-03 01:01:37",
   113  				want: 1,
   114  			},
   115  			{
   116  				s:    "2004-01-03",
   117  				want: 0,
   118  			},
   119  		}
   120  
   121  		var inStrs []string
   122  		var wantUint8 []uint8
   123  		for _, k := range pairs {
   124  			inStrs = append(inStrs, k.s)
   125  			wantUint8 = append(wantUint8, k.want)
   126  		}
   127  
   128  		inVector := testutil.MakeDateTimeVector(inStrs, nil)
   129  		wantVector := testutil.MakeUint8Vector(wantUint8, nil)
   130  		proc := testutil.NewProc()
   131  		res, err := DatetimeToMinute([]*vector.Vector{inVector}, proc)
   132  		convey.So(err, convey.ShouldBeNil)
   133  		compare := testutil.CompareVectors(wantVector, res)
   134  		convey.So(compare, convey.ShouldBeTrue)
   135  	})
   136  	convey.Convey("MinuteOfDayTimestampCase", t, func() {
   137  
   138  		pairs := []testPair{
   139  			{
   140  				s:    "2004-04-03 10:20:00",
   141  				want: 20,
   142  			},
   143  			{
   144  				s:    "2004-08-03 01:01:37",
   145  				want: 1,
   146  			},
   147  			{
   148  				s:    "2004-01-03",
   149  				want: 0,
   150  			},
   151  		}
   152  
   153  		var inStrs []string
   154  		var wantUint8 []uint8
   155  		for _, k := range pairs {
   156  			inStrs = append(inStrs, k.s)
   157  			wantUint8 = append(wantUint8, k.want)
   158  		}
   159  
   160  		inVector := testutil.MakeTimeStampVector(inStrs, nil)
   161  		wantVector := testutil.MakeUint8Vector(wantUint8, nil)
   162  		proc := testutil.NewProc()
   163  		res, err := TimestampToMinute([]*vector.Vector{inVector}, proc)
   164  		convey.So(err, convey.ShouldBeNil)
   165  		compare := testutil.CompareVectors(wantVector, res)
   166  		convey.So(compare, convey.ShouldBeTrue)
   167  	})
   168  	convey.Convey("SecondOfDayDatetimeCase", t, func() {
   169  
   170  		pairs := []testPair{
   171  			{
   172  				s:    "2004-04-03 10:20:00",
   173  				want: 0,
   174  			},
   175  			{
   176  				s:    "2004-08-03 01:01:37",
   177  				want: 37,
   178  			},
   179  			{
   180  				s:    "2004-01-03",
   181  				want: 0,
   182  			},
   183  			{
   184  				s:    "2024-04-03 10:20:09",
   185  				want: 9,
   186  			},
   187  		}
   188  
   189  		var inStrs []string
   190  		var wantUint8 []uint8
   191  		for _, k := range pairs {
   192  			inStrs = append(inStrs, k.s)
   193  			wantUint8 = append(wantUint8, k.want)
   194  		}
   195  
   196  		inVector := testutil.MakeDateTimeVector(inStrs, nil)
   197  		wantVector := testutil.MakeUint8Vector(wantUint8, nil)
   198  		proc := testutil.NewProc()
   199  		res, err := DatetimeToSecond([]*vector.Vector{inVector}, proc)
   200  		convey.So(err, convey.ShouldBeNil)
   201  		compare := testutil.CompareVectors(wantVector, res)
   202  		convey.So(compare, convey.ShouldBeTrue)
   203  	})
   204  	convey.Convey("SecondOfDayTimestampCase", t, func() {
   205  
   206  		pairs := []testPair{
   207  			{
   208  				s:    "2004-04-03 10:20:00",
   209  				want: 0,
   210  			},
   211  			{
   212  				s:    "2004-08-03 01:01:37",
   213  				want: 37,
   214  			},
   215  			{
   216  				s:    "2004-01-03",
   217  				want: 0,
   218  			},
   219  			{
   220  				s:    "2024-04-03 10:20:09",
   221  				want: 9,
   222  			},
   223  		}
   224  
   225  		var inStrs []string
   226  		var wantUint8 []uint8
   227  		for _, k := range pairs {
   228  			inStrs = append(inStrs, k.s)
   229  			wantUint8 = append(wantUint8, k.want)
   230  		}
   231  
   232  		inVector := testutil.MakeTimeStampVector(inStrs, nil)
   233  		wantVector := testutil.MakeUint8Vector(wantUint8, nil)
   234  		proc := testutil.NewProc()
   235  		res, err := TimestampToSecond([]*vector.Vector{inVector}, proc)
   236  		convey.So(err, convey.ShouldBeNil)
   237  		compare := testutil.CompareVectors(wantVector, res)
   238  		convey.So(compare, convey.ShouldBeTrue)
   239  	})
   240  	convey.Convey("TimeOfDayCaseScalar", t, func() {
   241  
   242  		hourPairs := testPair{
   243  			s:    "2004-01-03 23:15:08",
   244  			want: 23,
   245  		}
   246  
   247  		minutePairs := testPair{
   248  			s:    "2004-01-03 23:15:08",
   249  			want: 15,
   250  		}
   251  
   252  		secondPairs := testPair{
   253  			s:    "2004-01-03 23:15:08",
   254  			want: 8,
   255  		}
   256  
   257  		//Hour Test
   258  		{
   259  			inVectorDT := testutil.MakeScalarDateTime(hourPairs.s, 10)
   260  			inVectorTS := testutil.MakeScalarTimeStamp(hourPairs.s, 10)
   261  			wantVector := testutil.MakeScalarUint8(hourPairs.want, 10)
   262  			proc := testutil.NewProc()
   263  			{
   264  				res, err := DatetimeToHour([]*vector.Vector{inVectorDT}, proc)
   265  				convey.So(err, convey.ShouldBeNil)
   266  				compare := testutil.CompareVectors(wantVector, res)
   267  				convey.So(compare, convey.ShouldBeTrue)
   268  			}
   269  			{
   270  				res, err := TimestampToHour([]*vector.Vector{inVectorTS}, proc)
   271  				convey.So(err, convey.ShouldBeNil)
   272  				compare := testutil.CompareVectors(wantVector, res)
   273  				convey.So(compare, convey.ShouldBeTrue)
   274  			}
   275  		}
   276  
   277  		//Minute Test
   278  		{
   279  			inVectorDT := testutil.MakeScalarDateTime(minutePairs.s, 10)
   280  			inVectorTS := testutil.MakeScalarTimeStamp(minutePairs.s, 10)
   281  			wantVector := testutil.MakeScalarUint8(minutePairs.want, 10)
   282  			proc := testutil.NewProc()
   283  			{
   284  				res, err := DatetimeToMinute([]*vector.Vector{inVectorDT}, proc)
   285  				convey.So(err, convey.ShouldBeNil)
   286  				compare := testutil.CompareVectors(wantVector, res)
   287  				convey.So(compare, convey.ShouldBeTrue)
   288  			}
   289  			{
   290  				res, err := TimestampToMinute([]*vector.Vector{inVectorTS}, proc)
   291  				convey.So(err, convey.ShouldBeNil)
   292  				compare := testutil.CompareVectors(wantVector, res)
   293  				convey.So(compare, convey.ShouldBeTrue)
   294  			}
   295  		}
   296  
   297  		//Second Test
   298  		{
   299  			inVectorDT := testutil.MakeScalarDateTime(secondPairs.s, 10)
   300  			inVectorTS := testutil.MakeScalarTimeStamp(secondPairs.s, 10)
   301  			wantVector := testutil.MakeScalarUint8(secondPairs.want, 10)
   302  			proc := testutil.NewProc()
   303  			{
   304  				res, err := DatetimeToSecond([]*vector.Vector{inVectorDT}, proc)
   305  				convey.So(err, convey.ShouldBeNil)
   306  				compare := testutil.CompareVectors(wantVector, res)
   307  				convey.So(compare, convey.ShouldBeTrue)
   308  			}
   309  			{
   310  				res, err := TimestampToSecond([]*vector.Vector{inVectorTS}, proc)
   311  				convey.So(err, convey.ShouldBeNil)
   312  				compare := testutil.CompareVectors(wantVector, res)
   313  				convey.So(compare, convey.ShouldBeTrue)
   314  			}
   315  		}
   316  
   317  	})
   318  	convey.Convey("TimeOfDayCaseScalarNull", t, func() {
   319  
   320  		//Hour Test
   321  		{
   322  			inVectorDT := testutil.MakeScalarNull(types.T_datetime, 10)
   323  			inVectorTS := testutil.MakeScalarNull(types.T_timestamp, 10)
   324  			wantVector := testutil.MakeScalarNull(types.T_uint8, 10)
   325  			proc := testutil.NewProc()
   326  			{
   327  				res, err := DatetimeToHour([]*vector.Vector{inVectorDT}, proc)
   328  				convey.So(err, convey.ShouldBeNil)
   329  				compare := testutil.CompareVectors(wantVector, res)
   330  				convey.So(compare, convey.ShouldBeTrue)
   331  			}
   332  			{
   333  				res, err := TimestampToHour([]*vector.Vector{inVectorTS}, proc)
   334  				convey.So(err, convey.ShouldBeNil)
   335  				compare := testutil.CompareVectors(wantVector, res)
   336  				convey.So(compare, convey.ShouldBeTrue)
   337  			}
   338  		}
   339  
   340  		//Minute Test
   341  		{
   342  			inVectorDT := testutil.MakeScalarNull(types.T_datetime, 10)
   343  			inVectorTS := testutil.MakeScalarNull(types.T_timestamp, 10)
   344  			wantVector := testutil.MakeScalarNull(types.T_uint8, 10)
   345  			proc := testutil.NewProc()
   346  			{
   347  				res, err := DatetimeToMinute([]*vector.Vector{inVectorDT}, proc)
   348  				convey.So(err, convey.ShouldBeNil)
   349  				compare := testutil.CompareVectors(wantVector, res)
   350  				convey.So(compare, convey.ShouldBeTrue)
   351  			}
   352  			{
   353  				res, err := TimestampToMinute([]*vector.Vector{inVectorTS}, proc)
   354  				convey.So(err, convey.ShouldBeNil)
   355  				compare := testutil.CompareVectors(wantVector, res)
   356  				convey.So(compare, convey.ShouldBeTrue)
   357  			}
   358  		}
   359  
   360  		//Second Test
   361  		{
   362  			inVectorDT := testutil.MakeScalarNull(types.T_datetime, 10)
   363  			inVectorTS := testutil.MakeScalarNull(types.T_timestamp, 10)
   364  			wantVector := testutil.MakeScalarNull(types.T_uint8, 10)
   365  			proc := testutil.NewProc()
   366  			{
   367  				res, err := DatetimeToSecond([]*vector.Vector{inVectorDT}, proc)
   368  				convey.So(err, convey.ShouldBeNil)
   369  				compare := testutil.CompareVectors(wantVector, res)
   370  				convey.So(compare, convey.ShouldBeTrue)
   371  			}
   372  			{
   373  				res, err := TimestampToSecond([]*vector.Vector{inVectorTS}, proc)
   374  				convey.So(err, convey.ShouldBeNil)
   375  				compare := testutil.CompareVectors(wantVector, res)
   376  				convey.So(compare, convey.ShouldBeTrue)
   377  			}
   378  		}
   379  
   380  	})
   381  }
   382  
   383  type benchmarkTestCase struct {
   384  	flags []bool // flags[i] == true: nullable
   385  	types []types.Type
   386  	proc  *process.Process
   387  }
   388  
   389  var (
   390  	tcs []benchmarkTestCase
   391  )
   392  
   393  func init() {
   394  	tcs = []benchmarkTestCase{
   395  		newTestCase(mpool.MustNewZero(), []bool{false}, []types.Type{{Oid: types.T_datetime}}),
   396  	}
   397  }
   398  
   399  func newTestCase(m *mpool.MPool, flgs []bool, ts []types.Type) benchmarkTestCase {
   400  	return benchmarkTestCase{
   401  		types: ts,
   402  		flags: flgs,
   403  		proc:  testutil.NewProcessWithMPool(m),
   404  	}
   405  }
   406  
   407  // create a new block based on the type information, flags[i] == ture: has null
   408  func newBatch(t *testing.T, flgs []bool, ts []types.Type, proc *process.Process, rows int64) *batch.Batch {
   409  	return testutil.NewBatch(ts, false, int(rows), proc.Mp())
   410  }
   411  
   412  func BenchmarkDatetimeToHour(b *testing.B) {
   413  	t := new(testing.T)
   414  	for i := 0; i < b.N; i++ {
   415  		for _, tc := range tcs {
   416  			bat := newBatch(t, tc.flags, tc.types, tc.proc, Rows)
   417  			vec, err := DatetimeToHour(bat.Vecs, tc.proc)
   418  			require.NoError(t, err)
   419  			bat.Clean(tc.proc.Mp())
   420  			vec.Free(tc.proc.Mp())
   421  			require.Equal(t, int64(0), tc.proc.Mp().Stats().NumCurrBytes.Load())
   422  		}
   423  	}
   424  }