File tree 4 files changed +81
-1
lines changed 4 files changed +81
-1
lines changed Original file line number Diff line number Diff line change @@ -401,6 +401,8 @@ pub enum Expr {
401
401
} ,
402
402
/// An array expression e.g. `ARRAY[1, 2]`
403
403
Array ( Array ) ,
404
+ /// An array subquery constructor, e.g. `array(SELECT 1 UNION SELECT 2)`
405
+ ArraySubquery ( Box < Query > ) ,
404
406
}
405
407
406
408
impl fmt:: Display for Expr {
@@ -576,6 +578,7 @@ impl fmt::Display for Expr {
576
578
}
577
579
Expr :: Exists ( s) => write ! ( f, "EXISTS ({})" , s) ,
578
580
Expr :: Subquery ( s) => write ! ( f, "({})" , s) ,
581
+ Expr :: ArraySubquery ( s) => write ! ( f, "ARRAY({})" , s) ,
579
582
Expr :: ListAgg ( listagg) => write ! ( f, "{}" , listagg) ,
580
583
Expr :: GroupingSets ( sets) => {
581
584
write ! ( f, "GROUPING SETS (" ) ?;
Original file line number Diff line number Diff line change @@ -453,6 +453,13 @@ impl<'a> Parser<'a> {
453
453
self . expect_token ( & Token :: LBracket ) ?;
454
454
self . parse_array_expr ( true )
455
455
}
456
+ Keyword :: ARRAY
457
+ if dialect_of ! ( self is PostgreSqlDialect | GenericDialect )
458
+ && self . peek_token ( ) == Token :: LParen =>
459
+ {
460
+ self . expect_token ( & Token :: LParen ) ?;
461
+ self . parse_array_subquery ( )
462
+ }
456
463
Keyword :: NOT => Ok ( Expr :: UnaryOp {
457
464
op : UnaryOperator :: Not ,
458
465
expr : Box :: new ( self . parse_subexpr ( Self :: UNARY_NOT_PREC ) ?) ,
@@ -911,6 +918,13 @@ impl<'a> Parser<'a> {
911
918
}
912
919
}
913
920
921
+ /// Parses an array subquery `ARRAY(SELECT 1 UNION SELECT 2)`
922
+ pub fn parse_array_subquery ( & mut self ) -> Result < Expr , ParserError > {
923
+ let subquery = self . parse_query ( ) ?;
924
+ self . expect_token ( & Token :: RParen ) ?;
925
+ Ok ( Expr :: ArraySubquery ( Box :: new ( subquery) ) )
926
+ }
927
+
914
928
/// Parse a SQL LISTAGG expression, e.g. `LISTAGG(...) WITHIN GROUP (ORDER BY ...)`.
915
929
pub fn parse_listagg_expr ( & mut self ) -> Result < Expr , ParserError > {
916
930
self . expect_token ( & Token :: LParen ) ?;
Original file line number Diff line number Diff line change @@ -2439,7 +2439,7 @@ fn parse_bad_constraint() {
2439
2439
2440
2440
#[ test]
2441
2441
fn parse_scalar_function_in_projection ( ) {
2442
- let names = vec ! [ "sqrt" , "array" , " foo"] ;
2442
+ let names = vec ! [ "sqrt" , "foo" ] ;
2443
2443
2444
2444
for function_name in names {
2445
2445
// like SELECT sqrt(id) FROM foo
Original file line number Diff line number Diff line change @@ -1241,6 +1241,69 @@ fn parse_array_index_expr() {
1241
1241
) ;
1242
1242
}
1243
1243
1244
+ #[ test]
1245
+ fn parse_array_subquery_expr ( ) {
1246
+ let sql = "SELECT ARRAY(SELECT 1 UNION SELECT 2)" ;
1247
+ let select = pg ( ) . verified_only_select ( sql) ;
1248
+ assert_eq ! (
1249
+ & Expr :: ArraySubquery ( Box :: new( Query {
1250
+ with: None ,
1251
+ body: SetExpr :: SetOperation {
1252
+ op: SetOperator :: Union ,
1253
+ all: false ,
1254
+ left: Box :: new( SetExpr :: Select ( Box :: new( Select {
1255
+ distinct: false ,
1256
+ top: None ,
1257
+ projection: vec![ SelectItem :: UnnamedExpr ( Expr :: Value ( Value :: Number (
1258
+ #[ cfg( not( feature = "bigdecimal" ) ) ]
1259
+ "1" . to_string( ) ,
1260
+ #[ cfg( feature = "bigdecimal" ) ]
1261
+ "1" . parse( ) . unwrap( ) ,
1262
+ false ,
1263
+ ) ) ) ] ,
1264
+ into: None ,
1265
+ from: vec![ ] ,
1266
+ lateral_views: vec![ ] ,
1267
+ selection: None ,
1268
+ group_by: vec![ ] ,
1269
+ cluster_by: vec![ ] ,
1270
+ distribute_by: vec![ ] ,
1271
+ sort_by: vec![ ] ,
1272
+ having: None ,
1273
+ qualify: None ,
1274
+ } ) ) ) ,
1275
+ right: Box :: new( SetExpr :: Select ( Box :: new( Select {
1276
+ distinct: false ,
1277
+ top: None ,
1278
+ projection: vec![ SelectItem :: UnnamedExpr ( Expr :: Value ( Value :: Number (
1279
+ #[ cfg( not( feature = "bigdecimal" ) ) ]
1280
+ "2" . to_string( ) ,
1281
+ #[ cfg( feature = "bigdecimal" ) ]
1282
+ "2" . parse( ) . unwrap( ) ,
1283
+ false ,
1284
+ ) ) ) ] ,
1285
+ into: None ,
1286
+ from: vec![ ] ,
1287
+ lateral_views: vec![ ] ,
1288
+ selection: None ,
1289
+ group_by: vec![ ] ,
1290
+ cluster_by: vec![ ] ,
1291
+ distribute_by: vec![ ] ,
1292
+ sort_by: vec![ ] ,
1293
+ having: None ,
1294
+ qualify: None ,
1295
+ } ) ) ) ,
1296
+ } ,
1297
+ order_by: vec![ ] ,
1298
+ limit: None ,
1299
+ offset: None ,
1300
+ fetch: None ,
1301
+ lock: None ,
1302
+ } ) ) ,
1303
+ expr_from_projection( only( & select. projection) ) ,
1304
+ ) ;
1305
+ }
1306
+
1244
1307
#[ test]
1245
1308
fn test_transaction_statement ( ) {
1246
1309
let statement = pg ( ) . verified_stmt ( "SET TRANSACTION SNAPSHOT '000003A1-1'" ) ;
You can’t perform that action at this time.
0 commit comments