github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/sessiondata/search_path_test.go (about)

     1  // Copyright 2016 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package sessiondata
    12  
    13  import (
    14  	"reflect"
    15  	"strings"
    16  	"testing"
    17  
    18  	"github.com/stretchr/testify/assert"
    19  )
    20  
    21  // Tests the implied search path when no temporary schema has been created
    22  // by the session.
    23  func TestImpliedSearchPath(t *testing.T) {
    24  	testTempSchemaName := `test_temp_schema`
    25  
    26  	testCases := []struct {
    27  		explicitSearchPath                                             []string
    28  		expectedSearchPath                                             []string
    29  		expectedSearchPathWithoutImplicitPgSchemas                     []string
    30  		expectedSearchPathWhenTemporarySchemaExists                    []string
    31  		expectedSearchPathWithoutImplicitPgSchemasWhenTempSchemaExists []string
    32  	}{
    33  		{
    34  			explicitSearchPath:                                             []string{},
    35  			expectedSearchPath:                                             []string{`pg_catalog`},
    36  			expectedSearchPathWithoutImplicitPgSchemas:                     []string{},
    37  			expectedSearchPathWhenTemporarySchemaExists:                    []string{testTempSchemaName, `pg_catalog`},
    38  			expectedSearchPathWithoutImplicitPgSchemasWhenTempSchemaExists: []string{},
    39  		},
    40  		{
    41  			explicitSearchPath:                                             []string{`pg_catalog`},
    42  			expectedSearchPath:                                             []string{`pg_catalog`},
    43  			expectedSearchPathWithoutImplicitPgSchemas:                     []string{`pg_catalog`},
    44  			expectedSearchPathWhenTemporarySchemaExists:                    []string{testTempSchemaName, `pg_catalog`},
    45  			expectedSearchPathWithoutImplicitPgSchemasWhenTempSchemaExists: []string{`pg_catalog`},
    46  		},
    47  		{
    48  			explicitSearchPath:                                             []string{`pg_catalog`, `pg_temp`},
    49  			expectedSearchPath:                                             []string{`pg_catalog`},
    50  			expectedSearchPathWithoutImplicitPgSchemas:                     []string{`pg_catalog`},
    51  			expectedSearchPathWhenTemporarySchemaExists:                    []string{`pg_catalog`, testTempSchemaName},
    52  			expectedSearchPathWithoutImplicitPgSchemasWhenTempSchemaExists: []string{`pg_catalog`, testTempSchemaName},
    53  		},
    54  		{
    55  			explicitSearchPath:                                             []string{`pg_temp`, `pg_catalog`},
    56  			expectedSearchPath:                                             []string{`pg_catalog`},
    57  			expectedSearchPathWithoutImplicitPgSchemas:                     []string{`pg_catalog`},
    58  			expectedSearchPathWhenTemporarySchemaExists:                    []string{testTempSchemaName, `pg_catalog`},
    59  			expectedSearchPathWithoutImplicitPgSchemasWhenTempSchemaExists: []string{testTempSchemaName, `pg_catalog`},
    60  		},
    61  		{
    62  			explicitSearchPath:                                             []string{`foobar`, `pg_catalog`},
    63  			expectedSearchPath:                                             []string{`foobar`, `pg_catalog`},
    64  			expectedSearchPathWithoutImplicitPgSchemas:                     []string{`foobar`, `pg_catalog`},
    65  			expectedSearchPathWhenTemporarySchemaExists:                    []string{testTempSchemaName, `foobar`, `pg_catalog`},
    66  			expectedSearchPathWithoutImplicitPgSchemasWhenTempSchemaExists: []string{`foobar`, `pg_catalog`},
    67  		},
    68  		{
    69  			explicitSearchPath:                                             []string{`foobar`, `pg_temp`},
    70  			expectedSearchPath:                                             []string{`pg_catalog`, `foobar`},
    71  			expectedSearchPathWithoutImplicitPgSchemas:                     []string{`foobar`},
    72  			expectedSearchPathWhenTemporarySchemaExists:                    []string{`pg_catalog`, `foobar`, testTempSchemaName},
    73  			expectedSearchPathWithoutImplicitPgSchemasWhenTempSchemaExists: []string{`foobar`, testTempSchemaName},
    74  		},
    75  		{
    76  			explicitSearchPath:                                             []string{`foobar`},
    77  			expectedSearchPath:                                             []string{`pg_catalog`, `foobar`},
    78  			expectedSearchPathWithoutImplicitPgSchemas:                     []string{`foobar`},
    79  			expectedSearchPathWhenTemporarySchemaExists:                    []string{testTempSchemaName, `pg_catalog`, `foobar`},
    80  			expectedSearchPathWithoutImplicitPgSchemasWhenTempSchemaExists: []string{`foobar`},
    81  		},
    82  		{
    83  			explicitSearchPath:                                             []string{`public`},
    84  			expectedSearchPath:                                             []string{`pg_catalog`, `pg_extension`, `public`},
    85  			expectedSearchPathWithoutImplicitPgSchemas:                     []string{`public`},
    86  			expectedSearchPathWhenTemporarySchemaExists:                    []string{testTempSchemaName, `pg_catalog`, `pg_extension`, `public`},
    87  			expectedSearchPathWithoutImplicitPgSchemasWhenTempSchemaExists: []string{`public`},
    88  		},
    89  		{
    90  			explicitSearchPath:                                             []string{`public`, `pg_extension`},
    91  			expectedSearchPath:                                             []string{`pg_catalog`, `public`, `pg_extension`},
    92  			expectedSearchPathWithoutImplicitPgSchemas:                     []string{`public`, `pg_extension`},
    93  			expectedSearchPathWhenTemporarySchemaExists:                    []string{testTempSchemaName, `pg_catalog`, `public`, `pg_extension`},
    94  			expectedSearchPathWithoutImplicitPgSchemasWhenTempSchemaExists: []string{`public`, `pg_extension`},
    95  		},
    96  	}
    97  
    98  	for tcNum, tc := range testCases {
    99  		t.Run(strings.Join(tc.explicitSearchPath, ","), func(t *testing.T) {
   100  			searchPath := MakeSearchPath(tc.explicitSearchPath)
   101  			actualSearchPath := make([]string, 0)
   102  			iter := searchPath.Iter()
   103  			for p, ok := iter.Next(); ok; p, ok = iter.Next() {
   104  				actualSearchPath = append(actualSearchPath, p)
   105  			}
   106  			if !reflect.DeepEqual(tc.expectedSearchPath, actualSearchPath) {
   107  				t.Errorf(
   108  					`#%d: Expected search path to be %#v, but was %#v.`,
   109  					tcNum,
   110  					tc.expectedSearchPath,
   111  					actualSearchPath,
   112  				)
   113  			}
   114  		})
   115  
   116  		t.Run(strings.Join(tc.explicitSearchPath, ",")+"/no-pg-schemas", func(t *testing.T) {
   117  			searchPath := MakeSearchPath(tc.explicitSearchPath)
   118  			actualSearchPath := make([]string, 0)
   119  			iter := searchPath.IterWithoutImplicitPGSchemas()
   120  			for p, ok := iter.Next(); ok; p, ok = iter.Next() {
   121  				actualSearchPath = append(actualSearchPath, p)
   122  			}
   123  			if !reflect.DeepEqual(tc.expectedSearchPathWithoutImplicitPgSchemas, actualSearchPath) {
   124  				t.Errorf(
   125  					`#%d: Expected search path to be %#v, but was %#v.`,
   126  					tcNum,
   127  					tc.expectedSearchPathWithoutImplicitPgSchemas,
   128  					actualSearchPath,
   129  				)
   130  			}
   131  		})
   132  
   133  		t.Run(strings.Join(tc.explicitSearchPath, ",")+"/temp-schema-exists", func(t *testing.T) {
   134  			searchPath := MakeSearchPath(tc.explicitSearchPath).WithTemporarySchemaName(testTempSchemaName)
   135  			actualSearchPath := make([]string, 0)
   136  			iter := searchPath.Iter()
   137  			for p, ok := iter.Next(); ok; p, ok = iter.Next() {
   138  				actualSearchPath = append(actualSearchPath, p)
   139  			}
   140  			if !reflect.DeepEqual(tc.expectedSearchPathWhenTemporarySchemaExists, actualSearchPath) {
   141  				t.Errorf(
   142  					`#%d: Expected search path to be %#v, but was %#v.`,
   143  					tcNum,
   144  					tc.expectedSearchPathWhenTemporarySchemaExists,
   145  					actualSearchPath,
   146  				)
   147  			}
   148  		})
   149  
   150  		t.Run(strings.Join(tc.explicitSearchPath, ",")+"/no-pg-schemas/temp-schema-exists", func(t *testing.T) {
   151  			searchPath := MakeSearchPath(tc.explicitSearchPath).WithTemporarySchemaName(testTempSchemaName)
   152  			actualSearchPath := make([]string, 0)
   153  			iter := searchPath.IterWithoutImplicitPGSchemas()
   154  			for p, ok := iter.Next(); ok; p, ok = iter.Next() {
   155  				actualSearchPath = append(actualSearchPath, p)
   156  			}
   157  			if !reflect.DeepEqual(tc.expectedSearchPathWithoutImplicitPgSchemasWhenTempSchemaExists, actualSearchPath) {
   158  				t.Errorf(
   159  					`#%d: Expected search path to be %#v, but was %#v.`,
   160  					tcNum,
   161  					tc.expectedSearchPathWithoutImplicitPgSchemasWhenTempSchemaExists,
   162  					actualSearchPath,
   163  				)
   164  			}
   165  		})
   166  	}
   167  }
   168  
   169  func TestSearchPathEquals(t *testing.T) {
   170  	testTempSchemaName := `test_temp_schema`
   171  
   172  	a1 := MakeSearchPath([]string{"x", "y", "z"})
   173  	a2 := MakeSearchPath([]string{"x", "y", "z"})
   174  	assert.True(t, a1.Equals(&a1))
   175  	assert.True(t, a2.Equals(&a2))
   176  
   177  	assert.True(t, a1.Equals(&a2))
   178  	assert.True(t, a2.Equals(&a1))
   179  
   180  	b := MakeSearchPath([]string{"x", "z", "y"})
   181  	assert.False(t, a1.Equals(&b))
   182  
   183  	c1 := MakeSearchPath([]string{"x", "y", "z", "pg_catalog"})
   184  	c2 := MakeSearchPath([]string{"x", "y", "z", "pg_catalog"})
   185  	assert.True(t, c1.Equals(&c2))
   186  	assert.False(t, a1.Equals(&c1))
   187  
   188  	d := MakeSearchPath([]string{"x"})
   189  	assert.False(t, a1.Equals(&d))
   190  
   191  	e1 := MakeSearchPath([]string{"x", "y", "z"}).WithTemporarySchemaName(testTempSchemaName)
   192  	e2 := MakeSearchPath([]string{"x", "y", "z"}).WithTemporarySchemaName(testTempSchemaName)
   193  	assert.True(t, e1.Equals(&e1))
   194  	assert.True(t, e1.Equals(&e2))
   195  	assert.False(t, e1.Equals(&a1))
   196  
   197  	f := MakeSearchPath([]string{"x", "z", "y"}).WithTemporarySchemaName(testTempSchemaName)
   198  	assert.False(t, e1.Equals(&f))
   199  
   200  	g := MakeSearchPath([]string{"x", "y", "z", "pg_temp"})
   201  	assert.False(t, e1.Equals(&g))
   202  	assert.False(t, g.Equals(&c1))
   203  
   204  	h := MakeSearchPath([]string{"x", "y", "z", "pg_temp"}).WithTemporarySchemaName(testTempSchemaName)
   205  	assert.False(t, g.Equals(&h))
   206  
   207  	i := MakeSearchPath([]string{"x", "y", "z", "pg_temp", "pg_catalog"}).WithTemporarySchemaName(testTempSchemaName)
   208  	assert.False(t, i.Equals(&h))
   209  	assert.False(t, i.Equals(&c1))
   210  }
   211  
   212  func TestWithTemporarySchema(t *testing.T) {
   213  	testTempSchemaName := `test_temp_schema`
   214  
   215  	sp := MakeSearchPath([]string{"x", "y", "z"})
   216  	sp = sp.UpdatePaths([]string{"x", "pg_catalog"})
   217  	assert.True(t, sp.GetTemporarySchemaName() == "")
   218  
   219  	sp = sp.WithTemporarySchemaName(testTempSchemaName)
   220  	sp = sp.UpdatePaths([]string{"pg_catalog"})
   221  	assert.True(t, sp.GetTemporarySchemaName() == testTempSchemaName)
   222  
   223  	sp = sp.UpdatePaths([]string{"x", "pg_temp"})
   224  	assert.True(t, sp.GetTemporarySchemaName() == testTempSchemaName)
   225  }