github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/colexec/preinsert/preinsert_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 preinsert 16 17 import ( 18 "context" 19 "fmt" 20 "testing" 21 "time" 22 23 "github.com/golang/mock/gomock" 24 "github.com/matrixorigin/matrixone/pkg/container/batch" 25 "github.com/matrixorigin/matrixone/pkg/container/types" 26 "github.com/matrixorigin/matrixone/pkg/container/vector" 27 mock_frontend "github.com/matrixorigin/matrixone/pkg/frontend/test" 28 "github.com/matrixorigin/matrixone/pkg/pb/plan" 29 "github.com/matrixorigin/matrixone/pkg/sql/colexec/value_scan" 30 "github.com/matrixorigin/matrixone/pkg/testutil" 31 "github.com/matrixorigin/matrixone/pkg/vm" 32 "github.com/matrixorigin/matrixone/pkg/vm/engine" 33 "github.com/stretchr/testify/require" 34 ) 35 36 var ( 37 i64typ = plan.Type{Id: int32(types.T_int64)} 38 varchartyp = plan.Type{Id: int32(types.T_varchar)} 39 ) 40 41 func TestPreInsertNormal(t *testing.T) { 42 ctrl := gomock.NewController(t) 43 defer ctrl.Finish() 44 45 ctx := context.TODO() 46 txnOperator := mock_frontend.NewMockTxnOperator(ctrl) 47 txnOperator.EXPECT().Commit(gomock.Any()).Return(nil).AnyTimes() 48 txnOperator.EXPECT().Rollback(ctx).Return(nil).AnyTimes() 49 50 txnClient := mock_frontend.NewMockTxnClient(ctrl) 51 txnClient.EXPECT().New(gomock.Any(), gomock.Any()).Return(txnOperator, nil).AnyTimes() 52 53 eng := mock_frontend.NewMockEngine(ctrl) 54 eng.EXPECT().New(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() 55 eng.EXPECT().Hints().Return(engine.Hints{ 56 CommitOrRollbackTimeout: time.Second, 57 }).AnyTimes() 58 59 proc := testutil.NewProc() 60 proc.TxnClient = txnClient 61 proc.SessionInfo.StorageEngine = eng 62 batch1 := &batch.Batch{ 63 Vecs: []*vector.Vector{ 64 testutil.MakeInt64Vector([]int64{1, 2, 0}, []uint64{3}), 65 testutil.MakeScalarInt64(3, 3), 66 testutil.MakeVarcharVector([]string{"a", "b", "c"}, nil), 67 testutil.MakeScalarVarchar("d", 3), 68 testutil.MakeScalarNull(types.T_int64, 3), 69 }, 70 Cnt: 1, 71 } 72 batch1.SetRowCount(3) 73 argument1 := Argument{ 74 SchemaName: "testDb", 75 TableDef: &plan.TableDef{ 76 Cols: []*plan.ColDef{ 77 {Name: "int64_column", Typ: i64typ}, 78 {Name: "scalar_int64", Typ: i64typ}, 79 {Name: "varchar_column", Typ: varchartyp}, 80 {Name: "scalar_varchar", Typ: varchartyp}, 81 {Name: "int64_column", Typ: i64typ}, 82 }, 83 Pkey: &plan.PrimaryKeyDef{}, 84 }, 85 Attrs: []string{"int64_column", "scalar_int64", "varchar_column", "scalar_varchar", "int64_column"}, 86 IsUpdate: false, 87 HasAutoCol: false, 88 OperatorBase: vm.OperatorBase{ 89 OperatorInfo: vm.OperatorInfo{ 90 Idx: 0, 91 IsFirst: false, 92 IsLast: false, 93 }, 94 }, 95 } 96 checkResultBat, _ := batch1.Dup(proc.Mp()) 97 resetChildren(&argument1, batch1) 98 callResult, err := argument1.Call(proc) 99 require.NoError(t, err) 100 { 101 result := callResult.Batch 102 // check attr names 103 require.Equal(t, []string{"int64_column", "scalar_int64", "varchar_column", "scalar_varchar", "int64_column"}, result.Attrs) 104 // check vector 105 require.Equal(t, len(checkResultBat.Vecs), len(result.Vecs)) 106 for i, vec := range result.Vecs { 107 require.Equal(t, checkResultBat.RowCount(), vec.Length(), fmt.Sprintf("column number: %d", i)) 108 } 109 checkResultBat.Clean(proc.Mp()) 110 } 111 112 argument1.Free(proc, false, nil) 113 proc.FreeVectors() 114 require.Equal(t, int64(0), proc.GetMPool().CurrNB()) 115 } 116 117 func TestPreInsertNullCheck(t *testing.T) { 118 ctrl := gomock.NewController(t) 119 defer ctrl.Finish() 120 121 ctx := context.TODO() 122 txnOperator := mock_frontend.NewMockTxnOperator(ctrl) 123 txnOperator.EXPECT().Commit(gomock.Any()).Return(nil).AnyTimes() 124 txnOperator.EXPECT().Rollback(ctx).Return(nil).AnyTimes() 125 126 txnClient := mock_frontend.NewMockTxnClient(ctrl) 127 txnClient.EXPECT().New(gomock.Any(), gomock.Any()).Return(txnOperator, nil).AnyTimes() 128 129 eng := mock_frontend.NewMockEngine(ctrl) 130 eng.EXPECT().New(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() 131 eng.EXPECT().Hints().Return(engine.Hints{ 132 CommitOrRollbackTimeout: time.Second, 133 }).AnyTimes() 134 135 proc := testutil.NewProc() 136 proc.TxnClient = txnClient 137 proc.Ctx = ctx 138 proc.SessionInfo.StorageEngine = eng 139 batch2 := &batch.Batch{ 140 Vecs: []*vector.Vector{ 141 testutil.MakeInt64Vector([]int64{1, 2, 0}, []uint64{2}), 142 }, 143 Attrs: []string{"int64_column_primary"}, 144 Cnt: 1, 145 } 146 batch2.SetRowCount(3) 147 argument2 := Argument{ 148 SchemaName: "testDb", 149 Attrs: []string{"int64_column_primary"}, 150 TableDef: &plan.TableDef{ 151 Cols: []*plan.ColDef{ 152 {Name: "int64_column_primary", Primary: true, Typ: i64typ, 153 Default: &plan.Default{ 154 NullAbility: false, 155 }, 156 }, 157 }, 158 Pkey: &plan.PrimaryKeyDef{ 159 PkeyColName: "int64_column_primary", 160 }, 161 }, 162 OperatorBase: vm.OperatorBase{ 163 OperatorInfo: vm.OperatorInfo{ 164 Idx: 1, 165 IsFirst: false, 166 IsLast: false, 167 }, 168 }, 169 } 170 resetChildren(&argument2, batch2) 171 _, err2 := argument2.Call(proc) 172 require.Error(t, err2, "should return error when insert null into primary key column") 173 } 174 175 func resetChildren(arg *Argument, bat *batch.Batch) { 176 arg.SetChildren( 177 []vm.Operator{ 178 &value_scan.Argument{ 179 Batchs: []*batch.Batch{bat}, 180 }, 181 }) 182 }