@@ -31,7 +31,7 @@ use datafusion_execution::object_store::ObjectStoreUrl;
31
31
use datafusion_execution:: { SendableRecordBatchStream , TaskContext } ;
32
32
use datafusion_expr:: { Operator , ScalarUDF , ScalarUDFImpl , Signature , Volatility } ;
33
33
use datafusion_physical_expr:: expressions:: {
34
- binary, col, BinaryExpr , CaseExpr , CastExpr , Column , Literal , NegativeExpr ,
34
+ binary, cast , col, BinaryExpr , CaseExpr , CastExpr , Column , Literal , NegativeExpr ,
35
35
} ;
36
36
use datafusion_physical_expr:: ScalarFunctionExpr ;
37
37
use datafusion_physical_expr:: {
@@ -1383,28 +1383,29 @@ fn test_union_after_projection() -> Result<()> {
1383
1383
Ok ( ( ) )
1384
1384
}
1385
1385
1386
- #[ test]
1387
- fn test_partition_col_projection_pushdown ( ) -> Result < ( ) > {
1386
+ /// Returns a DataSourceExec that scans a file with (int_col, string_col)
1387
+ /// and has a partitioning column partition_col (Utf8)
1388
+ fn partitioned_data_source ( ) -> Arc < DataSourceExec > {
1388
1389
let file_schema = Arc :: new ( Schema :: new ( vec ! [
1389
1390
Field :: new( "int_col" , DataType :: Int32 , true ) ,
1390
1391
Field :: new( "string_col" , DataType :: Utf8 , true ) ,
1391
1392
] ) ) ;
1392
1393
1393
- let partitioned_schema = Arc :: new ( Schema :: new ( vec ! [
1394
- Field :: new( "int_col" , DataType :: Int32 , true ) ,
1395
- Field :: new( "string_col" , DataType :: Utf8 , true ) ,
1396
- Field :: new( "partition_col" , DataType :: Utf8 , true ) ,
1397
- ] ) ) ;
1398
-
1399
- let source = FileScanConfig :: new (
1394
+ FileScanConfig :: new (
1400
1395
ObjectStoreUrl :: parse ( "test:///" ) . unwrap ( ) ,
1401
1396
file_schema. clone ( ) ,
1402
1397
Arc :: new ( CsvSource :: default ( ) ) ,
1403
1398
)
1404
1399
. with_file ( PartitionedFile :: new ( "x" . to_string ( ) , 100 ) )
1405
1400
. with_table_partition_cols ( vec ! [ Field :: new( "partition_col" , DataType :: Utf8 , true ) ] )
1406
1401
. with_projection ( Some ( vec ! [ 0 , 1 , 2 ] ) )
1407
- . build ( ) ;
1402
+ . build ( )
1403
+ }
1404
+
1405
+ #[ test]
1406
+ fn test_partition_col_projection_pushdown ( ) -> Result < ( ) > {
1407
+ let source = partitioned_data_source ( ) ;
1408
+ let partitioned_schema = source. schema ( ) ;
1408
1409
1409
1410
let projection = Arc :: new ( ProjectionExec :: try_new (
1410
1411
vec ! [
@@ -1427,8 +1428,50 @@ fn test_partition_col_projection_pushdown() -> Result<()> {
1427
1428
let after_optimize =
1428
1429
ProjectionPushdown :: new ( ) . optimize ( projection, & ConfigOptions :: new ( ) ) ?;
1429
1430
1430
- let expected = [ "ProjectionExec: expr=[string_col@1 as string_col, partition_col@2 as partition_col, int_col@0 as int_col]" ,
1431
- " DataSourceExec: file_groups={1 group: [[x]]}, projection=[int_col, string_col, partition_col], file_type=csv, has_header=false" ] ;
1431
+ let expected = [
1432
+ "ProjectionExec: expr=[string_col@1 as string_col, partition_col@2 as partition_col, int_col@0 as int_col]" ,
1433
+ " DataSourceExec: file_groups={1 group: [[x]]}, projection=[int_col, string_col, partition_col], file_type=csv, has_header=false"
1434
+ ] ;
1435
+ assert_eq ! ( get_plan_string( & after_optimize) , expected) ;
1436
+
1437
+ Ok ( ( ) )
1438
+ }
1439
+
1440
+ #[ test]
1441
+ fn test_partition_col_projection_pushdown_expr ( ) -> Result < ( ) > {
1442
+ let source = partitioned_data_source ( ) ;
1443
+ let partitioned_schema = source. schema ( ) ;
1444
+
1445
+ let projection = Arc :: new ( ProjectionExec :: try_new (
1446
+ vec ! [
1447
+ (
1448
+ col( "string_col" , partitioned_schema. as_ref( ) ) ?,
1449
+ "string_col" . to_string( ) ,
1450
+ ) ,
1451
+ (
1452
+ // CAST(partition_col, Utf8View)
1453
+ cast(
1454
+ col( "partition_col" , partitioned_schema. as_ref( ) ) ?,
1455
+ partitioned_schema. as_ref( ) ,
1456
+ DataType :: Utf8View ,
1457
+ ) ?,
1458
+ "partition_col" . to_string( ) ,
1459
+ ) ,
1460
+ (
1461
+ col( "int_col" , partitioned_schema. as_ref( ) ) ?,
1462
+ "int_col" . to_string( ) ,
1463
+ ) ,
1464
+ ] ,
1465
+ source,
1466
+ ) ?) ;
1467
+
1468
+ let after_optimize =
1469
+ ProjectionPushdown :: new ( ) . optimize ( projection, & ConfigOptions :: new ( ) ) ?;
1470
+
1471
+ let expected = [
1472
+ "ProjectionExec: expr=[string_col@1 as string_col, CAST(partition_col@2 AS Utf8View) as partition_col, int_col@0 as int_col]" ,
1473
+ " DataSourceExec: file_groups={1 group: [[x]]}, projection=[int_col, string_col, partition_col], file_type=csv, has_header=false"
1474
+ ] ;
1432
1475
assert_eq ! ( get_plan_string( & after_optimize) , expected) ;
1433
1476
1434
1477
Ok ( ( ) )
0 commit comments