Skip to content

Commit ed23bd6

Browse files
feat: Improve error message on unsupported SQL subquery comparisons (#25135)
1 parent 7d5d966 commit ed23bd6

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

crates/polars-sql/src/sql_expr.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,18 @@ impl SQLExprVisitor<'_> {
469469
op: &SQLBinaryOperator,
470470
right: &SQLExpr,
471471
) -> PolarsResult<Expr> {
472+
// check for (unsupported) scalar subquery comparisons
473+
if matches!(left, SQLExpr::Subquery(_)) || matches!(right, SQLExpr::Subquery(_)) {
474+
let (suggestion, str_op) = match op {
475+
SQLBinaryOperator::NotEq => ("; use 'NOT IN' instead", "!=".to_string()),
476+
SQLBinaryOperator::Eq => ("; use 'IN' instead", format!("{op}")),
477+
_ => ("", format!("{op}")),
478+
};
479+
polars_bail!(
480+
SQLSyntax: "subquery comparisons with '{str_op}' are not supported{suggestion}"
481+
);
482+
}
483+
472484
// need special handling for interval offsets and comparisons
473485
let (lhs, mut rhs) = match (left, op, right) {
474486
(_, SQLBinaryOperator::Minus, SQLExpr::Interval(v)) => {

py-polars/tests/unit/sql/test_subqueries.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,3 +158,28 @@ def test_subquery_20732() -> None:
158158
)
159159
res = pl.sql("SELECT * FROM lf WHERE id IN (SELECT MAX(id) FROM lf)", eager=True)
160160
assert res.to_dict(as_series=False) == {"id": [2], "s": ["b"]}
161+
162+
163+
def test_unsupported_subquery_comparisons() -> None:
164+
"""Test that using = with a subquery gives a helpful error message."""
165+
df = pl.DataFrame({"value": [2000, 2000]}) # noqa: F841
166+
167+
for op, suggestion in (("=", "IN"), ("!=", "NOT IN")):
168+
with pytest.raises(
169+
SQLSyntaxError,
170+
match=rf"subquery comparisons with '{op}' are not supported; use '{suggestion}' instead",
171+
):
172+
pl.sql(f"SELECT * FROM df WHERE value {op} (SELECT MAX(e) FROM df)")
173+
174+
for op in ("<", "<=", ">", ">="):
175+
with pytest.raises(
176+
SQLSyntaxError,
177+
match=rf"subquery comparisons with '{op}' are not supported",
178+
):
179+
pl.sql(f"SELECT * FROM df WHERE (SELECT MAX(e) FROM df) {op} value")
180+
181+
with pytest.raises(
182+
SQLSyntaxError,
183+
match=rf"subquery comparisons with '{op}' are not supported",
184+
):
185+
pl.sql(f"SELECT * FROM df WHERE value {op} (SELECT MAX(value) FROM df)")

0 commit comments

Comments
 (0)