@@ -23,7 +23,7 @@ use super::{
23
23
} ;
24
24
use crate :: {
25
25
datasource:: file_format:: { file_compression_type:: FileCompressionType , FileFormat } ,
26
- datasource:: { create_ordering , physical_plan:: FileSinkConfig } ,
26
+ datasource:: physical_plan:: FileSinkConfig ,
27
27
execution:: context:: SessionState ,
28
28
} ;
29
29
use arrow:: datatypes:: { DataType , Field , SchemaBuilder , SchemaRef } ;
@@ -32,7 +32,7 @@ use async_trait::async_trait;
32
32
use datafusion_catalog:: { Session , TableProvider } ;
33
33
use datafusion_common:: {
34
34
config_datafusion_err, config_err, internal_err, plan_err, project_schema,
35
- stats:: Precision , Constraints , DataFusionError , Result , SchemaExt ,
35
+ stats:: Precision , Constraints , DFSchema , DataFusionError , Result , SchemaExt ,
36
36
} ;
37
37
use datafusion_datasource:: {
38
38
compute_all_files_statistics,
@@ -45,16 +45,19 @@ use datafusion_execution::{
45
45
cache:: { cache_manager:: FileStatisticsCache , cache_unit:: DefaultFileStatisticsCache } ,
46
46
config:: SessionConfig ,
47
47
} ;
48
+ use datafusion_expr:: execution_props:: ExecutionProps ;
48
49
use datafusion_expr:: {
49
50
dml:: InsertOp , Expr , SortExpr , TableProviderFilterPushDown , TableType ,
50
51
} ;
52
+ use datafusion_physical_expr:: create_lex_orderings;
51
53
use datafusion_physical_expr_adapter:: PhysicalExprAdapterFactory ;
52
54
use datafusion_physical_expr_common:: sort_expr:: LexOrdering ;
53
55
use datafusion_physical_plan:: { empty:: EmptyExec , ExecutionPlan , Statistics } ;
54
56
use futures:: { future, stream, Stream , StreamExt , TryStreamExt } ;
55
57
use itertools:: Itertools ;
56
58
use object_store:: ObjectStore ;
57
59
use std:: { any:: Any , collections:: HashMap , str:: FromStr , sync:: Arc } ;
60
+
58
61
/// Indicates the source of the schema for a [`ListingTable`]
59
62
// PartialEq required for assert_eq! in tests
60
63
#[ derive( Debug , Clone , Copy , PartialEq , Default ) ]
@@ -1126,8 +1129,12 @@ impl ListingTable {
1126
1129
}
1127
1130
1128
1131
/// If file_sort_order is specified, creates the appropriate physical expressions
1129
- fn try_create_output_ordering ( & self ) -> Result < Vec < LexOrdering > > {
1130
- create_ordering ( & self . table_schema , & self . options . file_sort_order )
1132
+ fn try_create_output_ordering (
1133
+ & self ,
1134
+ execution_props : & ExecutionProps ,
1135
+ ) -> Result < Vec < LexOrdering > > {
1136
+ let df_schema = DFSchema :: try_from ( Arc :: clone ( & self . table_schema ) ) ?;
1137
+ create_lex_orderings ( & self . options . file_sort_order , & df_schema, execution_props)
1131
1138
}
1132
1139
}
1133
1140
@@ -1199,7 +1206,7 @@ impl TableProvider for ListingTable {
1199
1206
return Ok ( Arc :: new ( EmptyExec :: new ( projected_schema) ) ) ;
1200
1207
}
1201
1208
1202
- let output_ordering = self . try_create_output_ordering ( ) ?;
1209
+ let output_ordering = self . try_create_output_ordering ( state . execution_props ( ) ) ?;
1203
1210
match state
1204
1211
. config_options ( )
1205
1212
. execution
@@ -1334,7 +1341,7 @@ impl TableProvider for ListingTable {
1334
1341
file_extension : self . options ( ) . format . get_ext ( ) ,
1335
1342
} ;
1336
1343
1337
- let orderings = self . try_create_output_ordering ( ) ?;
1344
+ let orderings = self . try_create_output_ordering ( state . execution_props ( ) ) ?;
1338
1345
// It is sufficient to pass only one of the equivalent orderings:
1339
1346
let order_requirements = orderings. into_iter ( ) . next ( ) . map ( Into :: into) ;
1340
1347
@@ -1562,6 +1569,7 @@ mod tests {
1562
1569
SchemaAdapter , SchemaAdapterFactory , SchemaMapper ,
1563
1570
} ;
1564
1571
use datafusion_expr:: { BinaryExpr , LogicalPlanBuilder , Operator } ;
1572
+ use datafusion_physical_expr:: expressions:: binary;
1565
1573
use datafusion_physical_expr:: PhysicalSortExpr ;
1566
1574
use datafusion_physical_plan:: { collect, ExecutionPlanProperties } ;
1567
1575
use rstest:: rstest;
@@ -1694,29 +1702,44 @@ mod tests {
1694
1702
1695
1703
use crate :: datasource:: file_format:: parquet:: ParquetFormat ;
1696
1704
use datafusion_physical_plan:: expressions:: col as physical_col;
1705
+ use datafusion_physical_plan:: expressions:: lit as physical_lit;
1697
1706
use std:: ops:: Add ;
1698
1707
1699
1708
// (file_sort_order, expected_result)
1700
1709
let cases = vec ! [
1701
- ( vec![ ] , Ok ( Vec :: <LexOrdering >:: new( ) ) ) ,
1710
+ (
1711
+ vec![ ] ,
1712
+ Ok :: <Vec <LexOrdering >, DataFusionError >( Vec :: <LexOrdering >:: new( ) ) ,
1713
+ ) ,
1702
1714
// sort expr, but non column
1703
1715
(
1704
- vec![ vec![
1705
- col( "int_col" ) . add( lit( 1 ) ) . sort( true , true ) ,
1706
- ] ] ,
1707
- Err ( "Expected single column reference in sort_order[0][0], got int_col + Int32(1)" ) ,
1716
+ vec![ vec![ col( "int_col" ) . add( lit( 1 ) ) . sort( true , true ) ] ] ,
1717
+ Ok ( vec![ [ PhysicalSortExpr {
1718
+ expr: binary(
1719
+ physical_col( "int_col" , & schema) . unwrap( ) ,
1720
+ Operator :: Plus ,
1721
+ physical_lit( 1 ) ,
1722
+ & schema,
1723
+ )
1724
+ . unwrap( ) ,
1725
+ options: SortOptions {
1726
+ descending: false ,
1727
+ nulls_first: true ,
1728
+ } ,
1729
+ } ]
1730
+ . into( ) ] ) ,
1708
1731
) ,
1709
1732
// ok with one column
1710
1733
(
1711
1734
vec![ vec![ col( "string_col" ) . sort( true , false ) ] ] ,
1712
1735
Ok ( vec![ [ PhysicalSortExpr {
1713
- expr: physical_col( "string_col" , & schema) . unwrap( ) ,
1714
- options: SortOptions {
1715
- descending: false ,
1716
- nulls_first: false ,
1717
- } ,
1718
- } ] . into ( ) ,
1719
- ] )
1736
+ expr: physical_col( "string_col" , & schema) . unwrap( ) ,
1737
+ options: SortOptions {
1738
+ descending: false ,
1739
+ nulls_first: false ,
1740
+ } ,
1741
+ } ]
1742
+ . into ( ) ] ) ,
1720
1743
) ,
1721
1744
// ok with two columns, different options
1722
1745
(
@@ -1725,14 +1748,18 @@ mod tests {
1725
1748
col( "int_col" ) . sort( false , true ) ,
1726
1749
] ] ,
1727
1750
Ok ( vec![ [
1728
- PhysicalSortExpr :: new_default( physical_col( "string_col" , & schema) . unwrap( ) )
1729
- . asc( )
1730
- . nulls_last( ) ,
1731
- PhysicalSortExpr :: new_default( physical_col( "int_col" , & schema) . unwrap( ) )
1732
- . desc( )
1733
- . nulls_first( )
1734
- ] . into( ) ,
1735
- ] )
1751
+ PhysicalSortExpr :: new_default(
1752
+ physical_col( "string_col" , & schema) . unwrap( ) ,
1753
+ )
1754
+ . asc( )
1755
+ . nulls_last( ) ,
1756
+ PhysicalSortExpr :: new_default(
1757
+ physical_col( "int_col" , & schema) . unwrap( ) ,
1758
+ )
1759
+ . desc( )
1760
+ . nulls_first( ) ,
1761
+ ]
1762
+ . into( ) ] ) ,
1736
1763
) ,
1737
1764
] ;
1738
1765
@@ -1745,7 +1772,8 @@ mod tests {
1745
1772
1746
1773
let table =
1747
1774
ListingTable :: try_new ( config. clone ( ) ) . expect ( "Creating the table" ) ;
1748
- let ordering_result = table. try_create_output_ordering ( ) ;
1775
+ let ordering_result =
1776
+ table. try_create_output_ordering ( state. execution_props ( ) ) ;
1749
1777
1750
1778
match ( expected_result, ordering_result) {
1751
1779
( Ok ( expected) , Ok ( result) ) => {
0 commit comments