The "DB::Exception: Illegal type of column for filter" error means that the expression in a WHERE, HAVING, or PREWHERE clause does not evaluate to a Boolean-compatible type. In ClickHouse, filter expressions must produce a UInt8 (or Nullable(UInt8)) value where 0 means false and non-zero means true. If your filter expression returns a String, Float, Array, or any other type, ClickHouse rejects it.
Impact
The query fails entirely. This is a common stumbling block for users coming from databases that are more lenient about what constitutes a truthy value in a WHERE clause. Fixing it is usually straightforward once you understand what ClickHouse expects.
Common Causes
- Using a String expression in WHERE without a comparison —
WHERE nameinstead ofWHERE name != ''. - Forgetting the comparison operator —
WHERE statuswhen status is an Enum or String, not a numeric type. - Arithmetic expression in WHERE —
WHERE col1 + col2instead ofWHERE col1 + col2 > 0. - Function that returns a non-Boolean type — using a function like
length(col)in WHERE without comparing its result. - HAVING clause with an aggregate that returns a non-Boolean —
HAVING sum(amount)instead ofHAVING sum(amount) > 0.
Troubleshooting and Resolution Steps
Identify the filter expression type. Use
toTypeName()to check:SELECT toTypeName(your_filter_expression) FROM your_table LIMIT 1;Add an explicit comparison operator. Convert the expression to a Boolean:
-- Instead of: WHERE length(name) -- Use: WHERE length(name) > 0Convert String conditions to proper comparisons:
-- Instead of: WHERE status -- Use: WHERE status != '' -- Or for specific values: WHERE status = 'active'Handle Nullable filter expressions. If your filter produces
Nullable(UInt8), you may need to handle the NULL case:WHERE assumeNotNull(nullable_condition) -- Or WHERE ifNull(nullable_condition, 0)Fix HAVING clauses the same way:
-- Instead of: HAVING count() -- Use: HAVING count() > 0Cast to UInt8 as a last resort. If you have a numeric expression you want to use as a Boolean:
WHERE CAST(numeric_expression AS UInt8) != 0
Best Practices
- Always write explicit comparisons in WHERE and HAVING clauses — never rely on implicit truthiness.
- Use
toTypeName()to debug filter expressions when you're unsure of the result type. - When porting queries from MySQL or PostgreSQL, review all WHERE clauses for implicit Boolean conversions that ClickHouse does not support.
- Prefer clear Boolean expressions like
col > 0orcol != ''over relying on type casting.
Frequently Asked Questions
Q: Why doesn't ClickHouse treat non-zero numbers as true like other databases?
A: ClickHouse does treat non-zero UInt8 values as true. The error occurs when the filter expression isn't UInt8 at all — for example, a String, Float64, or Int32. You need to compare the value to produce a UInt8 result.
Q: Can I use Bool type in ClickHouse for filter columns?
A: Yes, ClickHouse has a Bool type which is an alias for UInt8. Columns of type Bool work directly in WHERE clauses without additional comparison.
Q: What about using integers like Int32 in WHERE?
A: An Int32 expression in WHERE will trigger this error. You need to explicitly compare it: WHERE int32_col != 0. Only UInt8 (and its aliases like Bool) is accepted directly.
Q: How do I handle Nullable(UInt8) in a filter?
A: ClickHouse does accept Nullable(UInt8) in filters, treating NULL as false. If you get an error, the type is likely something other than Nullable(UInt8). Check with toTypeName().