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 }