-
Notifications
You must be signed in to change notification settings - Fork 259
Description
Bug Description
The try_into_between function in prqlc/prqlc/src/sql/gen_expr.rs is designed to optimize a >= low AND a <= high into a BETWEEN low AND high. However, this optimization never triggers because the equality check a_l == b_l compares rq::Expr values including their span field.
Since the two references to column a in a >= 5 && a <= 10 originate from different source positions, they have different span values, causing the equality check to always fail.
Reproduction
from t | filter (a >= 5 && a <= 10)
Expected output:
SELECT * FROM t WHERE a BETWEEN 5 AND 10Actual output:
SELECT * FROM t WHERE a >= 5 AND a <= 10Root Cause
rq::Expr (in prqlc/prqlc/src/ir/rq/expr.rs) derives PartialEq, which compares both kind and span:
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, JsonSchema)]
pub struct Expr {
pub kind: ExprKind,
pub span: Option<Span>,
}In try_into_between, the check if a_l == b_l compares the full Expr including spans. The two column references to a have the same CId (same column) but different Span values (different source positions), so the comparison fails.
Suggested Fix
Compare only the kind field instead of the full Expr:
// Before:
if a_l == b_l {
// After:
if a_l.kind == b_l.kind {Impact
This is not a correctness bug -- the generated SQL is semantically equivalent. It's a dead-code / missed-optimization bug. The BETWEEN optimization code has likely never worked since it was written.