risingwavelabs/risingwave · error
`DynamicFilterExecutor` only supports comparators…
Error message
`DynamicFilterExecutor` only supports comparators: GreaterThan | GreaterThanOrEqual | LessThan | LessThanOrEqual
What it means
The DynamicFilter executor proto-to-executor conversion only supports the four ordering comparators (>, >=, <, <=). If the condition's function type is anything else (e.g. equal or non-comparison functions), `new_boxed_executor` bails, since dynamic filtering is only defined for range comparisons.
Solutions
- Fix the frontend so only ordering comparators are planned as dynamic filters.
- Rewrite the query so the predicate uses >, >=, <, or <= against the filter column.
- Upgrade stream/frontend components together so comparator support matches.
Defensive patterns
Strategy: validation
Validate before calling
// before constructing the node
let ok = matches!(comparator, GreaterThan | GreaterThanOrEqual | LessThan | LessThanOrEqual);
if !ok { /* plan it as a regular filter instead of a dynamic filter */ } Type guard
fn is_supported_comparator(c: ExprType) -> bool {
matches!(c, GreaterThan | GreaterThanOrEqual | LessThan | LessThanOrEqual)
} Prevention
- Only map ordering comparators to DynamicFilter in the planner
- Add planner assertions when lowering join/filter conditions
- Keep frontend and stream comparator enums in sync
When it happens
Trigger: Building a `DynamicFilterExecutor` from a proto node whose condition function type is not GreaterThan, GreaterThanOrEqual, LessThan, or LessThanOrEqual, e.g. a join/eq condition incorrectly mapped to a dynamic filter.
Common situations: Frontend planner mapping an equality predicate to a dynamic filter node; users writing queries whose plan lands an unsupported comparator into the dynamic filter path; version skew where new comparators are planned but the stream side is older.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- only inner join without non-equal condition is supported…
- Scalar subquery might produce more than one row.
- a stream has reached the end but some other stream has not…
- Actor exited unexpectedly
- actor exited unexpectedly
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/0cbab39bebfddf69.
Report an issue: GitHub.
Appendix: source
Thrown at src/stream/src/from_proto/dynamic_filter.rs:50
type Node = DynamicFilterNode;
async fn new_boxed_executor(
params: ExecutorParams,
node: &Self::Node,
store: impl StateStore,
) -> StreamResult<Executor> {
let [source_l, source_r]: [_; 2] = params.input.try_into().unwrap();
let key_l = node.get_left_key() as usize;
let vnodes = params.vnode_bitmap.map(Arc::new);
let prost_condition = node.get_condition()?;
let comparator = prost_condition.get_function_type()?;
if !matches!(
comparator,
GreaterThan | GreaterThanOrEqual | LessThan | LessThanOrEqual
) {
bail!(
"`DynamicFilterExecutor` only supports comparators:\
GreaterThan | GreaterThanOrEqual | LessThan | LessThanOrEqual",
);
}
let state_table_r = StateTableBuilder::new(node.get_right_table()?, store.clone(), None)
.enable_preload_all_rows_by_config(¶ms.config)
.build()
.await;
let left_table = node.get_left_table()?;
let cleaned_by_watermark = node.cleaned_by_watermark
|| #[expect(deprecated)]
left_table.cleaned_by_watermark;
let state_table_l = StateTableBuilder::new(node.get_left_table()?, store, vnodes)
.enable_preload_all_rows_by_config(¶ms.config)
.build()
.await;View on GitHub (pinned to 6469eb736d)