Skip to content

Commit 5ec3c15

Browse files
committed
add another test
1 parent 8252b62 commit 5ec3c15

File tree

1 file changed

+81
-0
lines changed
  • datafusion/core/src/datasource/physical_plan

1 file changed

+81
-0
lines changed

datafusion/core/src/datasource/physical_plan/parquet.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,87 @@ mod tests {
464464
assert_eq!(metric, 2, "Expected all rows to be pruned");
465465
}
466466

467+
#[tokio::test]
468+
async fn test_pushdown_with_missing_column_nested_conditions() {
469+
// Create test data with c1 and c3 columns
470+
let c1: ArrayRef = Arc::new(Int32Array::from(vec![1, 2, 3, 4, 5]));
471+
let c3: ArrayRef = Arc::new(Int32Array::from(vec![10, 20, 30, 40, 50]));
472+
473+
let file_schema = Arc::new(Schema::new(vec![
474+
Field::new("c1", DataType::Int32, true),
475+
Field::new("c3", DataType::Int32, true),
476+
]));
477+
478+
let table_schema = Arc::new(Schema::new(vec![
479+
Field::new("c1", DataType::Int32, true),
480+
Field::new("c2", DataType::Int32, true),
481+
Field::new("c3", DataType::Int32, true),
482+
]));
483+
484+
let batch = RecordBatch::try_new(file_schema.clone(), vec![c1, c3]).unwrap();
485+
486+
// Test with complex nested AND/OR:
487+
// (c1 = 1 OR c2 = 5) AND (c3 = 10 OR c2 IS NULL)
488+
// Should return 1 row where c1=1 AND c3=10 (since c2 IS NULL is always true)
489+
let filter = col("c1")
490+
.eq(lit(1_i32))
491+
.or(col("c2").eq(lit(5_i32)))
492+
.and(col("c3").eq(lit(10_i32)).or(col("c2").is_null()));
493+
494+
let rt = RoundTrip::new()
495+
.with_schema(table_schema.clone())
496+
.with_predicate(filter.clone())
497+
.with_pushdown_predicate()
498+
.round_trip(vec![batch.clone()])
499+
.await;
500+
501+
let batches = rt.batches.unwrap();
502+
#[rustfmt::skip]
503+
let expected = [
504+
"+----+----+----+",
505+
"| c1 | c2 | c3 |",
506+
"+----+----+----+",
507+
"| 1 | | 10 |",
508+
"+----+----+----+",
509+
];
510+
assert_batches_sorted_eq!(expected, &batches);
511+
let metrics = rt.parquet_exec.metrics().unwrap();
512+
let metric = get_value(&metrics, "pushdown_rows_pruned");
513+
assert_eq!(metric, 4, "Expected 4 rows to be pruned");
514+
515+
// Test a more complex nested condition:
516+
// (c1 < 3 AND c2 IS NOT NULL) OR (c3 > 20 AND c2 IS NULL)
517+
// First part should return 0 rows (c2 IS NOT NULL is always false)
518+
// Second part should return rows where c3 > 20 (3 rows: where c3 is 30, 40, 50)
519+
let filter = col("c1")
520+
.lt(lit(3_i32))
521+
.and(col("c2").is_not_null())
522+
.or(col("c3").gt(lit(20_i32)).and(col("c2").is_null()));
523+
524+
let rt = RoundTrip::new()
525+
.with_schema(table_schema)
526+
.with_predicate(filter.clone())
527+
.with_pushdown_predicate()
528+
.round_trip(vec![batch])
529+
.await;
530+
531+
let batches = rt.batches.unwrap();
532+
#[rustfmt::skip]
533+
let expected = [
534+
"+----+----+----+",
535+
"| c1 | c2 | c3 |",
536+
"+----+----+----+",
537+
"| 3 | | 30 |",
538+
"| 4 | | 40 |",
539+
"| 5 | | 50 |",
540+
"+----+----+----+",
541+
];
542+
assert_batches_sorted_eq!(expected, &batches);
543+
let metrics = rt.parquet_exec.metrics().unwrap();
544+
let metric = get_value(&metrics, "pushdown_rows_pruned");
545+
assert_eq!(metric, 2, "Expected 2 rows to be pruned");
546+
}
547+
467548
#[tokio::test]
468549
async fn evolved_schema() {
469550
let c1: ArrayRef =

0 commit comments

Comments
 (0)