When performing set comparison subqueries (such as > ANY / > ALL / = ANY, etc.) on the same table (without using aliases), silently returns wrong results (0 rows or all rows).
- Dominant language
- Rust
- Stars
- 9.3k
- Forks
- 2.4k
- Avg merge
- 3d 7h
- Merged PRs (30d)
- 344
Description
When the outer query and a set comparison subquery (`ANY` / `ALL`) reference the **same table without an alias**, DataFusion silently returns wrong results — no error is raised:
- ordered comparisons (`>`, `>=`, `<`, `<=`) with `ANY`/`ALL` → **0 rows** (expected non-empty)
- `= ANY` → **all rows** (expected only matching rows)
Aliasing either side (or using two different tables) produces correct results.
Verified on **54.1.0** and on the latest stable **55.1.0** (`datafusion = "55.1"`).
To Reproduce
```
CREATE TABLE emp (id INT, name TEXT, salary INT);
INSERT INTO emp VALUES
(1,'Alice',5000),(2,'Bob',6000),(3,'Carol',7000),
(4,'Dave',8000),(5,'Eve',9000),(6,'Frank',10000);
-- returns 0 rows, expected ids 2..6
SELECT id FROM emp WHERE salary > ANY (SELECT salary FROM emp WHERE id <= 3);
-- returns 0 rows, expected ids 3..6
SELECT id FROM emp WHERE salary > ALL (SELECT salary FROM emp WHERE id <= 2);
-- returns ALL 6 rows, expected ids 1,2
SELECT id FROM emp WHERE salary = ANY (SELECT salary FROM emp WHERE id <= 2);
-- workaround: aliasing either side returns correct results
SELECT e.id FROM emp e WHERE e.salary > ANY (SELECT s.salary FROM emp s WHERE s.id <= 3);
```
Standalone Rust reproducer (MemTable, no custom TableProvider):
```
use datafusion::arrow::array::{Int32Array, RecordBatch, StringArray};
use datafusion::arrow::datatypes::{DataType, Field, Schema};
use datafusion::datasource::MemTable;
use datafusion::prelude::SessionContext;
use std::sync::Arc;
#[tokio::main]
async fn main() -> datafusion::error::Result<()> {
let schema = Arc::new(Schema::new(vec![
Field::new("id", DataType::Int32, false),
Field::new("name", DataType::Utf8, true),
Field::new("salary", DataType::Int32, true),
]));
let batch = RecordBatch::try_new(
schema.clone(),
vec![
Arc::new(Int32Array::from(vec![1, 2, 3, 4, 5, 6])),
Arc::new(StringArray::from(vec!["Alice","Bob","Carol","Dave","Eve","Frank"])),
Arc::new(Int32Array::from(vec![5000, 6000, 7000, 8000, 9000, 10000])),
],
)?;
let ctx = SessionContext::new();
ctx.register_table("emp", Arc::new(MemTable::try_new(schema, vec![vec![batch]])?))?;
for sql in [
"SELECT id FROM emp WHERE salary > ANY (SELECT salary FROM emp WHERE id <= 3)",
"SELECT id FROM emp WHERE salary = ANY (SELECT salary FROM emp WHERE id <= 2)",
"SELECT e.id FROM emp e WHERE e.salary > ANY (SELECT s.salary FROM emp s WHERE s.id <= 3)",
] {
let rows = ctx.sql(sql).await?.collect().await?;
let n: usize = rows.iter().map(|b| b.num_rows()).sum();
println!("{sql} -> {n} rows");
}
Ok(())
}
```
Output on 55.1.0:
```
SELECT id FROM emp WHERE salary > ANY (SELECT salary FROM emp WHERE id <= 3) -> 0 rows -- expected 5
SELECT id FROM emp WHERE salary = ANY (SELECT salary FROM emp WHERE id <= 2) -> 6 rows -- expected 2
SELECT e.id FROM emp e WHERE e.salary > ANY (SELECT s.salary FROM emp s WHERE s.id <= 3) -> 5 rows -- correct (aliased)
```
Contributor guide
Assessment
This issue has not been assessed yet.