@@ -40,6 +40,12 @@ pub enum IsOptional {
40
40
}
41
41
use IsOptional :: * ;
42
42
43
+ pub enum IsLateral {
44
+ Lateral ,
45
+ NotLateral ,
46
+ }
47
+ use IsLateral :: * ;
48
+
43
49
impl From < TokenizerError > for ParserError {
44
50
fn from ( e : TokenizerError ) -> Self {
45
51
ParserError :: TokenizerError ( format ! ( "{:?}" , e) )
@@ -1523,7 +1529,10 @@ impl Parser {
1523
1529
} else if self . parse_keyword ( "VALUES" ) {
1524
1530
SQLSetExpr :: Values ( self . parse_values ( ) ?)
1525
1531
} else {
1526
- return self . expected ( "SELECT or a subquery in the query body" , self . peek_token ( ) ) ;
1532
+ return self . expected (
1533
+ "SELECT, VALUES, or a subquery in the query body" ,
1534
+ self . peek_token ( ) ,
1535
+ ) ;
1527
1536
} ;
1528
1537
1529
1538
loop {
@@ -1668,30 +1677,65 @@ impl Parser {
1668
1677
1669
1678
/// A table name or a parenthesized subquery, followed by optional `[AS] alias`
1670
1679
pub fn parse_table_factor ( & mut self ) -> Result < TableFactor , ParserError > {
1671
- let lateral = self . parse_keyword ( "LATERAL" ) ;
1680
+ if self . parse_keyword ( "LATERAL" ) {
1681
+ // LATERAL must always be followed by a subquery.
1682
+ if !self . consume_token ( & Token :: LParen ) {
1683
+ self . expected ( "subquery after LATERAL" , self . peek_token ( ) ) ?;
1684
+ }
1685
+ return self . parse_derived_table_factor ( Lateral ) ;
1686
+ }
1687
+
1672
1688
if self . consume_token ( & Token :: LParen ) {
1673
- if self . parse_keyword ( "SELECT" )
1674
- || self . parse_keyword ( "WITH" )
1675
- || self . parse_keyword ( "VALUES" )
1676
- {
1677
- self . prev_token ( ) ;
1678
- let subquery = Box :: new ( self . parse_query ( ) ?) ;
1679
- self . expect_token ( & Token :: RParen ) ?;
1680
- let alias = self . parse_optional_table_alias ( keywords:: RESERVED_FOR_TABLE_ALIAS ) ?;
1681
- Ok ( TableFactor :: Derived {
1682
- lateral,
1683
- subquery,
1684
- alias,
1685
- } )
1686
- } else if lateral {
1687
- parser_err ! ( "Expected subquery after LATERAL, found nested join" . to_string( ) )
1688
- } else {
1689
- let table_reference = self . parse_table_and_joins ( ) ?;
1690
- self . expect_token ( & Token :: RParen ) ?;
1691
- Ok ( TableFactor :: NestedJoin ( Box :: new ( table_reference) ) )
1689
+ let index = self . index ;
1690
+ // A left paren introduces either a derived table (i.e., a subquery)
1691
+ // or a nested join. It's nearly impossible to determine ahead of
1692
+ // time which it is... so we just try to parse both.
1693
+ //
1694
+ // Here's an example that demonstrates the complexity:
1695
+ // /-------------------------------------------------------\
1696
+ // | /-----------------------------------\ |
1697
+ // SELECT * FROM ( ( ( (SELECT 1) UNION (SELECT 2) ) AS t1 NATURAL JOIN t2 ) )
1698
+ // ^ ^ ^ ^
1699
+ // | | | |
1700
+ // | | | |
1701
+ // | | | (4) belongs to a SQLSetExpr::Query inside the subquery
1702
+ // | | (3) starts a derived table (subquery)
1703
+ // | (2) starts a nested join
1704
+ // (1) an additional set of parens around a nested join
1705
+ //
1706
+ match self . parse_derived_table_factor ( NotLateral ) {
1707
+ // The recently consumed '(' started a derived table, and we've
1708
+ // parsed the subquery, followed by the closing ')', and the
1709
+ // alias of the derived table. In the example above this is
1710
+ // case (3), and the next token would be `NATURAL`.
1711
+ Ok ( table_factor) => Ok ( table_factor) ,
1712
+ Err ( _) => {
1713
+ // The '(' we've recently consumed does not start a derived
1714
+ // table. For valid input this can happen either when the
1715
+ // token following the paren can't start a query (e.g. `foo`
1716
+ // in `FROM (foo NATURAL JOIN bar)`, or when the '(' we've
1717
+ // consumed is followed by another '(' that starts a
1718
+ // derived table, like (3), or another nested join (2).
1719
+ //
1720
+ // Ignore the error and back up to where we were before.
1721
+ // Either we'll be able to parse a valid nested join, or
1722
+ // we won't, and we'll return that error instead.
1723
+ self . index = index;
1724
+ let table_and_joins = self . parse_table_and_joins ( ) ?;
1725
+ match table_and_joins. relation {
1726
+ TableFactor :: NestedJoin { .. } => ( ) ,
1727
+ _ => {
1728
+ if table_and_joins. joins . is_empty ( ) {
1729
+ // The SQL spec prohibits derived tables and bare
1730
+ // tables from appearing alone in parentheses.
1731
+ self . expected ( "joined table" , self . peek_token ( ) ) ?
1732
+ }
1733
+ }
1734
+ }
1735
+ self . expect_token ( & Token :: RParen ) ?;
1736
+ Ok ( TableFactor :: NestedJoin ( Box :: new ( table_and_joins) ) )
1737
+ }
1692
1738
}
1693
- } else if lateral {
1694
- self . expected ( "subquery after LATERAL" , self . peek_token ( ) )
1695
1739
} else {
1696
1740
let name = self . parse_object_name ( ) ?;
1697
1741
// Postgres, MSSQL: table-valued functions:
@@ -1721,6 +1765,23 @@ impl Parser {
1721
1765
}
1722
1766
}
1723
1767
1768
+ pub fn parse_derived_table_factor (
1769
+ & mut self ,
1770
+ lateral : IsLateral ,
1771
+ ) -> Result < TableFactor , ParserError > {
1772
+ let subquery = Box :: new ( self . parse_query ( ) ?) ;
1773
+ self . expect_token ( & Token :: RParen ) ?;
1774
+ let alias = self . parse_optional_table_alias ( keywords:: RESERVED_FOR_TABLE_ALIAS ) ?;
1775
+ Ok ( TableFactor :: Derived {
1776
+ lateral : match lateral {
1777
+ Lateral => true ,
1778
+ NotLateral => false ,
1779
+ } ,
1780
+ subquery,
1781
+ alias,
1782
+ } )
1783
+ }
1784
+
1724
1785
fn parse_join_constraint ( & mut self , natural : bool ) -> Result < JoinConstraint , ParserError > {
1725
1786
if natural {
1726
1787
Ok ( JoinConstraint :: Natural )
0 commit comments