github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/plan/build_ddl_test.go (about) 1 // Copyright 2021 - 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 plan 16 17 import ( 18 "context" 19 "encoding/json" 20 "github.com/golang/mock/gomock" 21 "github.com/matrixorigin/matrixone/pkg/catalog" 22 "github.com/matrixorigin/matrixone/pkg/container/types" 23 "github.com/matrixorigin/matrixone/pkg/pb/plan" 24 "github.com/matrixorigin/matrixone/pkg/sql/parsers" 25 "github.com/matrixorigin/matrixone/pkg/sql/parsers/dialect" 26 "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" 27 "github.com/stretchr/testify/assert" 28 "testing" 29 ) 30 31 func TestBuildAlterView(t *testing.T) { 32 ctrl := gomock.NewController(t) 33 defer ctrl.Finish() 34 35 type arg struct { 36 obj *ObjectRef 37 table *TableDef 38 } 39 40 sql1 := "alter view v as select a from a" 41 sql2 := "alter view v as select a from v" 42 sql3 := "alter view v as select a from vx" 43 44 store := make(map[string]arg) 45 46 vData, err := json.Marshal(ViewData{ 47 "create view v as select a from a", 48 "db", 49 }) 50 assert.NoError(t, err) 51 52 store["db.v"] = arg{nil, 53 &plan.TableDef{ 54 TableType: catalog.SystemViewRel, 55 ViewSql: &plan.ViewDef{ 56 View: string(vData), 57 }}, 58 } 59 60 vxData, err := json.Marshal(ViewData{ 61 "create view vx as select a from v", 62 "db", 63 }) 64 assert.NoError(t, err) 65 store["db.vx"] = arg{nil, 66 &plan.TableDef{ 67 TableType: catalog.SystemViewRel, 68 ViewSql: &plan.ViewDef{ 69 View: string(vxData), 70 }}, 71 } 72 73 store["db.a"] = arg{ 74 &plan.ObjectRef{}, 75 &plan.TableDef{ 76 TableType: catalog.SystemOrdinaryRel, 77 Cols: []*ColDef{ 78 { 79 Name: "a", 80 Typ: &plan.Type{ 81 Id: int32(types.T_varchar), 82 Width: types.MaxVarcharLen, 83 Table: "a", 84 }, 85 }, 86 }, 87 }} 88 89 store["db.verror"] = arg{nil, 90 &plan.TableDef{ 91 TableType: catalog.SystemViewRel}, 92 } 93 94 ctx := NewMockCompilerContext2(ctrl) 95 ctx.EXPECT().DefaultDatabase().Return("db").AnyTimes() 96 ctx.EXPECT().Resolve(gomock.Any(), gomock.Any()).DoAndReturn( 97 func(schemaName string, tableName string) (*ObjectRef, *TableDef) { 98 if schemaName == "" { 99 schemaName = "db" 100 } 101 x := store[schemaName+"."+tableName] 102 return x.obj, x.table 103 }).AnyTimes() 104 ctx.EXPECT().SetBuildingAlterView(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() 105 ctx.EXPECT().ResolveVariable(gomock.Any(), gomock.Any(), gomock.Any()).Return("", nil).AnyTimes() 106 ctx.EXPECT().GetAccountId().Return(catalog.System_Account).AnyTimes() 107 ctx.EXPECT().GetContext().Return(context.Background()).AnyTimes() 108 ctx.EXPECT().GetProcess().Return(nil).AnyTimes() 109 ctx.EXPECT().Stats(gomock.Any(), gomock.Any()).Return(&plan.Stats{}).AnyTimes() 110 111 ctx.EXPECT().GetRootSql().Return(sql1).AnyTimes() 112 stmt1, err := parsers.ParseOne(context.Background(), dialect.MYSQL, sql1) 113 assert.NoError(t, err) 114 _, err = buildAlterView(stmt1.(*tree.AlterView), ctx) 115 assert.NoError(t, err) 116 117 //direct recursive refrence 118 ctx.EXPECT().GetRootSql().Return(sql2).AnyTimes() 119 ctx.EXPECT().GetBuildingAlterView().Return(true, "db", "v").AnyTimes() 120 stmt2, err := parsers.ParseOne(context.Background(), dialect.MYSQL, sql2) 121 assert.NoError(t, err) 122 _, err = buildAlterView(stmt2.(*tree.AlterView), ctx) 123 assert.Error(t, err) 124 assert.EqualError(t, err, "internal error: there is a recursive reference to the view v") 125 126 //indirect recursive refrence 127 stmt3, err := parsers.ParseOne(context.Background(), dialect.MYSQL, sql3) 128 ctx.EXPECT().GetBuildingAlterView().Return(true, "db", "vx").AnyTimes() 129 assert.NoError(t, err) 130 _, err = buildAlterView(stmt3.(*tree.AlterView), ctx) 131 assert.Error(t, err) 132 assert.EqualError(t, err, "internal error: there is a recursive reference to the view v") 133 134 sql4 := "alter view noexists as select a from a" 135 stmt4, err := parsers.ParseOne(context.Background(), dialect.MYSQL, sql4) 136 assert.NoError(t, err) 137 _, err = buildAlterView(stmt4.(*tree.AlterView), ctx) 138 assert.Error(t, err) 139 140 sql5 := "alter view verror as select a from a" 141 stmt5, err := parsers.ParseOne(context.Background(), dialect.MYSQL, sql5) 142 assert.NoError(t, err) 143 _, err = buildAlterView(stmt5.(*tree.AlterView), ctx) 144 assert.Error(t, err) 145 }