{"record":{"id":"527c8e4639fc85d3","repo":"prestodb/presto","slug":"invalid-procedure-arguments-527c8e","errorCode":"INVALID_PROCEDURE_ARGUMENTS","errorMessage":"A GROUPING() operation can only be used with a corresponding GROUPING SET/CUBE/ROLLUP/GROUP BY clause","messagePattern":"A GROUPING\\(\\) operation can only be used with a corresponding GROUPING SET/CUBE/ROLLUP/GROUP BY clause","errorType":"error_code","errorClass":"SemanticException","httpStatus":null,"severity":"error","filePath":"presto-main-base/src/main/java/com/facebook/presto/sql/analyzer/StatementAnalyzer.java","lineNumber":5154,"sourceCode":"            }.process(expression, null);\n        }\n\n        private Scope analyzeFrom(QuerySpecification node, Optional<Scope> scope)\n        {\n            if (node.getFrom().isPresent()) {\n                return process(node.getFrom().get(), scope);\n            }\n\n            return createScope(scope);\n        }\n\n        private void analyzeGroupingOperations(QuerySpecification node, List<Expression> outputExpressions, List<Expression> orderByExpressions)\n        {\n            List<GroupingOperation> groupingOperations = extractExpressions(Stream.concat(outputExpressions.stream(), orderByExpressions.stream()).collect(toImmutableList()), GroupingOperation.class);\n            boolean isGroupingOperationPresent = !groupingOperations.isEmpty();\n\n            if (isGroupingOperationPresent && !node.getGroupBy().isPresent()) {\n                throw new SemanticException(\n                        INVALID_PROCEDURE_ARGUMENTS,\n                        node,\n                        \"A GROUPING() operation can only be used with a corresponding GROUPING SET/CUBE/ROLLUP/GROUP BY clause\");\n            }\n\n            analysis.setGroupingOperations(node, groupingOperations);\n        }\n\n        private List<FunctionCall> analyzeAggregations(\n                QuerySpecification node,\n                List<Expression> outputExpressions,\n                List<Expression> orderByExpressions)\n        {\n            List<FunctionCall> aggregates = extractAggregateFunctions(analysis.getFunctionHandles(), Stream.concat(outputExpressions.stream(), orderByExpressions.stream()).collect(toImmutableList()), functionAndTypeResolver);\n            analysis.setAggregates(node, aggregates);\n            return aggregates;\n        }\n","sourceCodeStart":5136,"sourceCodeEnd":5172,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-main-base/src/main/java/com/facebook/presto/sql/analyzer/StatementAnalyzer.java#L5136-L5172","documentation":"The GROUPING() function returns which grouping-set columns are aggregated, so it is only meaningful when the query actually has GROUP BY / GROUPING SETS / CUBE / ROLLUP. The analyzer collects all GroupingOperations from output and ORDER BY expressions and throws INVALID_PROCEDURE_ARGUMENTS if any exist while the query has no GROUP BY clause.","triggerScenarios":"Calling `SELECT grouping(a) FROM t` (or in ORDER BY) without any `GROUP BY`/`GROUPING SETS`/`CUBE`/`ROLLUP` clause; thrown from analyzeGroupingOperations in StatementAnalyzer.","commonSituations":"Copy-pasting a GROUPING() expression out of a grouped query into a plain select; a query builder dropping the GROUP BY clause but keeping the projection; typos like GROUP BY on a CTE while the outer query still calls GROUPING().","solutions":["Add the intended GROUP BY / GROUPING SETS / CUBE / ROLLUP clause to the query","Remove the GROUPING() call from the projection or ORDER BY","Replace GROUPING(col) with a literal (e.g. 0) if no grouping is intended"],"exampleFix":"// before\nSELECT grouping(region) FROM sales\n// after\nSELECT region, grouping(region) FROM sales GROUP BY region","handlingStrategy":"validation","validationCode":"// Verify GROUPING() usage only in queries that have GROUP BY:\nif (queryContainsGroupingFunction(sql) && !sql.toUpperCase().matches(\".*GROUP\\\\s+BY.*\")) {\n    throw new IllegalStateException(\"GROUPING() requires GROUP BY / GROUPING SETS / CUBE / ROLLUP\");\n}","typeGuard":"boolean groupingRequiresGroupBy(QuerySpecification node) {\n    return extractExpressions(node.getSelect().getItems(), GroupingOperation.class).size() > 0\n        && !node.getGroupBy().isPresent();\n}","tryCatchPattern":"try { session.execute(sql); }\ncatch (PrestoException e) {\n    if (e.getErrorCode() == INVALID_PROCEDURE_ARGUMENTS.toErrorCode()) {\n        throw new QueryBuildException(\"GROUPING() used without GROUP BY\", e);\n    } else { throw e; }\n}","preventionTips":["Keep GROUPING() calls co-located with the query that defines GROUP BY","When refactoring queries, move GROUP BY along with GROUPING() projections","Search query templates for grouping( when removing GROUP BY clauses"],"tags":["sql","grouping","group-by","semantic-analysis"],"backgroundTag":"grouping-without-group-by","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}