@@ -6,7 +6,7 @@ use super::sql_ident::*;
66use crate :: iterator_ext:: IteratorExt ;
77use core:: fmt:: Debug ;
88use derive_more:: Display ;
9- use sqltk:: parser:: ast:: Ident ;
9+ use sqltk:: parser:: ast:: { Ident , ObjectName } ;
1010use std:: sync:: Arc ;
1111use thiserror:: Error ;
1212
@@ -23,9 +23,16 @@ pub struct Schema {
2323/// A table (or view).
2424///
2525/// It has a name and some columns
26+ ///
27+ /// The source_schema is the schema that the table "physically" belongs to
28+ /// A user-visible schema can provide permissions across many source schemas.
29+ /// ie, the "information_schema" and "pg_catalog" schemas are both included in the cidde loaded schema
30+ ///
2631#[ derive( Debug , Clone , PartialEq , Eq , Display , Hash ) ]
2732#[ display( "Table<{}>" , name) ]
2833pub struct Table {
34+ // The schema this table belongs to (e.g. "public", "information_schema", "pg_catalog")
35+ pub source_schema : Ident ,
2936 pub name : Ident ,
3037 pub columns : Vec < Arc < Column > > ,
3138 // Stores indices into the columns Vec.
@@ -102,19 +109,27 @@ impl Schema {
102109
103110 /// Resolves a table by `Ident`, which takes into account the SQL rules
104111 /// of quoted and new identifier matching.
105- pub fn resolve_table ( & self , name : & Ident ) -> Result < Arc < Table > , SchemaError > {
112+ pub fn resolve_table (
113+ & self ,
114+ table_name : & Ident ,
115+ source_schema : & Ident ,
116+ ) -> Result < Arc < Table > , SchemaError > {
106117 let mut haystack = self . tables . iter ( ) ;
107118 haystack
108- . find_unique ( & |table| SqlIdent :: from ( & table. name ) == SqlIdent :: from ( name) )
119+ . find_unique ( & |table| {
120+ SqlIdent :: from ( & table. name ) == SqlIdent :: from ( table_name)
121+ && SqlIdent :: from ( & table. source_schema ) == SqlIdent :: from ( source_schema)
122+ } )
109123 . cloned ( )
110- . map_err ( |_| SchemaError :: TableNotFound ( name . to_string ( ) ) )
124+ . map_err ( |_| SchemaError :: TableNotFound ( table_name . to_string ( ) ) )
111125 }
112126
113127 pub fn resolve_table_columns (
114128 & self ,
115129 table_name : & Ident ,
130+ source_schema : & Ident ,
116131 ) -> Result < Vec < SchemaTableColumn > , SchemaError > {
117- let table = self . resolve_table ( table_name) ?;
132+ let table = self . resolve_table ( table_name, source_schema ) ?;
118133 Ok ( table
119134 . columns
120135 . iter ( )
@@ -129,12 +144,14 @@ impl Schema {
129144 pub fn resolve_table_column (
130145 & self ,
131146 table_name : & Ident ,
147+ source_schema : & Ident ,
132148 column_name : & Ident ,
133149 ) -> Result < SchemaTableColumn , SchemaError > {
134150 let mut haystack = self . tables . iter ( ) ;
135- match haystack
136- . find_unique ( & |table| SqlIdent :: from ( & table. name ) == SqlIdent :: from ( table_name) )
137- {
151+ match haystack. find_unique ( & |table| {
152+ SqlIdent :: from ( & table. name ) == SqlIdent :: from ( table_name)
153+ && SqlIdent :: from ( & table. source_schema ) == SqlIdent :: from ( source_schema)
154+ } ) {
138155 Ok ( table) => match table. get_column ( column_name) {
139156 Ok ( column) => Ok ( SchemaTableColumn {
140157 table : table. name . clone ( ) ,
@@ -153,9 +170,10 @@ impl Schema {
153170
154171impl Table {
155172 /// Create a new named table with no columns.
156- pub fn new ( name : Ident ) -> Self {
173+ pub fn new ( name : Ident , source_schema : Ident ) -> Self {
157174 Self {
158175 name,
176+ source_schema,
159177 primary_key : Vec :: with_capacity ( 1 ) ,
160178 columns : Vec :: with_capacity ( 16 ) ,
161179 }
@@ -192,6 +210,18 @@ impl Table {
192210 . cloned ( )
193211 . collect ( )
194212 }
213+
214+ // ObjectName is a list of identifiers, the last entry is always the table name
215+ pub fn get_table_name_and_source_schema ( name : & ObjectName ) -> ( Ident , Ident ) {
216+ let idents = & name. 0 ;
217+ let table_name = idents. last ( ) . unwrap ( ) . clone ( ) ;
218+ let source_schema = if idents. len ( ) == 2 {
219+ idents. first ( ) . unwrap ( ) . clone ( )
220+ } else {
221+ Ident :: new ( "public" )
222+ } ;
223+ ( table_name, source_schema)
224+ }
195225}
196226
197227/// A DSL to create a [`Schema`] for testing purposes.
@@ -227,8 +257,8 @@ macro_rules! schema {
227257 ( @add_table $schema: ident $table_name: ident $table: ident { $( $columns: tt) * } ) => {
228258 $schema. add_table(
229259 {
230-
231- let mut $table = $crate:: model:: Table :: new( :: sqltk:: parser:: ast:: Ident :: new( stringify!( $table_name) ) ) ;
260+ let source_schema = :: sqltk :: parser :: ast :: Ident :: new ( "public" ) ;
261+ let mut $table = $crate:: model:: Table :: new( :: sqltk:: parser:: ast:: Ident :: new( stringify!( $table_name) ) , source_schema ) ;
232262 schema!( @add_columns $table $( $columns) * ) ;
233263 $table
234264 }
0 commit comments