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  }