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  }