@@ -27,7 +27,7 @@ impl Binder {
2727 symbols : Arena :: new ( ) ,
2828 search_path_changes : vec ! [ SearchPathChange {
2929 position: TextSize :: from( 0 ) ,
30- search_path: vec![ Schema :: new( "pg_temp " ) , Schema :: new( "public " ) ] ,
30+ search_path: vec![ Schema :: new( "public " ) , Schema :: new( "pg_temp " ) ] ,
3131 } ] ,
3232 }
3333 }
@@ -40,6 +40,14 @@ impl Binder {
4040 . expect ( "root scope must exist" )
4141 }
4242
43+ fn current_search_path ( & self ) -> & [ Schema ] {
44+ & self
45+ . search_path_changes
46+ . last ( )
47+ . expect ( "search_path_changes should never be empty" )
48+ . search_path
49+ }
50+
4351 pub ( crate ) fn search_path_at ( & self , position : TextSize ) -> & [ Schema ] {
4452 // We're assuming people don't actually use `set search_path` that much,
4553 // so linear search is fine
@@ -84,7 +92,9 @@ fn bind_create_table(b: &mut Binder, create_table: ast::CreateTable) {
8492 } ;
8593 let name_ptr = path_to_ptr ( & path) ;
8694 let is_temp = create_table. temp_token ( ) . is_some ( ) || create_table. temporary_token ( ) . is_some ( ) ;
87- let schema = schema_name ( & path, is_temp) ;
95+ let Some ( schema) = schema_name ( b, & path, is_temp) else {
96+ return ;
97+ } ;
8898
8999 let table_id = b. symbols . alloc ( Symbol {
90100 kind : SymbolKind :: Table ,
@@ -121,36 +131,34 @@ fn path_to_ptr(path: &ast::Path) -> SyntaxNodePtr {
121131 SyntaxNodePtr :: new ( path. syntax ( ) )
122132}
123133
124- fn schema_name ( path : & ast:: Path , is_temp : bool ) -> Schema {
125- let default_schema = if is_temp { "pg_temp" } else { "public" } ;
126-
127- let Some ( segment) = path. qualifier ( ) . and_then ( |q| q. segment ( ) ) else {
128- return Schema :: new ( default_schema) ;
129- } ;
134+ fn schema_name ( b : & Binder , path : & ast:: Path , is_temp : bool ) -> Option < Schema > {
135+ if let Some ( name_ref) = path
136+ . qualifier ( )
137+ . and_then ( |q| q. segment ( ) )
138+ . and_then ( |s| s. name_ref ( ) )
139+ {
140+ return Some ( Schema ( Name :: new ( name_ref. syntax ( ) . text ( ) . to_string ( ) ) ) ) ;
141+ }
130142
131- let schema_name = if let Some ( name) = segment. name ( ) {
132- Name :: new ( name. syntax ( ) . text ( ) . to_string ( ) )
133- } else if let Some ( name_ref) = segment. name_ref ( ) {
134- Name :: new ( name_ref. syntax ( ) . text ( ) . to_string ( ) )
135- } else {
136- return Schema :: new ( default_schema) ;
137- } ;
143+ if is_temp {
144+ return Some ( Schema :: new ( "pg_temp" ) ) ;
145+ }
138146
139- Schema ( schema_name )
147+ b . current_search_path ( ) . first ( ) . cloned ( )
140148}
141149
142150fn bind_set ( b : & mut Binder , set : ast:: Set ) {
143151 let position = set. syntax ( ) . text_range ( ) . start ( ) ;
144152
145153 // `set schema` is an alternative to `set search_path`
146154 if set. schema_token ( ) . is_some ( ) {
147- if let Some ( literal) = set. literal ( ) {
148- if let Some ( string_value) = extract_string_literal ( & literal) {
149- b . search_path_changes . push ( SearchPathChange {
150- position ,
151- search_path : vec ! [ Schema :: new ( string_value ) ] ,
152- } ) ;
153- }
155+ if let Some ( literal) = set. literal ( )
156+ && let Some ( string_value) = extract_string_literal ( & literal)
157+ {
158+ b . search_path_changes . push ( SearchPathChange {
159+ position ,
160+ search_path : vec ! [ Schema :: new ( string_value ) ] ,
161+ } ) ;
154162 }
155163 return ;
156164 }
@@ -179,14 +187,17 @@ fn bind_set(b: &mut Binder, set: ast::Set) {
179187 if set. default_token ( ) . is_some ( ) {
180188 b. search_path_changes . push ( SearchPathChange {
181189 position,
182- search_path : vec ! [ Schema :: new( "pg_temp " ) , Schema :: new( "public " ) ] ,
190+ search_path : vec ! [ Schema :: new( "public " ) , Schema :: new( "pg_temp " ) ] ,
183191 } ) ;
184192 } else {
185193 let mut search_path = vec ! [ ] ;
186194 for config_value in set. config_values ( ) {
187195 match config_value {
188196 ast:: ConfigValue :: Literal ( literal) => {
189197 if let Some ( string_value) = extract_string_literal ( & literal) {
198+ // You can unset the search path via `set search_path = ''`
199+ // so we want to skip over these, otherwise we'll
200+ // have a schema of value `''` which isn't valid.
190201 if !string_value. is_empty ( ) {
191202 search_path. push ( Schema :: new ( string_value) ) ;
192203 }
0 commit comments