@@ -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 {
@@ -2048,9 +2053,115 @@ impl Parser {
2048
2053
} ;
2049
2054
joins. push ( join) ;
2050
2055
}
2056
+
2051
2057
Ok ( TableWithJoins { relation, joins } )
2052
2058
}
2053
2059
2060
+ fn add_alias_to_single_table_in_parenthesis (
2061
+ & self ,
2062
+ table_and_joins : TableWithJoins ,
2063
+ consumed_alias : TableAlias ,
2064
+ ) -> Result < TableWithJoins , ParserError > {
2065
+
2066
+ // This function deal with alias after single table in parenthesis
2067
+ // aliases not allow in joining between multiple tables (At least in snowflake DB)
2068
+ if !table_and_joins. joins . is_empty ( ) {
2069
+ return Err ( ParserError :: ParserError (
2070
+ "alias not allowed on multiple table join" . to_owned ( ) ,
2071
+ ) ) ;
2072
+ }
2073
+
2074
+ match table_and_joins. relation {
2075
+ // If the realation is Nested join - we will seep the alias
2076
+ // into the nested table, it's resonable as it's based
2077
+ // on the assumation that aliasing not allowed on join between
2078
+ // 2 diffrent tables - so the alias accutaly belong to the inner table
2079
+ TableFactor :: NestedJoin ( table_and_joins_box) => Ok ( TableWithJoins {
2080
+ relation : TableFactor :: NestedJoin ( Box :: new (
2081
+ self . add_alias_to_single_table_in_parenthesis (
2082
+ * table_and_joins_box,
2083
+ consumed_alias,
2084
+ ) ?,
2085
+ ) ) ,
2086
+ joins : Vec :: new ( ) ,
2087
+ } ) ,
2088
+ // Add the alias to dervied table
2089
+ TableFactor :: Derived {
2090
+ lateral,
2091
+ subquery,
2092
+ alias,
2093
+ } => match alias {
2094
+ None => Ok ( TableWithJoins {
2095
+ relation : TableFactor :: Derived {
2096
+ lateral,
2097
+ subquery,
2098
+ alias : Some ( consumed_alias) ,
2099
+ } ,
2100
+ joins : Vec :: new ( ) ,
2101
+ } ) ,
2102
+ // "Select * from (table1 as alias1) as alias1" - it prohabited
2103
+ Some ( alias) => Err ( ParserError :: ParserError ( format ! (
2104
+ "duplicate alias {}" ,
2105
+ alias
2106
+ ) ) ) ,
2107
+ } ,
2108
+ // Add The alias to the table factor
2109
+ TableFactor :: Table {
2110
+ name,
2111
+ alias,
2112
+ args,
2113
+ with_hints,
2114
+ } => match alias {
2115
+ None => Ok ( TableWithJoins {
2116
+ relation : TableFactor :: Table {
2117
+ name,
2118
+ alias : Some ( consumed_alias) ,
2119
+ args,
2120
+ with_hints,
2121
+ } ,
2122
+ joins : Vec :: new ( ) ,
2123
+ } ) ,
2124
+ // "Select * from (table1 as alias1) as alias1" - it prohabited
2125
+ Some ( alias) => Err ( ParserError :: ParserError ( format ! (
2126
+ "duplicate alias {}" ,
2127
+ alias
2128
+ ) ) ) ,
2129
+ } ,
2130
+ }
2131
+ }
2132
+
2133
+ fn check_for_alias_after_parenthesis (
2134
+ & mut self ,
2135
+ table_and_joins : TableWithJoins ,
2136
+ ) -> Result < TableWithJoins , ParserError > {
2137
+
2138
+ // Try to parse alias if there is no alias - just return the TableWithJoins as is .
2139
+ let alias = match self . parse_optional_table_alias ( keywords:: RESERVED_FOR_TABLE_ALIAS ) ? {
2140
+ None => {
2141
+ return Ok ( table_and_joins) ;
2142
+ }
2143
+ Some ( alias) => alias,
2144
+ } ;
2145
+
2146
+ // if we have alias, we attached it to the single table that inside parenthesis
2147
+ self . add_alias_to_single_table_in_parenthesis ( table_and_joins, alias)
2148
+ }
2149
+
2150
+ fn validate_nested_join ( & self , table_and_joins : & TableWithJoins ) -> Result < ( ) , ParserError > {
2151
+ match table_and_joins. relation {
2152
+ TableFactor :: NestedJoin { .. } => ( ) ,
2153
+ _ => {
2154
+ if table_and_joins. joins . is_empty ( ) {
2155
+ // validate thats indeed join and not dervied
2156
+ // or nested table
2157
+ self . expected ( "joined table" , self . peek_token ( ) ) ?
2158
+ }
2159
+ }
2160
+ }
2161
+
2162
+ Ok ( ( ) )
2163
+ }
2164
+
2054
2165
/// A table name or a parenthesized subquery, followed by optional `[AS] alias`
2055
2166
pub fn parse_table_factor ( & mut self ) -> Result < TableFactor , ParserError > {
2056
2167
if self . parse_keyword ( Keyword :: LATERAL ) {
@@ -2094,10 +2205,21 @@ impl Parser {
2094
2205
// followed by some joins or another level of nesting.
2095
2206
let table_and_joins = self . parse_table_and_joins ( ) ?;
2096
2207
self . expect_token ( & Token :: RParen ) ?;
2208
+
2097
2209
// The SQL spec prohibits derived and bare tables from appearing
2098
- // alone in parentheses. We don't enforce this as some databases
2099
- // (e.g. Snowflake) allow such syntax.
2100
- Ok ( TableFactor :: NestedJoin ( Box :: new ( table_and_joins) ) )
2210
+ // alone in parentheses. But as some databases
2211
+ // (e.g. Snowflake) allow such syntax - it's can be allowed
2212
+ // for specfic dialect.
2213
+ if self . dialect . alllow_single_table_in_parenthesis ( ) {
2214
+ // In case of single dervied or bare table in parenthesis,
2215
+ // the alias could appears also after the parenthesis
2216
+ let table_and_joins = self . check_for_alias_after_parenthesis ( table_and_joins) ?;
2217
+ Ok ( TableFactor :: NestedJoin ( Box :: new ( table_and_joins) ) )
2218
+ } else {
2219
+ // Defualt behaviuor
2220
+ self . validate_nested_join ( & table_and_joins) ?;
2221
+ Ok ( TableFactor :: NestedJoin ( Box :: new ( table_and_joins) ) )
2222
+ }
2101
2223
} else {
2102
2224
let name = self . parse_object_name ( ) ?;
2103
2225
// Postgres, MSSQL: table-valued functions:
0 commit comments