@@ -22,7 +22,7 @@ use std::fmt;
2222
2323use crate :: {
2424 expr_vec_fmt, Aggregate , DescribeTable , Distinct , DistinctOn , DmlStatement , Expr ,
25- Filter , Join , Limit , LogicalPlan , Partitioning , Projection , RecursiveQuery ,
25+ Filter , Join , Limit , LogicalPlan , Partitioning , Pivot , Projection , RecursiveQuery ,
2626 Repartition , Sort , Subquery , SubqueryAlias , TableProviderFilterPushDown , TableScan ,
2727 Unnest , Values , Window ,
2828} ;
@@ -650,7 +650,31 @@ impl<'a, 'b> PgJsonVisitor<'a, 'b> {
650650 "StructColumn" : expr_vec_fmt!( struct_type_columns) ,
651651 } )
652652 }
653- LogicalPlan :: Pivot ( _) => todo ! ( ) ,
653+ LogicalPlan :: Pivot ( Pivot {
654+ aggregate_expr,
655+ pivot_column,
656+ pivot_values,
657+ value_subquery,
658+ ..
659+ } ) => {
660+ let mut object = json ! ( {
661+ "Node Type" : "Pivot" ,
662+ "Aggregate" : format!( "{}" , aggregate_expr) ,
663+ "Pivot Column" : format!( "{}" , pivot_column) ,
664+ } ) ;
665+
666+ if !pivot_values. is_empty ( ) {
667+ object[ "Pivot Values" ] = serde_json:: Value :: Array (
668+ pivot_values. iter ( ) . map ( |v| serde_json:: Value :: String ( v. to_string ( ) ) ) . collect ( )
669+ ) ;
670+ }
671+
672+ if value_subquery. is_some ( ) {
673+ object[ "Value Subquery" ] = serde_json:: Value :: String ( "Provided" . to_string ( ) ) ;
674+ }
675+
676+ object
677+ } ,
654678 }
655679 }
656680}
@@ -722,7 +746,10 @@ impl<'n> TreeNodeVisitor<'n> for PgJsonVisitor<'_, '_> {
722746
723747#[ cfg( test) ]
724748mod tests {
725- use arrow:: datatypes:: { DataType , Field } ;
749+ use arrow:: datatypes:: { DataType , Field , Schema } ;
750+ use datafusion_common:: { Column , DFSchema , ScalarValue } ;
751+ use std:: sync:: Arc ;
752+ use crate :: EmptyRelation ;
726753
727754 use super :: * ;
728755
@@ -744,4 +771,82 @@ mod tests {
744771 format!( "{}" , display_schema( & schema) )
745772 ) ;
746773 }
774+
775+ #[ test]
776+ fn test_pivot_to_json_value ( ) {
777+ // Create a mock schema
778+ let schema = Arc :: new ( DFSchema :: empty ( ) . to_owned ( ) ) ;
779+
780+ // Create mock pivot values
781+ let pivot_values = vec ! [
782+ ScalarValue :: Utf8 ( Some ( "A" . to_string( ) ) ) ,
783+ ScalarValue :: Utf8 ( Some ( "B" . to_string( ) ) ) ,
784+ ] ;
785+
786+ // Create a Pivot plan
787+ let pivot = Pivot {
788+ input : Arc :: new ( LogicalPlan :: EmptyRelation ( EmptyRelation {
789+ produce_one_row : false ,
790+ schema : schema. clone ( ) ,
791+ } ) ) ,
792+ aggregate_expr : Expr :: Column ( Column :: from_name ( "sum_value" ) ) ,
793+ pivot_column : Column :: from_name ( "category" ) ,
794+ pivot_values,
795+ schema : schema. clone ( ) ,
796+ value_subquery : None ,
797+ } ;
798+
799+ // Test the to_json_value function
800+ let json_value = PgJsonVisitor :: to_json_value ( & LogicalPlan :: Pivot ( pivot) ) ;
801+
802+ // Check the JSON structure
803+ assert_eq ! ( json_value[ "Node Type" ] , "Pivot" ) ;
804+ assert_eq ! ( json_value[ "Aggregate" ] , "sum_value" ) ;
805+ assert_eq ! ( json_value[ "Pivot Column" ] , "category" ) ;
806+
807+ // Check the pivot values
808+ let pivot_values = json_value[ "Pivot Values" ] . as_array ( ) . unwrap ( ) ;
809+ assert_eq ! ( pivot_values. len( ) , 2 ) ;
810+ assert_eq ! ( pivot_values[ 0 ] , "A" ) ;
811+ assert_eq ! ( pivot_values[ 1 ] , "B" ) ;
812+
813+ // Check that Value Subquery is not present
814+ assert ! ( json_value. get( "Value Subquery" ) . is_none( ) ) ;
815+ }
816+
817+ #[ test]
818+ fn test_pivot_with_subquery_to_json_value ( ) {
819+ // Create a mock schema
820+ let schema = Arc :: new ( DFSchema :: empty ( ) . to_owned ( ) ) ;
821+
822+ // Create a Pivot plan with a value subquery
823+ let pivot = Pivot {
824+ input : Arc :: new ( LogicalPlan :: EmptyRelation ( EmptyRelation {
825+ produce_one_row : false ,
826+ schema : schema. clone ( ) ,
827+ } ) ) ,
828+ aggregate_expr : Expr :: Column ( Column :: from_name ( "sum_value" ) ) ,
829+ pivot_column : Column :: from_name ( "category" ) ,
830+ pivot_values : vec ! [ ] ,
831+ schema : schema. clone ( ) ,
832+ value_subquery : Some ( Arc :: new ( LogicalPlan :: EmptyRelation ( EmptyRelation {
833+ produce_one_row : false ,
834+ schema : schema. clone ( ) ,
835+ } ) ) ) ,
836+ } ;
837+
838+ // Test the to_json_value function
839+ let json_value = PgJsonVisitor :: to_json_value ( & LogicalPlan :: Pivot ( pivot) ) ;
840+
841+ // Check the JSON structure
842+ assert_eq ! ( json_value[ "Node Type" ] , "Pivot" ) ;
843+ assert_eq ! ( json_value[ "Aggregate" ] , "sum_value" ) ;
844+ assert_eq ! ( json_value[ "Pivot Column" ] , "category" ) ;
845+
846+ // Check that pivot values are not present
847+ assert ! ( json_value. get( "Pivot Values" ) . is_none( ) ) ;
848+
849+ // Check that Value Subquery is present
850+ assert_eq ! ( json_value[ "Value Subquery" ] , "Provided" ) ;
851+ }
747852}
0 commit comments