@@ -728,6 +728,31 @@ fn test_lineage_schema_less_cte_star_passthrough() {
728728 ) ;
729729}
730730
731+ #[ test]
732+ fn test_lineage_nested_set_operation_inside_derived_table ( ) {
733+ let column = c ( "v" ) ;
734+ let sql = c (
735+ "SELECT v FROM ((SELECT v FROM t1 UNION ALL SELECT v FROM t2) UNION ALL SELECT v FROM t3) u" ,
736+ ) ;
737+ let dialect = c ( "duckdb" ) ;
738+ let ( status, data, error) = consume_result ( polyglot_lineage (
739+ column. as_ptr ( ) ,
740+ sql. as_ptr ( ) ,
741+ dialect. as_ptr ( ) ,
742+ ) ) ;
743+ assert_eq ! ( status, 0 , "error={error:?}" ) ;
744+ let node: Value = serde_json:: from_str ( & data. expect ( "missing lineage" ) ) . expect ( "invalid json" ) ;
745+
746+ let mut names = Vec :: new ( ) ;
747+ collect_lineage_names ( & node, & mut names) ;
748+ assert ! (
749+ names. iter( ) . any( |name| name == "t1.v" )
750+ && names. iter( ) . any( |name| name == "t2.v" )
751+ && names. iter( ) . any( |name| name == "t3.v" ) ,
752+ "expected set operation source columns in lineage names, got {names:?}"
753+ ) ;
754+ }
755+
731756#[ test]
732757fn test_lineage_recursive_cte_terminates ( ) {
733758 let column = c ( "n" ) ;
@@ -889,6 +914,42 @@ fn test_analyze_query_cte_facts_and_star_projections() {
889914 ) ;
890915}
891916
917+ #[ test]
918+ fn test_analyze_query_pivot_alias_columns ( ) {
919+ let sql = c (
920+ "SELECT region2, p1 FROM (SELECT region, q, amt FROM sales) PIVOT(SUM(amt) FOR q IN ('Q1')) AS p(region2, p1)" ,
921+ ) ;
922+ let options = c ( r#"{"dialect":"duckdb"}"# ) ;
923+ let ( status, data, error) =
924+ consume_result ( polyglot_analyze_query ( sql. as_ptr ( ) , options. as_ptr ( ) ) ) ;
925+ assert_eq ! ( status, 0 , "error={error:?}" ) ;
926+ let analysis: Value =
927+ serde_json:: from_str ( & data. expect ( "missing analyze_query payload" ) ) . expect ( "invalid json" ) ;
928+
929+ let projections = analysis[ "projections" ]
930+ . as_array ( )
931+ . expect ( "projections array" ) ;
932+ let region = projections
933+ . iter ( )
934+ . find ( |projection| projection[ "name" ] == "region2" )
935+ . expect ( "region2 projection" ) ;
936+ assert ! ( region[ "upstream" ]
937+ . as_array( )
938+ . unwrap( )
939+ . iter( )
940+ . any( |reference| { reference[ "table" ] == "sales" && reference[ "column" ] == "region" } ) ) ;
941+
942+ let pivot_value = projections
943+ . iter ( )
944+ . find ( |projection| projection[ "name" ] == "p1" )
945+ . expect ( "p1 projection" ) ;
946+ assert ! ( pivot_value[ "upstream" ]
947+ . as_array( )
948+ . unwrap( )
949+ . iter( )
950+ . any( |reference| reference[ "table" ] == "sales" && reference[ "column" ] == "amt" ) ) ;
951+ }
952+
892953#[ test]
893954fn test_analyze_query_invalid_options_json ( ) {
894955 let sql = c ( "SELECT 1" ) ;
0 commit comments