@@ -83,23 +83,28 @@ impl fmt::Display for ParserError {
83
83
impl Error for ParserError { }
84
84
85
85
/// SQL Parser
86
- pub struct Parser {
86
+ pub struct Parser < ' a > {
87
87
tokens : Vec < Token > ,
88
88
/// The index of the first unprocessed token in `self.tokens`
89
89
index : usize ,
90
+ dialect : & ' a dyn Dialect ,
90
91
}
91
92
92
- impl Parser {
93
+ impl < ' a > Parser < ' a > {
93
94
/// Parse the specified tokens
94
- pub fn new ( tokens : Vec < Token > ) -> Self {
95
- Parser { tokens, index : 0 }
95
+ pub fn new ( tokens : Vec < Token > , dialect : & ' a dyn Dialect ) -> Self {
96
+ Parser {
97
+ tokens,
98
+ index : 0 ,
99
+ dialect,
100
+ }
96
101
}
97
102
98
103
/// Parse a SQL statement and produce an Abstract Syntax Tree (AST)
99
104
pub fn parse_sql ( dialect : & dyn Dialect , sql : & str ) -> Result < Vec < Statement > , ParserError > {
100
105
let mut tokenizer = Tokenizer :: new ( dialect, & sql) ;
101
106
let tokens = tokenizer. tokenize ( ) ?;
102
- let mut parser = Parser :: new ( tokens) ;
107
+ let mut parser = Parser :: new ( tokens, dialect ) ;
103
108
let mut stmts = Vec :: new ( ) ;
104
109
let mut expecting_statement_delimiter = false ;
105
110
debug ! ( "Parsing sql '{}'..." , sql) ;
@@ -950,7 +955,7 @@ impl Parser {
950
955
/// Parse a comma-separated list of 1+ items accepted by `F`
951
956
pub fn parse_comma_separated < T , F > ( & mut self , mut f : F ) -> Result < Vec < T > , ParserError >
952
957
where
953
- F : FnMut ( & mut Parser ) -> Result < T , ParserError > ,
958
+ F : FnMut ( & mut Parser < ' a > ) -> Result < T , ParserError > ,
954
959
{
955
960
let mut values = vec ! [ ] ;
956
961
loop {
@@ -2054,9 +2059,113 @@ impl Parser {
2054
2059
} ;
2055
2060
joins. push ( join) ;
2056
2061
}
2062
+
2057
2063
Ok ( TableWithJoins { relation, joins } )
2058
2064
}
2059
2065
2066
+ fn add_alias_to_single_table_in_parenthesis (
2067
+ & self ,
2068
+ table_and_joins : TableWithJoins ,
2069
+ consumed_alias : TableAlias ,
2070
+ ) -> Result < TableWithJoins , ParserError > {
2071
+ // This function deal with alias after single table in parenthesis
2072
+ // aliases not allow in joining between multiple tables (At least in snowflake DB)
2073
+ if !table_and_joins. joins . is_empty ( ) {
2074
+ return Err ( ParserError :: ParserError (
2075
+ "alias not allowed on multiple table join" . to_owned ( ) ,
2076
+ ) ) ;
2077
+ }
2078
+
2079
+ match table_and_joins. relation {
2080
+ // If the realation is Nested join - we will seep the alias
2081
+ // into the nested table, it's resonable as it's based
2082
+ // on the assumation that aliasing not allowed on join between
2083
+ // 2 diffrent tables - so the alias accutaly belong to the inner table
2084
+ TableFactor :: NestedJoin ( table_and_joins_box) => Ok ( TableWithJoins {
2085
+ relation : TableFactor :: NestedJoin ( Box :: new (
2086
+ self . add_alias_to_single_table_in_parenthesis (
2087
+ * table_and_joins_box,
2088
+ consumed_alias,
2089
+ ) ?,
2090
+ ) ) ,
2091
+ joins : Vec :: new ( ) ,
2092
+ } ) ,
2093
+ // Add the alias to dervied table
2094
+ TableFactor :: Derived {
2095
+ lateral,
2096
+ subquery,
2097
+ alias,
2098
+ } => match alias {
2099
+ None => Ok ( TableWithJoins {
2100
+ relation : TableFactor :: Derived {
2101
+ lateral,
2102
+ subquery,
2103
+ alias : Some ( consumed_alias) ,
2104
+ } ,
2105
+ joins : Vec :: new ( ) ,
2106
+ } ) ,
2107
+ // "Select * from (table1 as alias1) as alias1" - it prohabited
2108
+ Some ( alias) => Err ( ParserError :: ParserError ( format ! (
2109
+ "duplicate alias {}" ,
2110
+ alias
2111
+ ) ) ) ,
2112
+ } ,
2113
+ // Add The alias to the table factor
2114
+ TableFactor :: Table {
2115
+ name,
2116
+ alias,
2117
+ args,
2118
+ with_hints,
2119
+ } => match alias {
2120
+ None => Ok ( TableWithJoins {
2121
+ relation : TableFactor :: Table {
2122
+ name,
2123
+ alias : Some ( consumed_alias) ,
2124
+ args,
2125
+ with_hints,
2126
+ } ,
2127
+ joins : Vec :: new ( ) ,
2128
+ } ) ,
2129
+ // "Select * from (table1 as alias1) as alias1" - it prohabited
2130
+ Some ( alias) => Err ( ParserError :: ParserError ( format ! (
2131
+ "duplicate alias {}" ,
2132
+ alias
2133
+ ) ) ) ,
2134
+ } ,
2135
+ }
2136
+ }
2137
+
2138
+ fn check_for_alias_after_parenthesis (
2139
+ & mut self ,
2140
+ table_and_joins : TableWithJoins ,
2141
+ ) -> Result < TableWithJoins , ParserError > {
2142
+ // Try to parse alias if there is no alias - just return the TableWithJoins as is .
2143
+ let alias = match self . parse_optional_table_alias ( keywords:: RESERVED_FOR_TABLE_ALIAS ) ? {
2144
+ None => {
2145
+ return Ok ( table_and_joins) ;
2146
+ }
2147
+ Some ( alias) => alias,
2148
+ } ;
2149
+
2150
+ // if we have alias, we attached it to the single table that inside parenthesis
2151
+ self . add_alias_to_single_table_in_parenthesis ( table_and_joins, alias)
2152
+ }
2153
+
2154
+ fn validate_nested_join ( & self , table_and_joins : & TableWithJoins ) -> Result < ( ) , ParserError > {
2155
+ match table_and_joins. relation {
2156
+ TableFactor :: NestedJoin { .. } => ( ) ,
2157
+ _ => {
2158
+ if table_and_joins. joins . is_empty ( ) {
2159
+ // validate thats indeed join and not dervied
2160
+ // or nested table
2161
+ self . expected ( "joined table" , self . peek_token ( ) ) ?
2162
+ }
2163
+ }
2164
+ }
2165
+
2166
+ Ok ( ( ) )
2167
+ }
2168
+
2060
2169
/// A table name or a parenthesized subquery, followed by optional `[AS] alias`
2061
2170
pub fn parse_table_factor ( & mut self ) -> Result < TableFactor , ParserError > {
2062
2171
if self . parse_keyword ( Keyword :: LATERAL ) {
@@ -2100,10 +2209,21 @@ impl Parser {
2100
2209
// followed by some joins or another level of nesting.
2101
2210
let table_and_joins = self . parse_table_and_joins ( ) ?;
2102
2211
self . expect_token ( & Token :: RParen ) ?;
2212
+
2103
2213
// The SQL spec prohibits derived and bare tables from appearing
2104
- // alone in parentheses. We don't enforce this as some databases
2105
- // (e.g. Snowflake) allow such syntax.
2106
- Ok ( TableFactor :: NestedJoin ( Box :: new ( table_and_joins) ) )
2214
+ // alone in parentheses. But as some databases
2215
+ // (e.g. Snowflake) allow such syntax - it's can be allowed
2216
+ // for specfic dialect.
2217
+ if self . dialect . alllow_single_table_in_parenthesis ( ) {
2218
+ // In case of single dervied or bare table in parenthesis,
2219
+ // the alias could appears also after the parenthesis
2220
+ let table_and_joins = self . check_for_alias_after_parenthesis ( table_and_joins) ?;
2221
+ Ok ( TableFactor :: NestedJoin ( Box :: new ( table_and_joins) ) )
2222
+ } else {
2223
+ // Defualt behaviuor
2224
+ self . validate_nested_join ( & table_and_joins) ?;
2225
+ Ok ( TableFactor :: NestedJoin ( Box :: new ( table_and_joins) ) )
2226
+ }
2107
2227
} else {
2108
2228
let name = self . parse_object_name ( ) ?;
2109
2229
// Postgres, MSSQL: table-valued functions:
0 commit comments