{"record":{"id":"67a123a6be536d38","repo":"apache/cassandra","slug":"group-by-functions-accept-only-one-clustering-colu","errorCode":null,"errorMessage":"GROUP BY functions accept only one clustering column as parameter, got: %s","messagePattern":"GROUP BY functions accept only one clustering column as parameter, got: (.+?)","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/statements/SelectStatement.java","lineNumber":1599,"sourceCode":"\n            Iterator<ColumnMetadata> pkColumns = metadata.primaryKeyColumns().iterator();\n            List<ColumnMetadata> columns = null;\n            Selector.Factory selectorFactory = null;\n            for (Selectable.Raw raw : parameters.groups)\n            {\n                Selectable selectable = raw.prepare(metadata);\n                ColumnMetadata def = null;\n\n                // For GROUP BY we only allow column names or functions at the higher level.\n                if (selectable instanceof WithFunction)\n                {\n                    WithFunction withFunction = (WithFunction) selectable;\n                    validateGroupByFunction(withFunction);\n                    columns = new ArrayList<ColumnMetadata>();\n                    selectorFactory = selectable.newSelectorFactory(metadata, null, columns, boundNames);\n                    checkFalse(columns.isEmpty(), \"GROUP BY functions must have one clustering column name as parameter\");\n                    if (columns.size() > 1)\n                        throw invalidRequest(\"GROUP BY functions accept only one clustering column as parameter, got: %s\",\n                                             columns.stream().map(c -> c.name.toCQLString()).collect(Collectors.joining(\",\")));\n\n                    def = columns.get(0);\n                    checkTrue(def.isClusteringColumn(),\n                              \"Group by functions are only supported on clustering columns, got %s\", def.name);\n                }\n                else\n                {\n                    def = (ColumnMetadata) selectable;\n                    checkTrue(def.isPartitionKey() || def.isClusteringColumn(),\n                              \"Group by is currently only supported on the columns of the PRIMARY KEY, got %s\", def.name);\n                    checkNull(selectorFactory, \"Functions are only supported on the last element of the GROUP BY clause\");\n                }\n\n                while (true)\n                {\n                    checkTrue(pkColumns.hasNext(),\n                              \"Group by currently only support groups of columns following their declared order in the PRIMARY KEY\");","sourceCodeStart":1581,"sourceCodeEnd":1617,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java#L1581-L1617","documentation":"SelectStatement's GROUP BY validation rejects group-by functions (like tok(...) or bucket-style selectors) that take more than one clustering column as parameter. Functions in GROUP BY must operate on exactly one clustering column so the grouping maps onto partition-row ordering.","triggerScenarios":"Executing a SELECT with `GROUP BY somefunc(colA, colB)` where the function selector contributes more than one clustering column to the selector factory's `columns` list.","commonSituations":"Writing tok(pk1, pk2) style calls with multiple arguments in GROUP BY, or user-defined/wrapped selectors accepting several clustering columns; usually a misunderstanding that GROUP BY functions are limited to a single clustering column.","solutions":["Pass exactly one clustering column to the function in GROUP BY","If you need multi-column grouping, use plain GROUP BY col1, col2 without a function","For token-based grouping, group by a single column or restructure the query"],"exampleFix":"// before\nSELECT bucket(a, b) FROM ks.t GROUP BY bucket(a, b); -- two clustering columns\n// after\nSELECT bucket(a) FROM ks.t GROUP BY bucket(a); -- one clustering column","handlingStrategy":"validation","validationCode":"// client-side check before issuing the query\nif (groupByFuncArgs.size() != 1) throw new IllegalArgumentException(\"GROUP BY functions accept exactly one clustering column\");","typeGuard":null,"tryCatchPattern":"try { session.execute(query); }\ncatch (InvalidRequestException e) { if (e.getMessage().contains(\"GROUP BY functions\")) { /* rewrite query without function or with one arg */ } }","preventionTips":["Use plain GROUP BY col1, col2 for multi-column grouping","Restrict GROUP BY function usage to a single clustering column"],"tags":["cql","select","group-by","validation"],"backgroundTag":"invalid-argument-value","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"}