github.com/dolthub/go-mysql-server@v0.18.0/sql/rowexec/drop_view_test.go (about) 1 // Copyright 2020-2021 Dolthub, Inc. 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 rowexec 16 17 import ( 18 "context" 19 "testing" 20 21 "github.com/stretchr/testify/require" 22 23 "github.com/dolthub/go-mysql-server/memory" 24 "github.com/dolthub/go-mysql-server/sql" 25 "github.com/dolthub/go-mysql-server/sql/expression" 26 "github.com/dolthub/go-mysql-server/sql/plan" 27 "github.com/dolthub/go-mysql-server/sql/types" 28 ) 29 30 // Generates a database with a single table called mytable and a catalog with 31 // the view that is also returned. The context returned is the one used to 32 // create the view. 33 func setupView(t *testing.T, db memory.MemoryDatabase) (*sql.Context, *sql.View) { 34 table := memory.NewTable(db.Database(), "mytable", sql.NewPrimaryKeySchema(sql.Schema{ 35 {Name: "i", Source: "mytable", Type: types.Int32}, 36 {Name: "s", Source: "mytable", Type: types.Text}, 37 }), nil) 38 39 db.AddTable("db", table) 40 41 subqueryAlias := plan.NewSubqueryAlias("myview", "select i from mytable", 42 plan.NewProject( 43 []sql.Expression{ 44 expression.NewGetFieldWithTable(0, 1, types.Int32, "", table.Name(), "i", true), 45 }, 46 plan.NewUnresolvedTable(table.Name(), ""), 47 ), 48 ) 49 50 createView := plan.NewCreateView(db, subqueryAlias.Name(), subqueryAlias, false, "CREATE VIEW myview AS SELECT i FROM mytable", "", "", "") 51 52 ctx := sql.NewContext(context.Background()) 53 54 _, err := DefaultBuilder.Build(ctx, createView, nil) 55 require.NoError(t, err) 56 57 return ctx, createView.View() 58 } 59 60 // Tests that DropView works as expected and that the view is dropped in 61 // the catalog when RowIter is called, regardless of the value of ifExists 62 func TestDropExistingViewFromRegistry(t *testing.T) { 63 test := func(ifExists bool) { 64 db := memory.NewViewlessDatabase("mydb") 65 ctx, view := setupView(t, db) 66 67 singleDropView := plan.NewSingleDropView(db, view.Name()) 68 dropView := plan.NewDropView([]sql.Node{singleDropView}, ifExists) 69 70 _, err := DefaultBuilder.Build(ctx, dropView, nil) 71 require.NoError(t, err) 72 73 require.False(t, ctx.GetViewRegistry().Exists(db.Name(), view.Name())) 74 } 75 76 test(false) 77 test(true) 78 } 79 80 // Tests that DropView errors when trying to delete a non-existing view if and 81 // only if the flag ifExists is set to false 82 func TestDropNonExistingViewFromRegistry(t *testing.T) { 83 test := func(ifExists bool) error { 84 db := memory.NewViewlessDatabase("mydb") 85 ctx, view := setupView(t, db) 86 87 singleDropView := plan.NewSingleDropView(db, "non-existing-view") 88 dropView := plan.NewDropView([]sql.Node{singleDropView}, ifExists) 89 90 _, err := DefaultBuilder.Build(ctx, dropView, nil) 91 92 require.True(t, ctx.GetViewRegistry().Exists(db.Name(), view.Name())) 93 94 return err 95 } 96 97 err := test(true) 98 require.NoError(t, err) 99 100 err = test(false) 101 require.Error(t, err) 102 } 103 104 // Tests that DropView works as expected and that the view is dropped in 105 // the catalog when RowIter is called, regardless of the value of ifExists 106 func TestDropExistingViewNative(t *testing.T) { 107 test := func(ifExists bool) { 108 db := memory.NewDatabase("mydb") 109 ctx, view := setupView(t, db) 110 111 singleDropView := plan.NewSingleDropView(db, view.Name()) 112 dropView := plan.NewDropView([]sql.Node{singleDropView}, ifExists) 113 114 _, err := DefaultBuilder.Build(ctx, dropView, nil) 115 require.NoError(t, err) 116 117 _, ok, err := db.GetViewDefinition(ctx, view.Name()) 118 require.NoError(t, err) 119 require.False(t, ok) 120 } 121 122 test(false) 123 test(true) 124 } 125 126 // Tests that DropView errors when trying to delete a non-existing view if and 127 // only if the flag ifExists is set to false 128 func TestDropNonExistingViewNative(t *testing.T) { 129 test := func(ifExists bool) error { 130 db := memory.NewDatabase("mydb") 131 ctx, view := setupView(t, db) 132 133 singleDropView := plan.NewSingleDropView(db, "non-existing-view") 134 dropView := plan.NewDropView([]sql.Node{singleDropView}, ifExists) 135 136 _, dropErr := DefaultBuilder.Build(ctx, dropView, nil) 137 138 _, ok, err := db.GetViewDefinition(ctx, view.Name()) 139 require.NoError(t, err) 140 require.True(t, ok) 141 142 return dropErr 143 } 144 145 err := test(true) 146 require.NoError(t, err) 147 148 err = test(false) 149 require.Error(t, err) 150 require.True(t, sql.ErrViewDoesNotExist.Is(err)) 151 }