github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/colexec/insert/insert_test.go (about) 1 // Copyright 2021 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 insert 16 17 import ( 18 "context" 19 "fmt" 20 "reflect" 21 "testing" 22 "time" 23 24 "github.com/golang/mock/gomock" 25 "github.com/matrixorigin/matrixone/pkg/container/batch" 26 "github.com/matrixorigin/matrixone/pkg/container/types" 27 "github.com/matrixorigin/matrixone/pkg/container/vector" 28 mock_frontend "github.com/matrixorigin/matrixone/pkg/frontend/test" 29 "github.com/matrixorigin/matrixone/pkg/pb/plan" 30 "github.com/matrixorigin/matrixone/pkg/testutil" 31 "github.com/matrixorigin/matrixone/pkg/vm/engine" 32 "github.com/stretchr/testify/require" 33 ) 34 35 type mockRelation struct { 36 engine.Relation 37 result *batch.Batch 38 } 39 40 func (e *mockRelation) Write(_ context.Context, b *batch.Batch) error { 41 e.result = b 42 return nil 43 } 44 45 var ( 46 i64typ = &plan.Type{Id: int32(types.T_int64)} 47 varchartyp = &plan.Type{Id: int32(types.T_varchar)} 48 ) 49 50 func TestInsertOperator(t *testing.T) { 51 ctrl := gomock.NewController(t) 52 defer ctrl.Finish() 53 54 ctx := context.TODO() 55 txnOperator := mock_frontend.NewMockTxnOperator(ctrl) 56 txnOperator.EXPECT().Commit(gomock.Any()).Return(nil).AnyTimes() 57 txnOperator.EXPECT().Rollback(ctx).Return(nil).AnyTimes() 58 59 txnClient := mock_frontend.NewMockTxnClient(ctrl) 60 txnClient.EXPECT().New().Return(txnOperator, nil).AnyTimes() 61 62 eng := mock_frontend.NewMockEngine(ctrl) 63 eng.EXPECT().New(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() 64 eng.EXPECT().Commit(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() 65 eng.EXPECT().Rollback(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() 66 eng.EXPECT().Hints().Return(engine.Hints{ 67 CommitOrRollbackTimeout: time.Second, 68 }).AnyTimes() 69 70 proc := testutil.NewProc() 71 proc.TxnClient = txnClient 72 proc.Ctx = ctx 73 batch1 := &batch.Batch{ 74 Vecs: []*vector.Vector{ 75 testutil.MakeInt64Vector([]int64{1, 2, 0}, []uint64{3}), 76 testutil.MakeScalarInt64(3, 3), 77 testutil.MakeVarcharVector([]string{"a", "b", "c"}, nil), 78 testutil.MakeScalarVarchar("d", 3), 79 testutil.MakeScalarNull(types.T_int64, 3), 80 }, 81 Zs: []int64{1, 1, 1}, 82 } 83 argument1 := Argument{ 84 Engine: eng, 85 InsertCtx: &InsertCtx{ 86 Source: &mockRelation{}, 87 Idx: []int32{0, 1, 2, 3, 4}, 88 Ref: &plan.ObjectRef{ 89 Obj: 0, 90 SchemaName: "testDb", 91 ObjName: "testTable", 92 }, 93 TableDef: &plan.TableDef{ 94 Cols: []*plan.ColDef{ 95 {Name: "int64_column", Typ: i64typ}, 96 {Name: "scalar_int64", Typ: i64typ}, 97 {Name: "varchar_column", Typ: varchartyp}, 98 {Name: "scalar_varchar", Typ: varchartyp}, 99 {Name: "int64_column", Typ: i64typ}, 100 }, 101 }, 102 }, 103 } 104 proc.Reg.InputBatch = batch1 105 _, err := Call(0, proc, &argument1, false, false) 106 require.NoError(t, err) 107 println(argument1.InsertCtx.Source.(*mockRelation).result.Vecs) 108 { 109 result := argument1.InsertCtx.Source.(*mockRelation).result 110 // check attr names 111 require.True(t, reflect.DeepEqual( 112 []string{"int64_column", "scalar_int64", "varchar_column", "scalar_varchar", "int64_column"}, 113 result.Attrs, 114 )) 115 // check vector 116 require.Equal(t, len(batch1.Vecs), len(result.Vecs)) 117 for i, vec := range result.Vecs { 118 require.Equal(t, len(batch1.Zs), vector.Length(vec), fmt.Sprintf("column number: %d", i)) 119 } 120 } 121 122 batch2 := &batch.Batch{ 123 Vecs: []*vector.Vector{ 124 testutil.MakeInt64Vector([]int64{1, 2, 0}, []uint64{2}), 125 }, 126 Zs: []int64{1, 1, 1}, 127 } 128 argument2 := Argument{ 129 Engine: eng, 130 InsertCtx: &InsertCtx{ 131 Source: &mockRelation{}, 132 Idx: []int32{0}, 133 Ref: &plan.ObjectRef{ 134 Obj: 0, 135 SchemaName: "testDb", 136 ObjName: "testTable", 137 }, 138 TableDef: &plan.TableDef{ 139 Cols: []*plan.ColDef{ 140 {Name: "int64_column_primary", Primary: true, Typ: i64typ, 141 Default: &plan.Default{ 142 NullAbility: false, 143 }, 144 }, 145 }, 146 }, 147 }, 148 } 149 proc.Reg.InputBatch = batch2 150 _, err2 := Call(0, proc, &argument2, false, false) 151 require.Errorf(t, err2, "should return error when insert null into primary key column") 152 }