apache/druid · error · UnsupportedOperationException
Subqueries must be of type 'group by'
Error message
Subqueries must be of type 'group by'
What it means
mergeGroupByResultsWithoutPushDown expects the DataSource of the subquery being merged to be a QueryDataSource wrapping a GroupByQuery. When the cast fails (the wrapped query is not a GroupByQuery), an UnsupportedOperationException 'Subqueries must be of type \"group by\"' is thrown.
Solutions
- Rewrite the inner query as a groupBy query (groupBy can express most timeseries/topN shapes)
- Flatten the query into a single-level query or compute the inner query separately and use its results (e.g. via a join or inline datasource)
- Upgrade Druid — newer versions support more subquery types via QueryDataSource handling in the group-by engine
Example fix
// before DataSource sub = new QueryDataSource(Druids.newTimeseriesQueryBuilder()...build()); // after DataSource sub = new QueryDataSource(Druids.newTimeseriesQueryBuilder()...build().toGroupByQuery()); // or use a groupBy builder directly
Defensive patterns
Strategy: type-guard
Validate before calling
if (dataSource instanceof QueryDataSource && !(((QueryDataSource) dataSource).getQuery() instanceof GroupByQuery)) { throw new UnsupportedOperationException("Inner query must be a groupBy"); } Type guard
boolean isGroupBySubquery(DataSource ds) { return ds instanceof QueryDataSource && ((QueryDataSource) ds).getQuery() instanceof GroupByQuery; } Try / catch
try { mergeGroupByResultsWithoutPushDown(...); } catch (UnsupportedOperationException e) { /* run inner query separately or rewrite plan */ } Prevention
- Only nest groupBy queries inside groupBy subqueries
- Convert timeseries/topN inner queries to groupBy equivalents before nesting
When it happens
Trigger: Running a group-by with a subquery whose dataSource wraps a non-group-by query (e.g. a timeseries, topN, or scan query) such that ((QueryDataSource)dataSource).getQuery() cannot be cast to GroupByQuery.
Common situations: Nested native queries mixing engines/query types (timeseries inside groupBy); SQL-generated plans where the planner produced an unsupported nesting shape on older Druid versions; hand-built multi-level native queries.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Group key should be a single dimension
- Limit push down when sorting by a post aggregator is not…
- Aggregator[ ] cannot vectorize
- Ambiguous build, limit
- Ambiguous build, limitSpec
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/bfbddfa0460adc1c.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/query/groupby/GroupByQueryQueryToolChest.java:280
// Unlike withOverriddenContext's normal behavior, we want keys present in the subquery to win.
final Map<String, Object> subqueryContext = new TreeMap<>();
if (query.getContext() != null) {
for (Map.Entry<String, Object> entry : query.getContext().entrySet()) {
if (entry.getValue() != null) {
subqueryContext.put(entry.getKey(), entry.getValue());
}
}
}
if (((QueryDataSource) dataSource).getQuery().getContext() != null) {
subqueryContext.putAll(((QueryDataSource) dataSource).getQuery().getContext());
}
subqueryContext.put(GroupByQuery.CTX_KEY_SORT_BY_DIMS_FIRST, false);
subquery = (GroupByQuery) ((QueryDataSource) dataSource).getQuery().withOverriddenContext(subqueryContext);
closer.register(() -> groupByStatsProvider.closeQuery(subquery.context().getQueryResourceId()));
}
catch (ClassCastException e) {
throw new UnsupportedOperationException("Subqueries must be of type 'group by'");
}
final Sequence<ResultRow> subqueryResult = mergeGroupByResults(
subquery,
resource,
runner,
context,
closer,
perQueryStats
);
final Sequence<ResultRow> finalizingResults = finalizeSubqueryResults(subqueryResult, subquery);
if (query.getSubtotalsSpec() != null) {
return groupingEngine.processSubtotalsSpec(
query,
resource,
groupingEngine.processSubqueryResult(View on GitHub (pinned to 9b90983fd2)