@@ -20,7 +20,7 @@ use arrow::{
2020 record_batch:: { RecordBatch , RecordBatchOptions } ,
2121} ;
2222use datafusion:: {
23- common:: { Result , Statistics } ,
23+ common:: { stats :: Precision , ColumnStatistics , Result , Statistics } ,
2424 execution:: context:: TaskContext ,
2525 physical_expr:: { EquivalenceProperties , PhysicalSortExpr } ,
2626 physical_plan:: {
@@ -131,7 +131,19 @@ impl ExecutionPlan for WindowExec {
131131 }
132132
133133 fn statistics ( & self ) -> Result < Statistics > {
134- todo ! ( )
134+ let input_stat = self . input . statistics ( ) ?;
135+ let win_cols = self . context . window_exprs . len ( ) ;
136+ let input_cols = self . input . schema ( ) . fields ( ) . len ( ) ;
137+ let mut column_statistics = Vec :: with_capacity ( win_cols + input_cols) ;
138+ column_statistics. extend ( input_stat. column_statistics ) ;
139+ for _ in 0 ..win_cols {
140+ column_statistics. push ( ColumnStatistics :: new_unknown ( ) )
141+ }
142+ Ok ( Statistics {
143+ num_rows : input_stat. num_rows ,
144+ column_statistics,
145+ total_byte_size : Precision :: Absent ,
146+ } )
135147 }
136148}
137149
@@ -192,6 +204,7 @@ mod test {
192204 use arrow:: { array:: * , datatypes:: * , record_batch:: RecordBatch } ;
193205 use datafusion:: {
194206 assert_batches_eq,
207+ common:: stats:: Precision ,
195208 physical_expr:: { expressions:: Column , PhysicalSortExpr } ,
196209 physical_plan:: { memory:: MemoryExec , ExecutionPlan } ,
197210 prelude:: SessionContext ,
@@ -246,30 +259,31 @@ mod test {
246259 ( "b1" , & vec ! [ 1 , 2 , 2 , 3 , 4 , 1 , 1 ] ) ,
247260 ( "c1" , & vec ! [ 0 , 0 , 0 , 0 , 0 , 0 , 0 ] ) ,
248261 ) ;
262+ let window_exprs = vec ! [
263+ WindowExpr :: new(
264+ WindowFunction :: RankLike ( WindowRankType :: RowNumber ) ,
265+ vec![ ] ,
266+ Arc :: new( Field :: new( "b1_row_number" , DataType :: Int32 , false ) ) ,
267+ ) ,
268+ WindowExpr :: new(
269+ WindowFunction :: RankLike ( WindowRankType :: Rank ) ,
270+ vec![ ] ,
271+ Arc :: new( Field :: new( "b1_rank" , DataType :: Int32 , false ) ) ,
272+ ) ,
273+ WindowExpr :: new(
274+ WindowFunction :: RankLike ( WindowRankType :: DenseRank ) ,
275+ vec![ ] ,
276+ Arc :: new( Field :: new( "b1_dense_rank" , DataType :: Int32 , false ) ) ,
277+ ) ,
278+ WindowExpr :: new(
279+ WindowFunction :: Agg ( AggFunction :: Sum ) ,
280+ vec![ Arc :: new( Column :: new( "b1" , 1 ) ) ] ,
281+ Arc :: new( Field :: new( "b1_sum" , DataType :: Int64 , false ) ) ,
282+ ) ,
283+ ] ;
249284 let window = Arc :: new ( WindowExec :: try_new (
250285 input,
251- vec ! [
252- WindowExpr :: new(
253- WindowFunction :: RankLike ( WindowRankType :: RowNumber ) ,
254- vec![ ] ,
255- Arc :: new( Field :: new( "b1_row_number" , DataType :: Int32 , false ) ) ,
256- ) ,
257- WindowExpr :: new(
258- WindowFunction :: RankLike ( WindowRankType :: Rank ) ,
259- vec![ ] ,
260- Arc :: new( Field :: new( "b1_rank" , DataType :: Int32 , false ) ) ,
261- ) ,
262- WindowExpr :: new(
263- WindowFunction :: RankLike ( WindowRankType :: DenseRank ) ,
264- vec![ ] ,
265- Arc :: new( Field :: new( "b1_dense_rank" , DataType :: Int32 , false ) ) ,
266- ) ,
267- WindowExpr :: new(
268- WindowFunction :: Agg ( AggFunction :: Sum ) ,
269- vec![ Arc :: new( Column :: new( "b1" , 1 ) ) ] ,
270- Arc :: new( Field :: new( "b1_sum" , DataType :: Int64 , false ) ) ,
271- ) ,
272- ] ,
286+ window_exprs,
273287 vec ! [ Arc :: new( Column :: new( "a1" , 0 ) ) ] ,
274288 vec ! [ PhysicalSortExpr {
275289 expr: Arc :: new( Column :: new( "b1" , 1 ) ) ,
@@ -278,6 +292,7 @@ mod test {
278292 ) ?) ;
279293 let stream = window. execute ( 0 , task_ctx. clone ( ) ) ?;
280294 let batches = datafusion:: physical_plan:: common:: collect ( stream) . await ?;
295+ let row_count = window. statistics ( ) ?. num_rows ;
281296 let expected = vec ! [
282297 "+----+----+----+---------------+---------+---------------+--------+" ,
283298 "| a1 | b1 | c1 | b1_row_number | b1_rank | b1_dense_rank | b1_sum |" ,
@@ -292,37 +307,42 @@ mod test {
292307 "+----+----+----+---------------+---------+---------------+--------+" ,
293308 ] ;
294309 assert_batches_eq ! ( expected, & batches) ;
310+ assert_eq ! (
311+ row_count,
312+ Precision :: Exact ( window_exprs. clone( ) . len( ) + input. clone( ) . schema( ) . fields( ) . len( ) )
313+ ) ;
295314
296315 // test window without partition by clause
297316 let input = build_table (
298317 ( "a1" , & vec ! [ 1 , 3 , 3 , 1 , 1 , 1 , 2 ] ) ,
299318 ( "b1" , & vec ! [ 1 , 1 , 1 , 2 , 2 , 3 , 4 ] ) ,
300319 ( "c1" , & vec ! [ 0 , 0 , 0 , 0 , 0 , 0 , 0 ] ) ,
301320 ) ;
321+ let window_exprs = vec ! [
322+ WindowExpr :: new(
323+ WindowFunction :: RankLike ( WindowRankType :: RowNumber ) ,
324+ vec![ ] ,
325+ Arc :: new( Field :: new( "b1_row_number" , DataType :: Int32 , false ) ) ,
326+ ) ,
327+ WindowExpr :: new(
328+ WindowFunction :: RankLike ( WindowRankType :: Rank ) ,
329+ vec![ ] ,
330+ Arc :: new( Field :: new( "b1_rank" , DataType :: Int32 , false ) ) ,
331+ ) ,
332+ WindowExpr :: new(
333+ WindowFunction :: RankLike ( WindowRankType :: DenseRank ) ,
334+ vec![ ] ,
335+ Arc :: new( Field :: new( "b1_dense_rank" , DataType :: Int32 , false ) ) ,
336+ ) ,
337+ WindowExpr :: new(
338+ WindowFunction :: Agg ( AggFunction :: Sum ) ,
339+ vec![ Arc :: new( Column :: new( "b1" , 1 ) ) ] ,
340+ Arc :: new( Field :: new( "b1_sum" , DataType :: Int64 , false ) ) ,
341+ ) ,
342+ ] ;
302343 let window = Arc :: new ( WindowExec :: try_new (
303344 input,
304- vec ! [
305- WindowExpr :: new(
306- WindowFunction :: RankLike ( WindowRankType :: RowNumber ) ,
307- vec![ ] ,
308- Arc :: new( Field :: new( "b1_row_number" , DataType :: Int32 , false ) ) ,
309- ) ,
310- WindowExpr :: new(
311- WindowFunction :: RankLike ( WindowRankType :: Rank ) ,
312- vec![ ] ,
313- Arc :: new( Field :: new( "b1_rank" , DataType :: Int32 , false ) ) ,
314- ) ,
315- WindowExpr :: new(
316- WindowFunction :: RankLike ( WindowRankType :: DenseRank ) ,
317- vec![ ] ,
318- Arc :: new( Field :: new( "b1_dense_rank" , DataType :: Int32 , false ) ) ,
319- ) ,
320- WindowExpr :: new(
321- WindowFunction :: Agg ( AggFunction :: Sum ) ,
322- vec![ Arc :: new( Column :: new( "b1" , 1 ) ) ] ,
323- Arc :: new( Field :: new( "b1_sum" , DataType :: Int64 , false ) ) ,
324- ) ,
325- ] ,
345+ window_exprs,
326346 vec ! [ ] ,
327347 vec ! [ PhysicalSortExpr {
328348 expr: Arc :: new( Column :: new( "b1" , 1 ) ) ,
@@ -331,6 +351,7 @@ mod test {
331351 ) ?) ;
332352 let stream = window. execute ( 0 , task_ctx. clone ( ) ) ?;
333353 let batches = datafusion:: physical_plan:: common:: collect ( stream) . await ?;
354+ let row_count = window. statistics ( ) ?. num_rows ;
334355 let expected = vec ! [
335356 "+----+----+----+---------------+---------+---------------+--------+" ,
336357 "| a1 | b1 | c1 | b1_row_number | b1_rank | b1_dense_rank | b1_sum |" ,
@@ -345,6 +366,10 @@ mod test {
345366 "+----+----+----+---------------+---------+---------------+--------+" ,
346367 ] ;
347368 assert_batches_eq ! ( expected, & batches) ;
369+ assert_eq ! (
370+ row_count,
371+ Precision :: Exact ( window_exprs. clone( ) . len( ) + input. clone( ) . schema( ) . fields( ) . len( ) )
372+ ) ;
348373 Ok ( ( ) )
349374 }
350375}
0 commit comments