{"record":{"id":"adf02757814e8c70","repo":"risingwavelabs/risingwave","slug":"filter-can-only-receive-bool-array-adf027","errorCode":null,"errorMessage":"Filter can only receive bool array","messagePattern":"Filter can only receive bool array","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/stream/src/executor/aggregate/mod.rs","lineNumber":105,"sourceCode":"        agg_call.agg_type,\n        AggType::Builtin(PbAggKind::Min | PbAggKind::Max | PbAggKind::StringAgg)\n    ) {\n        // should skip NULL value for these kinds of agg function\n        let agg_col_idx = agg_call.args.val_indices()[0]; // the first arg is the agg column for all these kinds\n        let agg_col_bitmap = chunk.column_at(agg_col_idx).null_bitmap();\n        vis &= agg_col_bitmap;\n    }\n\n    if let Some(ref filter) = agg_call.filter {\n        // TODO: should we build `filter` in non-strict mode?\n        if let Bool(filter_res) = NonStrictExpression::new_topmost(filter.clone(), LogReport)\n            .eval_infallible(chunk)\n            .await\n            .as_ref()\n        {\n            vis &= filter_res.to_bitmap();\n        } else {\n            bail!(\"Filter can only receive bool array\");\n        }\n    }\n\n    Ok(vis)\n}\n\nfn iter_table_storage<S>(\n    state_storages: &mut [AggStateStorage<S>],\n) -> impl Iterator<Item = &mut StateTable<S>>\nwhere\n    S: StateStore,\n{\n    state_storages\n        .iter_mut()\n        .filter_map(|storage| match storage {\n            AggStateStorage::Value => None,\n            AggStateStorage::MaterializedInput { table, .. } => Some(table),\n        })","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/stream/src/executor/aggregate/mod.rs#L87-L123","documentation":"The stream aggregate executor evaluates a user-defined filter expression over a chunk and expects the result to be a boolean array used as a visibility mask. `agg_call_filter_res` bails with this error when the evaluated filter result is not a bool array, since it cannot be converted into a visibility bitmap.","triggerScenarios":"A `FILTER (WHERE ...)` clause on an aggregate (or an optimizer-inserted filter) whose expression type-checks in the frontend but evaluates to a non-boolean array at runtime in the streaming engine, e.g. a NULL-typed or non-bool projection reaching the aggregate filter slot.","commonSituations":"Frontend/stream type mismatch after planner bugs, expressions like `filter (where x)` where x is an integer, or state-restored plans created by an older RisingWave version whose schema drifted from the current executor expectations.","solutions":["Check the CREATE MATERIALIZED VIEW / aggregate query and make the FILTER clause expression explicitly boolean, e.g. `FILTER (WHERE (x)::boolean)` or `FILTER (WHERE x = 1)`.","Inspect the plan (`EXPLAIN`) to see what expression is bound to the aggregate filter and fix its type in SQL.","If the query is fine, collect the internal error and file/upgrade — this indicates a frontend type-checking gap.","If it started after a version upgrade of RisingWave, recreate the materialized view so plans are re-planned with the current frontend."],"exampleFix":"// before\nSELECT count(*) FILTER (WHERE status) FROM t; // status is int\n// after\nSELECT count(*) FILTER (WHERE status != 0) FROM t;","handlingStrategy":"validation","validationCode":"-- before creating an aggregate with FILTER, verify the predicate is boolean\nSELECT pg_typeof(status) FROM t LIMIT 0; -- must return boolean for FILTER (WHERE status)\n-- or force it: FILTER (WHERE (expr)::boolean)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always write FILTER predicates as explicit boolean comparisons (`x = 1`, `x IS NOT NULL`), never bare non-boolean columns.","Run EXPLAIN on queries with FILTER clauses to confirm the planned expression type.","Recreate materialized views after upgrading RisingWave so plans match executor expectations."],"tags":["streaming","aggregate","filter","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}