{"record":{"id":"0b6d9547fe1e1e65","repo":"apache/cassandra","slug":"aggregation-query-used-on-multiple-partition-keys","errorCode":null,"errorMessage":"Aggregation query used on multiple partition keys (IN restriction)","messagePattern":"Aggregation query used on multiple partition keys \\(IN restriction\\)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/java/org/apache/cassandra/cql3/statements/SelectStatement.java","lineNumber":627,"sourceCode":"                                       long nowInSec,\n                                       int userLimit,\n                                       AggregationSpecification aggregationSpec,\n                                       Dispatcher.RequestTime requestTime,\n                                       boolean unmask)\n    {\n        Guardrails.pageSize.guard(pageSize, table(), false, state.getClientState());\n\n        if (aggregationSpecFactory != null)\n        {\n            if (!restrictions.hasPartitionKeyRestrictions())\n            {\n                warn(\"Aggregation query used without partition key\");\n                noSpamLogger.warn(String.format(\"Aggregation query used without partition key on table %s.%s, aggregation type: %s\",\n                                                 keyspace(), table(), aggregationSpec.kind()));\n            }\n            else if (restrictions.keyIsInRelation())\n            {\n                warn(\"Aggregation query used on multiple partition keys (IN restriction)\");\n                noSpamLogger.warn(String.format(\"Aggregation query used on multiple partition keys (IN restriction) on table %s.%s, aggregation type: %s\",\n                                                 keyspace(), table(), aggregationSpec.kind()));\n            }\n        }\n\n        // We can't properly do post-query ordering if we page (see #6722)\n        // For GROUP BY or aggregation queries we always page internally even if the user has turned paging off\n        checkFalse(pageSize > 0 && needsPostQueryOrdering(),\n                  \"Cannot page queries with both ORDER BY and a IN restriction on the partition key;\"\n                  + \" you must either remove the ORDER BY or the IN and sort client side, or disable paging for this query\");\n\n        ResultMessage.Rows msg;\n        try (PartitionIterator page = pager.fetchPage(pageSize, requestTime))\n        {\n            msg = processResults(page, options, selectors, nowInSec, userLimit, aggregationSpec, unmask, state.getClientState());\n        }\n\n        // Please note that the isExhausted state of the pager only gets updated when we've closed the page, so this","sourceCodeStart":609,"sourceCodeEnd":645,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java#L609-L645","documentation":"Aggregation with an IN restriction on the partition key aggregates across multiple partitions in one coordinator operation. Cassandra warns the client because cost grows linearly with the number of partition keys in the IN list.","triggerScenarios":"`SELECT count(*) FROM ks.tbl WHERE pk IN (k1, k2, ..., kN)` with N > 1; SelectStatement.execute detects restrictions.keyIsInRelation() for an aggregating query and warns.","commonSituations":"Dashboard queries counting across a handful of known partitions; batch report jobs issuing large IN lists; gradual growth of IN lists until scans become slow.","solutions":["Issue one aggregation query per partition key and sum client-side","Reduce the IN list size or fan out queries in parallel","Precompute counts with counters or an aggregate table","Use analytics tooling for multi-partition aggregation"],"exampleFix":"// before\nSELECT count(*) FROM sensor_data WHERE device_id IN (1,2,3,4,5);\n// after\nSELECT count(*) FROM sensor_data WHERE device_id = 1; // repeat per device, sum client-side","handlingStrategy":"validation","validationCode":"if (isAggregate(cql) && cql.matches(\".*IN\\\\s*\\\\(.*\")) {\n    throw new IllegalArgumentException(\"aggregate with IN on partition key not allowed; fan out per key\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Cap IN list sizes in query builders","Fan out per-partition aggregate queries in parallel","Precompute multi-partition aggregates in tables"],"tags":["cassandra","aggregation","performance","client-warning"],"backgroundTag":"database-query-failed","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}