github.com/dolthub/go-mysql-server@v0.18.0/sql/expression/function/extract_test.go (about)

     1  // Copyright 2023 Dolthub, Inc.
     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 function
    16  
    17  import (
    18  	"testing"
    19  
    20  	"github.com/stretchr/testify/require"
    21  
    22  	"github.com/dolthub/go-mysql-server/sql"
    23  	"github.com/dolthub/go-mysql-server/sql/expression"
    24  	"github.com/dolthub/go-mysql-server/sql/types"
    25  )
    26  
    27  func TestExtract(t *testing.T) {
    28  	testCases := []struct {
    29  		name     string
    30  		unit     string
    31  		dateTime string
    32  		expected interface{}
    33  		skip     bool
    34  	}{
    35  		{
    36  			name:     "get year",
    37  			unit:     "YEAR",
    38  			dateTime: "2023-11-12 11:22:33.445566",
    39  			expected: 2023,
    40  		},
    41  		{
    42  			name:     "get quarter 1",
    43  			unit:     "QUARTER",
    44  			dateTime: "2023-3-12 11:22:33.445566",
    45  			expected: 1,
    46  		},
    47  		{
    48  			name:     "get quarter 2",
    49  			unit:     "QUARTER",
    50  			dateTime: "2023-6-12 11:22:33.445566",
    51  			expected: 2,
    52  		},
    53  		{
    54  			name:     "get quarter 3",
    55  			unit:     "QUARTER",
    56  			dateTime: "2023-9-12 11:22:33.445566",
    57  			expected: 3,
    58  		},
    59  		{
    60  			name:     "get quarter 4",
    61  			unit:     "QUARTER",
    62  			dateTime: "2023-11-12 11:22:33.445566",
    63  			expected: 4,
    64  		},
    65  		{
    66  			name:     "get month",
    67  			unit:     "MONTH",
    68  			dateTime: "2023-11-12 11:22:33.445566",
    69  			expected: 11,
    70  		},
    71  		{
    72  			name:     "get week",
    73  			unit:     "WEEK",
    74  			dateTime: "2023-11-12 11:22:33.445566",
    75  			expected: 46,
    76  		},
    77  		{
    78  			name:     "get day",
    79  			unit:     "DAY",
    80  			dateTime: "2023-11-12 11:22:33.445566",
    81  			expected: 12,
    82  		},
    83  		{
    84  			name:     "get hour",
    85  			unit:     "HOUR",
    86  			dateTime: "2023-11-12 11:22:33.445566",
    87  			expected: 11,
    88  		},
    89  		{
    90  			name:     "get minute",
    91  			unit:     "MINUTE",
    92  			dateTime: "2023-11-12 11:22:33.445566",
    93  			expected: 22,
    94  		},
    95  		{
    96  			name:     "get second",
    97  			unit:     "SECOND",
    98  			dateTime: "2023-11-12 11:22:33.445566",
    99  			expected: 33,
   100  		},
   101  		{
   102  			name:     "get microsecond",
   103  			unit:     "MICROSECOND",
   104  			dateTime: "2023-11-12 11:22:33.445566",
   105  			expected: 445566,
   106  		},
   107  		{
   108  			name:     "get year_month",
   109  			unit:     "YEAR_MONTH",
   110  			dateTime: "2023-11-12 11:22:33.445566",
   111  			expected: 202311,
   112  		},
   113  		{
   114  			name:     "get day_hour",
   115  			unit:     "DAY_HOUR",
   116  			dateTime: "2023-11-12 11:22:33.445566",
   117  			expected: 1211,
   118  		},
   119  		{
   120  			name:     "get day_minute",
   121  			unit:     "DAY_MINUTE",
   122  			dateTime: "2023-11-12 11:22:33.445566",
   123  			expected: 121122,
   124  		},
   125  		{
   126  			name:     "get day_second",
   127  			unit:     "DAY_SECOND",
   128  			dateTime: "2023-11-12 11:22:33.445566",
   129  			expected: 12112233,
   130  		},
   131  		{
   132  			name:     "get day_microsecond",
   133  			unit:     "DAY_MICROSECOND",
   134  			dateTime: "2023-11-12 11:22:33.445566",
   135  			expected: 12112233445566,
   136  		},
   137  		{
   138  			name:     "get hour_minute",
   139  			unit:     "HOUR_MINUTE",
   140  			dateTime: "2023-11-12 11:22:33.445566",
   141  			expected: 1122,
   142  		},
   143  		{
   144  			name:     "get hour_second",
   145  			unit:     "HOUR_SECOND",
   146  			dateTime: "2023-11-12 11:22:33.445566",
   147  			expected: 112233,
   148  		},
   149  		{
   150  			name:     "get hour_microsecond",
   151  			unit:     "HOUR_MICROSECOND",
   152  			dateTime: "2023-11-12 11:22:33.445566",
   153  			expected: 112233445566,
   154  		},
   155  		{
   156  			name:     "get minute_second",
   157  			unit:     "MINUTE_SECOND",
   158  			dateTime: "2023-11-12 11:22:33.445566",
   159  			expected: 2233,
   160  		},
   161  		{
   162  			name:     "get minute_microsecond",
   163  			unit:     "MINUTE_MICROSECOND",
   164  			dateTime: "2023-11-12 11:22:33.445566",
   165  			expected: 2233445566,
   166  		},
   167  		{
   168  			name:     "get second_microsecond",
   169  			unit:     "SECOND_MICROSECOND",
   170  			dateTime: "2023-11-12 11:22:33.445566",
   171  			expected: 33445566,
   172  		},
   173  		{
   174  			name:     "get month 0",
   175  			unit:     "MONTH",
   176  			dateTime: "2023-00-12 11:22:33.445566",
   177  			expected: 0,
   178  			skip:     true,
   179  		},
   180  		{
   181  			name:     "get quarter 0",
   182  			unit:     "QUARTER",
   183  			dateTime: "2023-00-12 11:22:33.445566",
   184  			expected: 0,
   185  			skip:     true,
   186  		},
   187  		{
   188  			name:     "get day 0",
   189  			unit:     "DAY",
   190  			dateTime: "2023-01-00 11:22:33.445566",
   191  			expected: 0,
   192  			skip:     true,
   193  		},
   194  	}
   195  
   196  	for _, tt := range testCases {
   197  		t.Run(tt.name, func(t *testing.T) {
   198  			if tt.skip {
   199  				t.Skip()
   200  			}
   201  			require := require.New(t)
   202  			f := NewExtract(expression.NewLiteral(tt.unit, types.LongText), expression.NewLiteral(tt.dateTime, types.LongText))
   203  			v, err := f.Eval(sql.NewEmptyContext(), nil)
   204  			require.NoError(err)
   205  			require.Equal(tt.expected, v)
   206  		})
   207  	}
   208  
   209  	t.Run("test extract null datetime", func(t *testing.T) {
   210  		require := require.New(t)
   211  		f := NewExtract(expression.NewLiteral("DAY", types.LongText), expression.NewLiteral(nil, types.Null))
   212  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   213  		require.NoError(err)
   214  		require.Equal(nil, v)
   215  	})
   216  
   217  	t.Run("test extract null units", func(t *testing.T) {
   218  		require := require.New(t)
   219  		f := NewExtract(expression.NewLiteral(nil, types.Null), expression.NewLiteral("2023-11-12 11:22:33.445566", types.LongText))
   220  		v, err := f.Eval(sql.NewEmptyContext(), nil)
   221  		require.NoError(err)
   222  		require.Equal(nil, v)
   223  	})
   224  
   225  	t.Run("test bad date", func(t *testing.T) {
   226  		require := require.New(t)
   227  		f := NewExtract(expression.NewLiteral("DAY", types.LongText), expression.NewLiteral("thisisnotadate", types.LongText))
   228  		ctx := sql.NewEmptyContext()
   229  		_, err := f.Eval(ctx, nil)
   230  		require.NoError(err)
   231  		require.Equal(1, len(ctx.Warnings()))
   232  		require.Equal(1292, ctx.Warnings()[0].Code)
   233  	})
   234  }