@@ -12341,6 +12341,92 @@ fn parse_create_table_with_bit_types() {
12341
12341
}
12342
12342
}
12343
12343
12344
+ #[ test]
12345
+ fn parse_composite_access_expr ( ) {
12346
+ assert_eq ! (
12347
+ verified_expr( "f(a).b" ) ,
12348
+ Expr :: CompositeAccess {
12349
+ expr: Box :: new( Expr :: Function ( Function {
12350
+ name: ObjectName ( vec![ Ident :: new( "f" ) ] ) ,
12351
+ uses_odbc_syntax: false ,
12352
+ parameters: FunctionArguments :: None ,
12353
+ args: FunctionArguments :: List ( FunctionArgumentList {
12354
+ duplicate_treatment: None ,
12355
+ args: vec![ FunctionArg :: Unnamed ( FunctionArgExpr :: Expr (
12356
+ Expr :: Identifier ( Ident :: new( "a" ) )
12357
+ ) ) ] ,
12358
+ clauses: vec![ ] ,
12359
+ } ) ,
12360
+ null_treatment: None ,
12361
+ filter: None ,
12362
+ over: None ,
12363
+ within_group: vec![ ]
12364
+ } ) ) ,
12365
+ key: Ident :: new( "b" )
12366
+ }
12367
+ ) ;
12368
+
12369
+ // Nested Composite Access
12370
+ assert_eq ! (
12371
+ verified_expr( "f(a).b.c" ) ,
12372
+ Expr :: CompositeAccess {
12373
+ expr: Box :: new( Expr :: CompositeAccess {
12374
+ expr: Box :: new( Expr :: Function ( Function {
12375
+ name: ObjectName ( vec![ Ident :: new( "f" ) ] ) ,
12376
+ uses_odbc_syntax: false ,
12377
+ parameters: FunctionArguments :: None ,
12378
+ args: FunctionArguments :: List ( FunctionArgumentList {
12379
+ duplicate_treatment: None ,
12380
+ args: vec![ FunctionArg :: Unnamed ( FunctionArgExpr :: Expr (
12381
+ Expr :: Identifier ( Ident :: new( "a" ) )
12382
+ ) ) ] ,
12383
+ clauses: vec![ ] ,
12384
+ } ) ,
12385
+ null_treatment: None ,
12386
+ filter: None ,
12387
+ over: None ,
12388
+ within_group: vec![ ]
12389
+ } ) ) ,
12390
+ key: Ident :: new( "b" )
12391
+ } ) ,
12392
+ key: Ident :: new( "c" )
12393
+ }
12394
+ ) ;
12395
+
12396
+ // Composite Access in Select and Where Clauses
12397
+ let stmt = verified_only_select ( "SELECT f(a).b FROM t WHERE f(a).b IS NOT NULL" ) ;
12398
+ let expr = Expr :: CompositeAccess {
12399
+ expr : Box :: new ( Expr :: Function ( Function {
12400
+ name : ObjectName ( vec ! [ Ident :: new( "f" ) ] ) ,
12401
+ uses_odbc_syntax : false ,
12402
+ parameters : FunctionArguments :: None ,
12403
+ args : FunctionArguments :: List ( FunctionArgumentList {
12404
+ duplicate_treatment : None ,
12405
+ args : vec ! [ FunctionArg :: Unnamed ( FunctionArgExpr :: Expr (
12406
+ Expr :: Identifier ( Ident :: new( "a" ) ) ,
12407
+ ) ) ] ,
12408
+ clauses : vec ! [ ] ,
12409
+ } ) ,
12410
+ null_treatment : None ,
12411
+ filter : None ,
12412
+ over : None ,
12413
+ within_group : vec ! [ ] ,
12414
+ } ) ) ,
12415
+ key : Ident :: new ( "b" ) ,
12416
+ } ;
12417
+
12418
+ assert_eq ! ( stmt. projection[ 0 ] , SelectItem :: UnnamedExpr ( expr. clone( ) ) ) ;
12419
+ assert_eq ! ( stmt. selection. unwrap( ) , Expr :: IsNotNull ( Box :: new( expr) ) ) ;
12420
+
12421
+ // Composite Access with quoted identifier
12422
+ verified_only_select ( "SELECT f(a).\" an id\" " ) ;
12423
+
12424
+ // Composite Access in struct literal
12425
+ all_dialects_where ( |d| d. supports_struct_literal ( ) ) . verified_stmt (
12426
+ "SELECT * FROM t WHERE STRUCT(STRUCT(1 AS a, NULL AS b) AS c, NULL AS d).c.a IS NOT NULL" ,
12427
+ ) ;
12428
+ }
12429
+
12344
12430
#[ test]
12345
12431
fn parse_create_table_with_enum_types ( ) {
12346
12432
let sql = "CREATE TABLE t0 (foo ENUM8('a' = 1, 'b' = 2), bar ENUM16('a' = 1, 'b' = 2), baz ENUM('a', 'b'))" ;
0 commit comments