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

     1  // Copyright 2020-2021 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/shopspring/decimal"
    21  	"github.com/stretchr/testify/require"
    22  
    23  	"github.com/dolthub/go-mysql-server/sql"
    24  	"github.com/dolthub/go-mysql-server/sql/expression"
    25  	"github.com/dolthub/go-mysql-server/sql/types"
    26  )
    27  
    28  func TestEmptyCoalesce(t *testing.T) {
    29  	_, err := NewCoalesce()
    30  	require.True(t, sql.ErrInvalidArgumentNumber.Is(err))
    31  }
    32  
    33  func TestCoalesce(t *testing.T) {
    34  	testCases := []struct {
    35  		name     string
    36  		input    []sql.Expression
    37  		expected interface{}
    38  		typ      sql.Type
    39  		nullable bool
    40  	}{
    41  		{
    42  			name: "coalesce(1, 2, 3)",
    43  			input: []sql.Expression{
    44  				expression.NewLiteral(1, types.Int32),
    45  				expression.NewLiteral(2, types.Int32),
    46  				expression.NewLiteral(3, types.Int32),
    47  			},
    48  			expected: 1,
    49  			typ:      types.Int32,
    50  			nullable: false,
    51  		},
    52  		{
    53  			name: "coalesce(NULL, NULL, 3)",
    54  			input: []sql.Expression{
    55  				nil,
    56  				nil,
    57  				expression.NewLiteral(3, types.Int32),
    58  			},
    59  			expected: 3,
    60  			typ:      types.Int32,
    61  			nullable: false,
    62  		},
    63  		{
    64  			name: "coalesce(NULL, NULL, '3')",
    65  			input: []sql.Expression{
    66  				nil,
    67  				nil,
    68  				expression.NewLiteral("3", types.LongText),
    69  			},
    70  			expected: "3",
    71  			typ:      types.LongText,
    72  			nullable: false,
    73  		},
    74  		{
    75  			name: "coalesce(NULL, '2', 3)",
    76  			input: []sql.Expression{
    77  				nil,
    78  				expression.NewLiteral("2", types.LongText),
    79  				expression.NewLiteral(3, types.Int32),
    80  			},
    81  			expected: "2",
    82  			typ:      types.LongText,
    83  			nullable: false,
    84  		},
    85  		{
    86  			name: "coalesce(NULL, NULL, NULL)",
    87  			input: []sql.Expression{
    88  				nil,
    89  				nil,
    90  				nil,
    91  			},
    92  			expected: nil,
    93  			typ:      types.Null,
    94  			nullable: true,
    95  		},
    96  		{
    97  			name: "coalesce(int(1), decimal(2.0), string('3'))",
    98  			input: []sql.Expression{
    99  				expression.NewLiteral(1, types.Int32),
   100  				expression.NewLiteral(decimal.NewFromFloat(2.0), types.MustCreateDecimalType(10, 0)),
   101  				expression.NewLiteral("3", types.LongText),
   102  			},
   103  			expected: 1,
   104  			typ:      types.LongText,
   105  			nullable: false,
   106  		},
   107  		{
   108  			name: "coalesce(signed(1), unsigned(2))",
   109  			input: []sql.Expression{
   110  				expression.NewLiteral(1, types.Int32),
   111  				expression.NewLiteral(2, types.Uint32),
   112  			},
   113  			expected: 1,
   114  			typ:      types.MustCreateDecimalType(20, 0),
   115  			nullable: false,
   116  		},
   117  		{
   118  			name: "coalesce(signed(1), unsigned(2))",
   119  			input: []sql.Expression{
   120  				expression.NewLiteral(1, types.Int32),
   121  				expression.NewLiteral(2, types.Uint32),
   122  			},
   123  			expected: 1,
   124  			typ:      types.MustCreateDecimalType(20, 0),
   125  			nullable: false,
   126  		},
   127  		{
   128  			name: "coalesce(decimal(1.0), float64(2.0))",
   129  			input: []sql.Expression{
   130  				expression.NewLiteral(1, types.MustCreateDecimalType(10, 0)),
   131  				expression.NewLiteral(2, types.Float64),
   132  			},
   133  			expected: 1,
   134  			typ:      types.Float64,
   135  			nullable: false,
   136  		},
   137  		{
   138  			name: "coalesce(float64(2.0))",
   139  			input: []sql.Expression{
   140  				expression.NewLiteral(2, types.Float64),
   141  			},
   142  			expected: 2,
   143  			typ:      types.Float64,
   144  			nullable: false,
   145  		},
   146  		{
   147  			name: "coalesce(1, float64(2.0))",
   148  			input: []sql.Expression{
   149  				expression.NewLiteral(1, types.Float64),
   150  			},
   151  			expected: 1,
   152  			typ:      types.Float64,
   153  			nullable: false,
   154  		},
   155  	}
   156  
   157  	for _, tt := range testCases {
   158  		c, err := NewCoalesce(tt.input...)
   159  		require.NoError(t, err)
   160  
   161  		require.Equal(t, tt.typ, c.Type())
   162  		require.Equal(t, tt.nullable, c.IsNullable())
   163  		v, err := c.Eval(sql.NewEmptyContext(), nil)
   164  		require.NoError(t, err)
   165  		require.Equal(t, tt.expected, v)
   166  	}
   167  }
   168  
   169  func TestComposeCoalasce(t *testing.T) {
   170  	ctx := sql.NewEmptyContext()
   171  	c1, err := NewCoalesce(nil)
   172  	require.NoError(t, err)
   173  	require.Equal(t, types.Null, c1.Type())
   174  	v, err := c1.Eval(ctx, nil)
   175  	require.NoError(t, err)
   176  	require.Equal(t, nil, v)
   177  
   178  	c2, err := NewCoalesce(nil, expression.NewLiteral(1, types.Int32))
   179  	require.NoError(t, err)
   180  	require.Equal(t, types.Int32, c2.Type())
   181  	v, err = c2.Eval(ctx, nil)
   182  	require.NoError(t, err)
   183  	require.Equal(t, 1, v)
   184  
   185  	c3, err := NewCoalesce(nil, c1, c2)
   186  	require.NoError(t, err)
   187  	require.Equal(t, types.Int32, c3.Type())
   188  	v, err = c3.Eval(ctx, nil)
   189  	require.NoError(t, err)
   190  	require.Equal(t, 1, v)
   191  
   192  	c4, err := NewCoalesce(expression.NewLiteral(nil, types.Null), c1, c2)
   193  	require.NoError(t, err)
   194  	require.Equal(t, types.Int32, c4.Type())
   195  	v, err = c4.Eval(ctx, nil)
   196  	require.NoError(t, err)
   197  	require.Equal(t, 1, v)
   198  }