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 @@ -1390,11 +1390,18 @@ impl Parser {
1390
1390
1391
1391
/// A table name or a parenthesized subquery, followed by optional `[AS] alias`
1392
1392
pub fn parse_table_factor ( & mut self ) -> Result < TableFactor , ParserError > {
1393
+ let lateral = self . parse_keyword ( "LATERAL" ) ;
1393
1394
if self . consume_token ( & Token :: LParen ) {
1394
1395
let subquery = Box :: new ( self . parse_query ( ) ?) ;
1395
1396
self . expect_token ( & Token :: RParen ) ?;
1396
1397
let alias = self . parse_optional_alias ( keywords:: RESERVED_FOR_TABLE_ALIAS ) ?;
1397
- Ok ( TableFactor :: Derived { subquery, alias } )
1398
+ Ok ( TableFactor :: Derived {
1399
+ lateral,
1400
+ subquery,
1401
+ alias,
1402
+ } )
1403
+ } else if lateral {
1404
+ self . expected ( "subquery after LATERAL" , self . peek_token ( ) )
1398
1405
} else {
1399
1406
let name = self . parse_object_name ( ) ?;
1400
1407
// Postgres, MSSQL: table-valued functions:
Original file line number Diff line number Diff line change @@ -1390,6 +1390,50 @@ fn parse_fetch_variations() {
1390
1390
) ;
1391
1391
}
1392
1392
1393
+ #[ test]
1394
+ fn lateral_derived ( ) {
1395
+ fn chk ( lateral_in : bool ) {
1396
+ let lateral_str = if lateral_in { "LATERAL " } else { "" } ;
1397
+ let sql = format ! (
1398
+ "SELECT * FROM customer LEFT JOIN {}\
1399
+ (SELECT * FROM order WHERE order.customer = customer.id LIMIT 3) AS order ON true",
1400
+ lateral_str
1401
+ ) ;
1402
+ let select = verified_only_select ( & sql) ;
1403
+ assert_eq ! ( select. joins. len( ) , 1 ) ;
1404
+ assert_eq ! (
1405
+ select. joins[ 0 ] . join_operator,
1406
+ JoinOperator :: LeftOuter ( JoinConstraint :: On ( ASTNode :: SQLValue ( Value :: Boolean ( true ) ) ) )
1407
+ ) ;
1408
+ if let TableFactor :: Derived {
1409
+ lateral,
1410
+ ref subquery,
1411
+ ref alias,
1412
+ } = select. joins [ 0 ] . relation
1413
+ {
1414
+ assert_eq ! ( lateral_in, lateral) ;
1415
+ assert_eq ! ( Some ( "order" . to_string( ) ) , * alias) ;
1416
+ assert_eq ! (
1417
+ subquery. to_string( ) ,
1418
+ "SELECT * FROM order WHERE order.customer = customer.id LIMIT 3"
1419
+ ) ;
1420
+ } else {
1421
+ unreachable ! ( )
1422
+ }
1423
+ }
1424
+ chk ( false ) ;
1425
+ chk ( true ) ;
1426
+
1427
+ let sql = "SELECT * FROM customer LEFT JOIN LATERAL generate_series(1, customer.id)" ;
1428
+ let res = parse_sql_statements ( sql) ;
1429
+ assert_eq ! (
1430
+ ParserError :: ParserError (
1431
+ "Expected subquery after LATERAL, found: generate_series" . to_string( )
1432
+ ) ,
1433
+ res. unwrap_err( )
1434
+ ) ;
1435
+ }
1436
+
1393
1437
#[ test]
1394
1438
#[ should_panic(
1395
1439
expected = "Parse results with GenericSqlDialect are different from PostgreSqlDialect"
You can’t perform that action at this time.
0 commit comments