github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/ccl/backupccl/targets_test.go (about)

     1  // Copyright 2016 The Cockroach Authors.
     2  //
     3  // Licensed as a CockroachDB Enterprise file under the Cockroach Community
     4  // License (the "License"); you may not use this file except in compliance with
     5  // the License. You may obtain a copy of the License at
     6  //
     7  //     https://github.com/cockroachdb/cockroach/blob/master/licenses/CCL.txt
     8  
     9  package backupccl
    10  
    11  import (
    12  	"context"
    13  	"fmt"
    14  	"reflect"
    15  	"sort"
    16  	"testing"
    17  
    18  	"github.com/cockroachdb/cockroach/pkg/sql/parser"
    19  	"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
    20  	"github.com/cockroachdb/cockroach/pkg/sql/sessiondata"
    21  	"github.com/cockroachdb/cockroach/pkg/sql/sqlbase"
    22  	"github.com/cockroachdb/cockroach/pkg/testutils"
    23  	"github.com/cockroachdb/cockroach/pkg/util/hlc"
    24  	"github.com/cockroachdb/cockroach/pkg/util/leaktest"
    25  )
    26  
    27  func TestDescriptorsMatchingTargets(t *testing.T) {
    28  	defer leaktest.AfterTest(t)()
    29  
    30  	descriptors := []sqlbase.Descriptor{
    31  		*sqlbase.WrapDescriptor(&sqlbase.DatabaseDescriptor{ID: 0, Name: "system"}),
    32  		*sqlbase.WrapDescriptor(&sqlbase.TableDescriptor{ID: 1, Name: "foo", ParentID: 0}),
    33  		*sqlbase.WrapDescriptor(&sqlbase.TableDescriptor{ID: 2, Name: "bar", ParentID: 0}),
    34  		*sqlbase.WrapDescriptor(&sqlbase.TableDescriptor{ID: 4, Name: "baz", ParentID: 3}),
    35  		*sqlbase.WrapDescriptor(&sqlbase.TableDescriptor{ID: 6, Name: "offline", ParentID: 0, State: sqlbase.TableDescriptor_OFFLINE}),
    36  		*sqlbase.WrapDescriptor(&sqlbase.DatabaseDescriptor{ID: 3, Name: "data"}),
    37  		*sqlbase.WrapDescriptor(&sqlbase.DatabaseDescriptor{ID: 5, Name: "empty"}),
    38  	}
    39  	// Set the timestamp on the table descriptors.
    40  	for _, d := range descriptors {
    41  		d.Table(hlc.Timestamp{WallTime: 1})
    42  	}
    43  
    44  	tests := []struct {
    45  		sessionDatabase string
    46  		pattern         string
    47  		expected        []string
    48  		expectedDBs     []string
    49  		err             string
    50  	}{
    51  		{"", "DATABASE system", []string{"system", "foo", "bar"}, []string{"system"}, ``},
    52  		{"", "DATABASE system, noexist", nil, nil, `unknown database "noexist"`},
    53  		{"", "DATABASE system, system", []string{"system", "foo", "bar"}, []string{"system"}, ``},
    54  		{"", "DATABASE data", []string{"data", "baz"}, []string{"data"}, ``},
    55  		{"", "DATABASE system, data", []string{"system", "foo", "bar", "data", "baz"}, []string{"data", "system"}, ``},
    56  		{"", "DATABASE system, data, noexist", nil, nil, `unknown database "noexist"`},
    57  		{"system", "DATABASE system", []string{"system", "foo", "bar"}, []string{"system"}, ``},
    58  		{"system", "DATABASE system, noexist", nil, nil, `unknown database "noexist"`},
    59  		{"system", "DATABASE data", []string{"data", "baz"}, []string{"data"}, ``},
    60  		{"system", "DATABASE system, data", []string{"system", "foo", "bar", "data", "baz"}, []string{"data", "system"}, ``},
    61  		{"system", "DATABASE system, data, noexist", nil, nil, `unknown database "noexist"`},
    62  
    63  		{"", "TABLE foo", nil, nil, `table "foo" does not exist`},
    64  		{"system", "TABLE foo", []string{"system", "foo"}, nil, ``},
    65  		{"system", "TABLE foo, foo", []string{"system", "foo"}, nil, ``},
    66  		{"data", "TABLE foo", nil, nil, `table "foo" does not exist`},
    67  
    68  		{"", "TABLE *", nil, nil, `"\*" does not match any valid database or schema`},
    69  		{"", "TABLE *, system.public.foo", nil, nil, `"\*" does not match any valid database or schema`},
    70  		{"noexist", "TABLE *", nil, nil, `"\*" does not match any valid database or schema`},
    71  		{"system", "TABLE *", []string{"system", "foo", "bar"}, nil, ``},
    72  		{"data", "TABLE *", []string{"data", "baz"}, nil, ``},
    73  		{"empty", "TABLE *", []string{"empty"}, nil, ``},
    74  
    75  		{"", "TABLE foo, baz", nil, nil, `table "(foo|baz)" does not exist`},
    76  		{"system", "TABLE foo, baz", nil, nil, `table "baz" does not exist`},
    77  		{"data", "TABLE foo, baz", nil, nil, `table "foo" does not exist`},
    78  
    79  		{"", "TABLE system.foo", []string{"system", "foo"}, nil, ``},
    80  		{"", "TABLE system.foo, foo", []string{"system", "foo"}, nil, `table "foo" does not exist`},
    81  		{"", "TABLE system.public.foo", []string{"system", "foo"}, nil, ``},
    82  		{"", "TABLE system.public.foo, foo", []string{"system", "foo"}, nil, `table "foo" does not exist`},
    83  
    84  		{"", "TABLE system.public.foo, bar", []string{"system", "foo"}, nil, `table "bar" does not exist`},
    85  		{"", "TABLE system.foo, bar", []string{"system", "foo"}, nil, `table "bar" does not exist`},
    86  		{"system", "TABLE system.public.foo, bar", []string{"system", "foo", "bar"}, nil, ``},
    87  		{"system", "TABLE system.foo, bar", []string{"system", "foo", "bar"}, nil, ``},
    88  
    89  		{"", "TABLE noexist.*", nil, nil, `"noexist\.\*" does not match any valid database or schema`},
    90  		{"", "TABLE empty.*", []string{"empty"}, nil, ``},
    91  		{"", "TABLE system.*", []string{"system", "foo", "bar"}, nil, ``},
    92  		{"", "TABLE system.public.*", []string{"system", "foo", "bar"}, nil, ``},
    93  		{"", "TABLE system.public.*, foo, baz", nil, nil, `table "(foo|baz)" does not exist`},
    94  		{"system", "TABLE system.public.*, foo, baz", nil, nil, `table "baz" does not exist`},
    95  		{"data", "TABLE system.public.*, baz", []string{"system", "foo", "bar", "data", "baz"}, nil, ``},
    96  		{"data", "TABLE system.public.*, foo, baz", nil, nil, `table "(foo|baz)" does not exist`},
    97  
    98  		{"", "TABLE SyStEm.FoO", []string{"system", "foo"}, nil, ``},
    99  		{"", "TABLE SyStEm.pUbLic.FoO", []string{"system", "foo"}, nil, ``},
   100  		{"", `TABLE system."FoO"`, nil, nil, `table "system.FoO" does not exist`},
   101  		{"system", `TABLE "FoO"`, nil, nil, `table "FoO" does not exist`},
   102  
   103  		{"", `TABLE system."foo"`, []string{"system", "foo"}, nil, ``},
   104  		{"", `TABLE system.public."foo"`, []string{"system", "foo"}, nil, ``},
   105  		{"system", `TABLE "foo"`, []string{"system", "foo"}, nil, ``},
   106  
   107  		{"system", `TABLE offline`, nil, nil, `table "offline" does not exist`},
   108  		{"", `TABLE system.offline`, []string{"system", "foo"}, nil, `table "system.public.offline" does not exist`},
   109  		{"system", `TABLE *`, []string{"system", "foo", "bar"}, nil, ``},
   110  	}
   111  	searchPath := sessiondata.MakeSearchPath([]string{"public", "pg_catalog"})
   112  	for i, test := range tests {
   113  		t.Run(fmt.Sprintf("%d/%s/%s", i, test.sessionDatabase, test.pattern), func(t *testing.T) {
   114  			sql := fmt.Sprintf(`GRANT ALL ON %s TO ignored`, test.pattern)
   115  			stmt, err := parser.ParseOne(sql)
   116  			if err != nil {
   117  				t.Fatal(err)
   118  			}
   119  			targets := stmt.AST.(*tree.Grant).Targets
   120  
   121  			matched, err := descriptorsMatchingTargets(context.Background(),
   122  				test.sessionDatabase, searchPath, descriptors, targets)
   123  			if test.err != "" {
   124  				if !testutils.IsError(err, test.err) {
   125  					t.Fatalf("expected error matching '%v', but got '%v'", test.err, err)
   126  				}
   127  			} else if err != nil {
   128  				t.Fatal(err)
   129  			} else {
   130  				var matchedNames []string
   131  				for _, m := range matched.descs {
   132  					matchedNames = append(matchedNames, m.GetName())
   133  				}
   134  				var matchedDBNames []string
   135  				for _, m := range matched.requestedDBs {
   136  					matchedDBNames = append(matchedDBNames, m.GetName())
   137  				}
   138  				sort.Strings(test.expected)
   139  				sort.Strings(test.expectedDBs)
   140  				sort.Strings(matchedNames)
   141  				sort.Strings(matchedDBNames)
   142  				if !reflect.DeepEqual(test.expected, matchedNames) {
   143  					t.Fatalf("expected %q got %q", test.expected, matchedNames)
   144  				}
   145  				if !reflect.DeepEqual(test.expectedDBs, matchedDBNames) {
   146  					t.Fatalf("expected %q got %q", test.expectedDBs, matchedDBNames)
   147  				}
   148  			}
   149  		})
   150  	}
   151  }