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 10
Actual output:
SELECT * FROM t WHERE a >= 5 AND a <= 10
Root 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.
Bug Description
The
try_into_betweenfunction inprqlc/prqlc/src/sql/gen_expr.rsis designed to optimizea >= low AND a <= highintoa BETWEEN low AND high. However, this optimization never triggers because the equality checka_l == b_lcomparesrq::Exprvalues including theirspanfield.Since the two references to column
aina >= 5 && a <= 10originate from different source positions, they have differentspanvalues, causing the equality check to always fail.Reproduction
Expected output:
Actual output:
Root Cause
rq::Expr(inprqlc/prqlc/src/ir/rq/expr.rs) derivesPartialEq, which compares bothkindandspan:In
try_into_between, the checkif a_l == b_lcompares the fullExprincluding spans. The two column references toahave the sameCId(same column) but differentSpanvalues (different source positions), so the comparison fails.Suggested Fix
Compare only the
kindfield instead of the fullExpr: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.