{"record":{"id":"48e7d491d7a34fbe","repo":"apache/cassandra","slug":"aggregation-query-used-without-partition-key","errorCode":null,"errorMessage":"Aggregation query used without partition key","messagePattern":"Aggregation query used without partition key","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/java/org/apache/cassandra/cql3/statements/SelectStatement.java","lineNumber":621,"sourceCode":"\n    private ResultMessage.Rows execute(QueryState state,\n                                       Pager pager,\n                                       QueryOptions options,\n                                       Selectors selectors,\n                                       int pageSize,\n                                       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;","sourceCodeStart":603,"sourceCodeEnd":639,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java#L603-L639","documentation":"When a query performs aggregation (COUNT, SUM, AVG, ...) without a partition key restriction, Cassandra must scan/aggregate across the whole table (or many partitions) on the coordinator. SelectStatement.execute warns the client and logs a rate-limited server warning because such queries can be extremely expensive.","triggerScenarios":"Running `SELECT count(*) FROM ks.tbl` or other aggregate with no WHERE clause on the partition key; also for token-range or secondary-index scans that lack partition-key restrictions.","commonSituations":"Ad-hoc analytics against production tables; COUNT(*) health checks on large tables; migrations from relational databases assuming free full-table aggregation.","solutions":["Add a partition key restriction so aggregation is scoped to one partition","Maintain denormalized counters/aggregate state instead of full-table COUNT","Use analytics tooling (Spark) for full-table aggregation rather than CQL","Suppress deliberately via guardrails/page-size config only for known-small tables"],"exampleFix":"// before\nSELECT count(*) FROM sensor_data;\n// after\nSELECT count(*) FROM sensor_data WHERE device_id = ?;","handlingStrategy":"validation","validationCode":"if (isAggregate(cql) && !cql.matches(\".*WHERE\\\\s+.*=?\")) {\n    throw new IllegalArgumentException(\"aggregation without partition key restriction is forbidden\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always scope aggregates to a partition key","Use counters instead of COUNT(*) for totals","Send full-table analytics to Spark, not CQL"],"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"}