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 }