File tree 3 files changed +63
-3
lines changed
3 files changed +63
-3
lines changed Original file line number Diff line number Diff line change @@ -209,6 +209,7 @@ pub enum TableFactor {
209
209
with_hints : Vec < ASTNode > ,
210
210
} ,
211
211
Derived {
212
+ lateral : bool ,
212
213
subquery : Box < SQLQuery > ,
213
214
alias : Option < SQLIdent > ,
214
215
} ,
@@ -235,8 +236,16 @@ impl ToString for TableFactor {
235
236
}
236
237
s
237
238
}
238
- TableFactor :: Derived { subquery, alias } => {
239
- let mut s = format ! ( "({})" , subquery. to_string( ) ) ;
239
+ TableFactor :: Derived {
240
+ lateral,
241
+ subquery,
242
+ alias,
243
+ } => {
244
+ let mut s = String :: new ( ) ;
245
+ if * lateral {
246
+ s += "LATERAL " ;
247
+ }
248
+ s += & format ! ( "({})" , subquery. to_string( ) ) ;
240
249
if let Some ( alias) = alias {
241
250
s += & format ! ( " AS {}" , alias) ;
242
251
}
Original file line number Diff line number Diff line change @@ -1464,11 +1464,18 @@ impl Parser {
1464
1464
1465
1465
/// A table name or a parenthesized subquery, followed by optional `[AS] alias`
1466
1466
pub fn parse_table_factor ( & mut self ) -> Result < TableFactor , ParserError > {
1467
+ let lateral = self . parse_keyword ( "LATERAL" ) ;
1467
1468
if self . consume_token ( & Token :: LParen ) {
1468
1469
let subquery = Box :: new ( self . parse_query ( ) ?) ;
1469
1470
self . expect_token ( & Token :: RParen ) ?;
1470
1471
let alias = self . parse_optional_alias ( keywords:: RESERVED_FOR_TABLE_ALIAS ) ?;
1471
- Ok ( TableFactor :: Derived { subquery, alias } )
1472
+ Ok ( TableFactor :: Derived {
1473
+ lateral,
1474
+ subquery,
1475
+ alias,
1476
+ } )
1477
+ } else if lateral {
1478
+ self . expected ( "subquery after LATERAL" , self . peek_token ( ) )
1472
1479
} else {
1473
1480
let name = self . parse_object_name ( ) ?;
1474
1481
// Postgres, MSSQL: table-valued functions:
Original file line number Diff line number Diff line change @@ -1559,6 +1559,50 @@ fn parse_fetch_variations() {
1559
1559
) ;
1560
1560
}
1561
1561
1562
+ #[ test]
1563
+ fn lateral_derived ( ) {
1564
+ fn chk ( lateral_in : bool ) {
1565
+ let lateral_str = if lateral_in { "LATERAL " } else { "" } ;
1566
+ let sql = format ! (
1567
+ "SELECT * FROM customer LEFT JOIN {}\
1568
+ (SELECT * FROM order WHERE order.customer = customer.id LIMIT 3) AS order ON true",
1569
+ lateral_str
1570
+ ) ;
1571
+ let select = verified_only_select ( & sql) ;
1572
+ assert_eq ! ( select. joins. len( ) , 1 ) ;
1573
+ assert_eq ! (
1574
+ select. joins[ 0 ] . join_operator,
1575
+ JoinOperator :: LeftOuter ( JoinConstraint :: On ( ASTNode :: SQLValue ( Value :: Boolean ( true ) ) ) )
1576
+ ) ;
1577
+ if let TableFactor :: Derived {
1578
+ lateral,
1579
+ ref subquery,
1580
+ ref alias,
1581
+ } = select. joins [ 0 ] . relation
1582
+ {
1583
+ assert_eq ! ( lateral_in, lateral) ;
1584
+ assert_eq ! ( Some ( "order" . to_string( ) ) , * alias) ;
1585
+ assert_eq ! (
1586
+ subquery. to_string( ) ,
1587
+ "SELECT * FROM order WHERE order.customer = customer.id LIMIT 3"
1588
+ ) ;
1589
+ } else {
1590
+ unreachable ! ( )
1591
+ }
1592
+ }
1593
+ chk ( false ) ;
1594
+ chk ( true ) ;
1595
+
1596
+ let sql = "SELECT * FROM customer LEFT JOIN LATERAL generate_series(1, customer.id)" ;
1597
+ let res = parse_sql_statements ( sql) ;
1598
+ assert_eq ! (
1599
+ ParserError :: ParserError (
1600
+ "Expected subquery after LATERAL, found: generate_series" . to_string( )
1601
+ ) ,
1602
+ res. unwrap_err( )
1603
+ ) ;
1604
+ }
1605
+
1562
1606
#[ test]
1563
1607
#[ should_panic(
1564
1608
expected = "Parse results with GenericSqlDialect are different from PostgreSqlDialect"
You can’t perform that action at this time.
0 commit comments