@@ -12341,6 +12341,92 @@ fn parse_create_table_with_bit_types() {
1234112341 }
1234212342}
1234312343
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+
1234412430#[ test]
1234512431fn parse_create_table_with_enum_types ( ) {
1234612432 let sql = "CREATE TABLE t0 (foo ENUM8('a' = 1, 'b' = 2), bar ENUM16('a' = 1, 'b' = 2), baz ENUM('a', 'b'))" ;
0 commit comments