risingwavelabs/risingwave · error
inequal condition from the same side should be push down in
Error message
inequal condition from the same side should be push down in optimizer
What it means
get_inequality_desc_from_predicate requires the ASOF join's single inequality condition to reference both left and right sides. An inequality whose operands come from the same side should have been pushed down earlier; encountering one here is rejected with bail! (an error, returned to the caller).
Source
Thrown at src/frontend/src/optimizer/plan_node/logical_join.rs:1581
let batch_join = BatchHashJoin::new(logical_join, asof_desc);
Ok(batch_join.into())
}
pub fn get_inequality_desc_from_predicate(
predicate: Condition,
left_input_len: usize,
) -> Result<AsOfJoinDesc> {
let expr: ExprImpl = predicate.into();
if let Some((left_input_ref, expr_type, right_input_ref)) = expr.as_comparison_cond() {
if left_input_ref.index() < left_input_len && right_input_ref.index() >= left_input_len
{
Ok(AsOfJoinDesc {
left_idx: left_input_ref.index() as u32,
right_idx: (right_input_ref.index() - left_input_len) as u32,
inequality_type: Self::expr_type_to_comparison_type(expr_type)?.into(),
})
} else {
bail!("inequal condition from the same side should be push down in optimizer");
}
} else {
Err(ErrorCode::InvalidInputSyntax(
"AsOf join requires exactly 1 ineuquality condition".to_owned(),
)
.into())
}
}
fn expr_type_to_comparison_type(expr_type: PbType) -> Result<PbAsOfJoinInequalityType> {
match expr_type {
PbType::LessThan => Ok(PbAsOfJoinInequalityType::AsOfInequalityTypeLt),
PbType::LessThanOrEqual => Ok(PbAsOfJoinInequalityType::AsOfInequalityTypeLe),
PbType::GreaterThan => Ok(PbAsOfJoinInequalityType::AsOfInequalityTypeGt),
PbType::GreaterThanOrEqual => Ok(PbAsOfJoinInequalityType::AsOfInequalityTypeGe),
_ => Err(ErrorCode::InvalidInputSyntax(format!(
"Invalid comparison type: {}",
expr_type.as_str_name()View on GitHub (pinned to 6469eb736d)
Solutions
- Move same-side predicates out of the ON clause into a WHERE clause or a subquery filter
- Ensure predicate pushdown runs before asof join stream conversion
- Keep exactly one left-vs-right inequality condition in the ASOF ON clause
- Check the query contains only the required one inequality (error otherwise: 'requires exactly 1 ineuquality condition')
Example fix
-- before SELECT * FROM t ASOF JOIN d ON t.id = d.id AND t.ts <= d.ts AND t.x < t.y; -- after SELECT * FROM (SELECT * FROM t WHERE x < y) t ASOF JOIN d ON t.id = d.id AND t.ts <= d.ts;
Defensive patterns
Strategy: validation
Validate before calling
// before creating an ASOF join, ensure the ON clause has exactly one cross-side inequality and no same-side predicates: // same-side comparisons belong in WHERE
Try / catch
match asof_conversion_result { Err(e) if e.to_string().contains("same side") => rewrite_query_with_where_filter(), ... } Prevention
- Put same-side predicates in WHERE, not ON
- Keep exactly one left-vs-right inequality in ASOF ON
- Run predicate pushdown before ASOF stream conversion
When it happens
Trigger: ASOF join whose OTHER condition contains a comparison between two columns of the same input side (e.g. `t1.a < t1.b`) instead of a left-right inequality like `t1.ts <= t2.ts`.
Common situations: Users writing ASOF joins with extra same-side predicates in ON; frontend pushdown rules failing to remove them before stream conversion.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- core predicate must exist
- call predicate_pushdown of the PlanRef instead of calling di
- should always have a stream key in the stream plan but not,
- update should always be converted to batch plan
- Expected at most 1 clean_watermark_index per table, got {:?}
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/02a8b2c3c17d1310.
Report an issue: GitHub.