github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/plan/function/operator/case_when_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/matrixorigin/matrixone/pkg/vm/process"
    25  	"github.com/stretchr/testify/require"
    26  )
    27  
    28  type arg struct {
    29  	info   string
    30  	proc   *process.Process
    31  	vs     []*vector.Vector
    32  	match  bool // if false, the case shouldn't meet the function requirement
    33  	err    bool
    34  	expect *vector.Vector
    35  }
    36  
    37  func TestCwFn1(t *testing.T) {
    38  	testCases := []arg{
    39  		{
    40  			info: "when a = 1 then 1, when a = 2 then 2, else 3", proc: testutil.NewProc(),
    41  			vs: []*vector.Vector{
    42  				testutil.MakeBoolVector([]bool{true, true, false, false, false}),  // a = 1
    43  				testutil.MakeScalarInt64(1, 5),                                    // 1
    44  				testutil.MakeBoolVector([]bool{false, false, false, true, false}), // a = 2
    45  				testutil.MakeScalarInt64(2, 5),                                    // 2
    46  				testutil.MakeScalarInt64(3, 5),                                    // 3
    47  			},
    48  			match:  true,
    49  			err:    false,
    50  			expect: testutil.MakeInt64Vector([]int64{1, 1, 3, 2, 3}, nil),
    51  		},
    52  
    53  		{
    54  			info: "when a = 1 then 1, when a = 2 then 2, else null", proc: testutil.NewProc(),
    55  			vs: []*vector.Vector{
    56  				testutil.MakeBoolVector([]bool{false, false, false, false}), // a = 1
    57  				testutil.MakeScalarInt64(1, 4),                              // 1
    58  				testutil.MakeBoolVector([]bool{true, false, false, false}),  // a = 2
    59  				testutil.MakeScalarInt64(2, 4),                              // 2
    60  				testutil.MakeScalarNull(types.T_int64, 4),
    61  			},
    62  			match:  true,
    63  			err:    false,
    64  			expect: testutil.MakeInt64Vector([]int64{2, 0, 0, 0}, []uint64{1, 2, 3}),
    65  		},
    66  
    67  		{
    68  			info: "when a = 1 then 1, when a = 2 then 2", proc: testutil.NewProc(),
    69  			vs: []*vector.Vector{
    70  				testutil.MakeBoolVector([]bool{false, false, false, false}), // a = 1
    71  				testutil.MakeScalarInt64(1, 4),                              // 1
    72  				testutil.MakeBoolVector([]bool{true, false, false, false}),  // a = 2
    73  				testutil.MakeScalarInt64(2, 4),                              // 2
    74  			},
    75  			match:  true,
    76  			err:    false,
    77  			expect: testutil.MakeInt64Vector([]int64{2, 0, 0, 0}, []uint64{1, 2, 3}),
    78  		},
    79  
    80  		{
    81  			info: "when a = 1 then c1, when a = 2 then c2", proc: testutil.NewProc(),
    82  			vs: []*vector.Vector{
    83  				testutil.MakeBoolVector([]bool{true, true, false, false, false}),    // a = 1
    84  				testutil.MakeInt64Vector([]int64{1, 0, 3, 4, 5}, []uint64{1}),       // 1, null, 3, 4, 5
    85  				testutil.MakeBoolVector([]bool{false, false, true, true, false}),    // a = 2
    86  				testutil.MakeInt64Vector([]int64{0, 0, 0, 0, 0}, []uint64{1, 2, 3}), // 0, null, null, null, 0
    87  			},
    88  			match:  true,
    89  			err:    false,
    90  			expect: testutil.MakeInt64Vector([]int64{1, 0, 0, 0, 0}, []uint64{1, 2, 3, 4}), // 1, null, null, null, null
    91  		},
    92  
    93  		{
    94  			info: "when a = 1 then c1, when a = 2 then c2", proc: testutil.NewProc(),
    95  			vs: []*vector.Vector{
    96  				testutil.MakeBoolVector([]bool{true, true, false, false, false}),    // a = 1
    97  				testutil.MakeInt64Vector([]int64{1, 0, 3, 4, 5}, []uint64{1}),       // 1, null, 3, 4, 5
    98  				testutil.MakeBoolVector([]bool{false, false, true, true, false}),    // a = 2
    99  				testutil.MakeInt64Vector([]int64{0, 0, 0, 0, 0}, []uint64{1, 2, 3}), // 0, null, null, null, 0
   100  			},
   101  			match:  true,
   102  			err:    false,
   103  			expect: testutil.MakeInt64Vector([]int64{1, 0, 0, 0, 0}, []uint64{1, 2, 3, 4}), // 1, null, null, null, null
   104  		},
   105  
   106  		{
   107  			info: "when a = 1 then c1, when a = 2 then c2, else null", proc: testutil.NewProc(),
   108  			vs: []*vector.Vector{
   109  				testutil.MakeBoolVector([]bool{true, true, false, false, false}),    // a = 1
   110  				testutil.MakeInt64Vector([]int64{1, 0, 3, 4, 5}, []uint64{1}),       // 1, null, 3, 4, 5
   111  				testutil.MakeBoolVector([]bool{false, false, true, true, false}),    // a = 2
   112  				testutil.MakeInt64Vector([]int64{0, 0, 0, 0, 0}, []uint64{1, 2, 3}), // 0, null, null, null, 0
   113  			},
   114  			match:  true,
   115  			err:    false,
   116  			expect: testutil.MakeInt64Vector([]int64{1, 0, 0, 0, 0}, []uint64{1, 2, 3, 4}), // 1, null, null, null, null
   117  		},
   118  
   119  		{
   120  			info: "when a = 1 then c1, when a = 2 then c2, else c3", proc: testutil.NewProc(),
   121  			vs: []*vector.Vector{
   122  				testutil.MakeBoolVector([]bool{true, true, false, false, false}),      // a = 1
   123  				testutil.MakeInt64Vector([]int64{1, 0, 3, 4, 5}, []uint64{1}),         // 1, null, 3, 4, 5
   124  				testutil.MakeBoolVector([]bool{false, false, true, true, false}),      // a = 2
   125  				testutil.MakeInt64Vector([]int64{0, 0, 0, 0, 0}, []uint64{1, 2, 3}),   // 0, null, null, null, 0
   126  				testutil.MakeInt64Vector([]int64{100, 200, 300, 0, 500}, []uint64{3}), // 100, 200, 300, null, 500
   127  			},
   128  			match:  true,
   129  			err:    false,
   130  			expect: testutil.MakeInt64Vector([]int64{1, 0, 0, 0, 500}, []uint64{1, 2, 3}), // 1, null, null, null, 500
   131  		},
   132  
   133  		{
   134  			info: "when true then c1, when false then c2, else null", proc: testutil.NewProc(),
   135  			vs: []*vector.Vector{
   136  				testutil.MakeScalarBool(true, 4),
   137  				testutil.MakeInt64Vector([]int64{1, 2, 3, 4}, nil), // 1, 2, 3, 4
   138  				testutil.MakeScalarBool(false, 4),
   139  				testutil.MakeInt64Vector([]int64{4, 3, 2, 1}, nil),
   140  				testutil.MakeScalarNull(types.T_int64, 4),
   141  			},
   142  			match:  true,
   143  			err:    false,
   144  			expect: testutil.MakeInt64Vector([]int64{1, 2, 3, 4}, nil), // 1, 2, 3, 4
   145  		},
   146  
   147  		{
   148  			info: "when true then 1, when false then 2, else null", proc: testutil.NewProc(),
   149  			vs: []*vector.Vector{
   150  				testutil.MakeScalarBool(true, 4),
   151  				testutil.MakeScalarInt64(1, 4),
   152  				testutil.MakeScalarBool(false, 4),
   153  				testutil.MakeScalarInt64(2, 4),
   154  				testutil.MakeScalarNull(types.T_int64, 4),
   155  			},
   156  			match:  true,
   157  			err:    false,
   158  			expect: testutil.MakeScalarInt64(1, 4),
   159  		},
   160  
   161  		{
   162  			info: "when a = 1 then 10, when a = 2 then true, else null", proc: testutil.NewProc(),
   163  			vs: []*vector.Vector{
   164  				testutil.MakeBoolVector([]bool{false, false, false, false}),
   165  				testutil.MakeScalarInt64(10, 4),
   166  				testutil.MakeBoolVector([]bool{false, false, false, false}),
   167  				testutil.MakeScalarBool(true, 4),
   168  				testutil.MakeScalarNull(types.T_bool, 4),
   169  			},
   170  			match: false,
   171  		},
   172  
   173  		{
   174  			// special case 1
   175  			info: "when a = 1 then 1, when a = 1 then 2, else null", proc: testutil.NewProc(),
   176  			vs: []*vector.Vector{
   177  				testutil.MakeBoolVector([]bool{true, true, false, false}),
   178  				testutil.MakeScalarInt64(1, 4),
   179  				testutil.MakeBoolVector([]bool{false, true, true, false}),
   180  				testutil.MakeScalarInt64(2, 4),
   181  				testutil.MakeScalarNull(types.T_int64, 4),
   182  			},
   183  			match:  true,
   184  			err:    false,
   185  			expect: testutil.MakeInt64Vector([]int64{1, 1, 2, 0}, []uint64{3}),
   186  		},
   187  
   188  		{
   189  			// special case 2
   190  			info: "when true then null else null", proc: testutil.NewProc(),
   191  			vs: []*vector.Vector{
   192  				testutil.MakeScalarBool(true, 5),
   193  				testutil.MakeScalarNull(types.T_any, 5),
   194  				testutil.MakeScalarNull(types.T_any, 5),
   195  			},
   196  			match:  true,
   197  			err:    false,
   198  			expect: testutil.MakeScalarNull(types.T_any, 5),
   199  		},
   200  	}
   201  
   202  	for i, tc := range testCases {
   203  		t.Run(tc.info, func(t *testing.T) {
   204  			{
   205  				inputTypes := make([]types.T, len(tc.vs))
   206  				for i := range inputTypes {
   207  					inputTypes[i] = tc.vs[i].Typ.Oid
   208  				}
   209  				b := CwTypeCheckFn(inputTypes, nil, types.T_int64)
   210  				if !tc.match {
   211  					require.False(t, b, fmt.Sprintf("case '%s' shouldn't meet the function's requirement but it meets.", tc.info))
   212  					return
   213  				}
   214  				require.True(t, b)
   215  			}
   216  
   217  			got, ergot := cwGeneral[int64](tc.vs, tc.proc, types.Type{Oid: types.T_int64})
   218  			if tc.err {
   219  				require.Errorf(t, ergot, fmt.Sprintf("case '%d' expected error, but no error happens", i))
   220  			} else {
   221  				require.NoError(t, ergot)
   222  				require.True(t, testutil.CompareVectors(tc.expect, got), "got vector is different with expected")
   223  			}
   224  		})
   225  	}
   226  }