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