github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/plan/function/operator/coalesce_test.go (about)

     1  // Copyright 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 operator
    16  
    17  import (
    18  	"fmt"
    19  	"testing"
    20  
    21  	"github.com/matrixorigin/matrixone/pkg/container/types"
    22  	"github.com/matrixorigin/matrixone/pkg/container/vector"
    23  	"github.com/matrixorigin/matrixone/pkg/testutil"
    24  	"github.com/stretchr/testify/require"
    25  )
    26  
    27  func TestCoalesceGeneral(t *testing.T) {
    28  	testCases := []arg{
    29  		{
    30  			info: "coalesce(null, 1)", proc: testutil.NewProc(),
    31  			vs: []*vector.Vector{
    32  				testutil.MakeScalarNull(types.T_any, 1),
    33  				testutil.MakeScalarInt64(1, 1),
    34  			},
    35  			match:  true,
    36  			err:    false,
    37  			expect: testutil.MakeScalarInt64(1, 1),
    38  		},
    39  
    40  		{
    41  			info: "coalesce(null, 1, null, 3)", proc: testutil.NewProc(),
    42  			vs: []*vector.Vector{
    43  				testutil.MakeScalarNull(types.T_any, 1),
    44  				testutil.MakeScalarInt64(1, 1),
    45  				testutil.MakeScalarNull(types.T_any, 1),
    46  				testutil.MakeScalarInt64(1, 3),
    47  			},
    48  			match:  true,
    49  			err:    false,
    50  			expect: testutil.MakeScalarInt64(1, 1),
    51  		},
    52  
    53  		{
    54  			info: "coalesce(a, 1, null, 3)", proc: testutil.NewProc(),
    55  			vs: []*vector.Vector{
    56  				testutil.MakeInt64Vector([]int64{1, 0, 3, 0}, []uint64{1, 3}),
    57  				testutil.MakeScalarInt64(1, 1),
    58  				testutil.MakeScalarNull(types.T_any, 1),
    59  				testutil.MakeScalarInt64(1, 3),
    60  			},
    61  			match:  true,
    62  			err:    false,
    63  			expect: testutil.MakeInt64Vector([]int64{1, 1, 3, 1}, nil),
    64  		},
    65  
    66  		{
    67  			info: "coalesce(a, null, b)", proc: testutil.NewProc(),
    68  			vs: []*vector.Vector{
    69  				testutil.MakeInt64Vector([]int64{1, 0, 3, 0}, []uint64{1, 3}),
    70  				testutil.MakeScalarNull(types.T_any, 1),
    71  				testutil.MakeInt64Vector([]int64{1, 11, 3, 0}, []uint64{3}),
    72  			},
    73  			match:  true,
    74  			err:    false,
    75  			expect: testutil.MakeInt64Vector([]int64{1, 11, 3, 0}, []uint64{3}),
    76  		},
    77  
    78  		{
    79  			info: "coalesce(a, null, 33)", proc: testutil.NewProc(),
    80  			vs: []*vector.Vector{
    81  				testutil.MakeInt64Vector([]int64{1, 0, 3, 0}, []uint64{1, 3}),
    82  				testutil.MakeScalarNull(types.T_any, 1),
    83  				testutil.MakeScalarInt64(33, 4),
    84  			},
    85  			match:  true,
    86  			err:    false,
    87  			expect: testutil.MakeInt64Vector([]int64{1, 33, 3, 33}, nil),
    88  		},
    89  	}
    90  
    91  	for i, tc := range testCases {
    92  		t.Run(tc.info, func(t *testing.T) {
    93  			{
    94  				inputTypes := make([]types.T, len(tc.vs))
    95  				for i := range inputTypes {
    96  					inputTypes[i] = tc.vs[i].Typ.Oid
    97  				}
    98  				b := CoalesceTypeCheckFn(inputTypes, nil, types.T_int64)
    99  				if !tc.match {
   100  					require.False(t, b, fmt.Sprintf("case '%s' shouldn't meet the function's requirement but it meets.", tc.info))
   101  					return
   102  				}
   103  				require.True(t, b)
   104  			}
   105  
   106  			got, ergot := coalesceGeneral[int64](tc.vs, tc.proc, types.Type{Oid: types.T_int64})
   107  			if tc.err {
   108  				require.Errorf(t, ergot, fmt.Sprintf("case '%d' expected error, but no error happens", i))
   109  			} else {
   110  				require.NoError(t, ergot)
   111  				require.True(t, testutil.CompareVectors(tc.expect, got), "got vector is different with expected")
   112  			}
   113  		})
   114  	}
   115  }
   116  
   117  func TestCoalesceString(t *testing.T) {
   118  	testCases := []arg{
   119  		{
   120  			info: "coalesce(null, 'a', null, 'b')", proc: testutil.NewProc(),
   121  			vs: []*vector.Vector{
   122  				testutil.MakeScalarNull(types.T_any, 1),
   123  				testutil.MakeScalarVarchar("a", 1),
   124  				testutil.MakeScalarNull(types.T_any, 1),
   125  				testutil.MakeScalarVarchar("b", 1),
   126  			},
   127  			match:  true,
   128  			err:    false,
   129  			expect: testutil.MakeScalarVarchar("a", 1),
   130  		},
   131  
   132  		{
   133  			info: "coalesce(a, 'a')", proc: testutil.NewProc(),
   134  			vs: []*vector.Vector{
   135  				testutil.MakeVarcharVector([]string{"x", "y", "z"}, nil),
   136  				testutil.MakeScalarVarchar("a", 1),
   137  			},
   138  			match:  true,
   139  			err:    false,
   140  			expect: testutil.MakeVarcharVector([]string{"x", "y", "z"}, nil),
   141  		},
   142  
   143  		{
   144  			info: "coalesce(a, 'a', null, 'b')", proc: testutil.NewProc(),
   145  			vs: []*vector.Vector{
   146  				testutil.MakeVarcharVector([]string{"kk", "", "ss", ""}, []uint64{1, 3}),
   147  				testutil.MakeScalarVarchar("a", 1),
   148  				testutil.MakeScalarNull(types.T_any, 1),
   149  				testutil.MakeScalarVarchar("b", 1),
   150  			},
   151  			match:  true,
   152  			err:    false,
   153  			expect: testutil.MakeVarcharVector([]string{"kk", "a", "ss", "a"}, nil),
   154  		},
   155  
   156  		{
   157  			info: "coalesce(a, null, 'b')", proc: testutil.NewProc(),
   158  			vs: []*vector.Vector{
   159  				testutil.MakeVarcharVector([]string{"kk", "", "ss", ""}, []uint64{1, 3}),
   160  				testutil.MakeScalarNull(types.T_any, 1),
   161  				testutil.MakeScalarVarchar("b", 1),
   162  			},
   163  			match:  true,
   164  			err:    false,
   165  			expect: testutil.MakeVarcharVector([]string{"kk", "b", "ss", "b"}, nil),
   166  		},
   167  
   168  		{
   169  			info: "coalesce(a, null, b)", proc: testutil.NewProc(),
   170  			vs: []*vector.Vector{
   171  				testutil.MakeVarcharVector([]string{"a1", "", "a2", ""}, []uint64{1, 3}),
   172  				testutil.MakeScalarNull(types.T_any, 1),
   173  				testutil.MakeVarcharVector([]string{"b1", "b2", "", ""}, []uint64{2, 3}),
   174  			},
   175  			match:  true,
   176  			err:    false,
   177  			expect: testutil.MakeVarcharVector([]string{"a1", "b2", "a2", ""}, []uint64{3}),
   178  		},
   179  	}
   180  
   181  	for i, tc := range testCases {
   182  		t.Run(tc.info, func(t *testing.T) {
   183  			{
   184  				inputTypes := make([]types.T, len(tc.vs))
   185  				for i := range inputTypes {
   186  					inputTypes[i] = tc.vs[i].Typ.Oid
   187  				}
   188  				b := CoalesceTypeCheckFn(inputTypes, nil, types.T_varchar)
   189  				if !tc.match {
   190  					require.False(t, b, fmt.Sprintf("case '%s' shouldn't meet the function's requirement but it meets.", tc.info))
   191  					return
   192  				}
   193  				require.True(t, b)
   194  			}
   195  
   196  			got, ergot := coalesceString(tc.vs, tc.proc, types.Type{Oid: types.T_varchar, Width: types.MaxVarcharLen})
   197  			if tc.err {
   198  				require.Errorf(t, ergot, fmt.Sprintf("case '%d' expected error, but no error happens", i))
   199  			} else {
   200  				require.NoError(t, ergot)
   201  				require.True(t, testutil.CompareVectors(tc.expect, got), "got vector is different with expected")
   202  			}
   203  		})
   204  	}
   205  }