prestodb/presto · error · SemanticException

INVALID_PROCEDURE_ARGUMENTS

INVALID_PROCEDURE_ARGUMENTS

Error message

A GROUPING() operation can only be used with a corresponding GROUPING SET/CUBE/ROLLUP/GROUP BY clause

What it means

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.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/sql/analyzer/StatementAnalyzer.java:5154

            }.process(expression, null);
        }

        private Scope analyzeFrom(QuerySpecification node, Optional<Scope> scope)
        {
            if (node.getFrom().isPresent()) {
                return process(node.getFrom().get(), scope);
            }

            return createScope(scope);
        }

        private void analyzeGroupingOperations(QuerySpecification node, List<Expression> outputExpressions, List<Expression> orderByExpressions)
        {
            List<GroupingOperation> groupingOperations = extractExpressions(Stream.concat(outputExpressions.stream(), orderByExpressions.stream()).collect(toImmutableList()), GroupingOperation.class);
            boolean isGroupingOperationPresent = !groupingOperations.isEmpty();

            if (isGroupingOperationPresent && !node.getGroupBy().isPresent()) {
                throw new SemanticException(
                        INVALID_PROCEDURE_ARGUMENTS,
                        node,
                        "A GROUPING() operation can only be used with a corresponding GROUPING SET/CUBE/ROLLUP/GROUP BY clause");
            }

            analysis.setGroupingOperations(node, groupingOperations);
        }

        private List<FunctionCall> analyzeAggregations(
                QuerySpecification node,
                List<Expression> outputExpressions,
                List<Expression> orderByExpressions)
        {
            List<FunctionCall> aggregates = extractAggregateFunctions(analysis.getFunctionHandles(), Stream.concat(outputExpressions.stream(), orderByExpressions.stream()).collect(toImmutableList()), functionAndTypeResolver);
            analysis.setAggregates(node, aggregates);
            return aggregates;
        }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Add the intended GROUP BY / GROUPING SETS / CUBE / ROLLUP clause to the query
  2. Remove the GROUPING() call from the projection or ORDER BY
  3. Replace GROUPING(col) with a literal (e.g. 0) if no grouping is intended

Example fix

// before
SELECT grouping(region) FROM sales
// after
SELECT region, grouping(region) FROM sales GROUP BY region
Defensive patterns

Strategy: validation

Validate before calling

// Verify GROUPING() usage only in queries that have GROUP BY:
if (queryContainsGroupingFunction(sql) && !sql.toUpperCase().matches(".*GROUP\\s+BY.*")) {
    throw new IllegalStateException("GROUPING() requires GROUP BY / GROUPING SETS / CUBE / ROLLUP");
}

Type guard

boolean groupingRequiresGroupBy(QuerySpecification node) {
    return extractExpressions(node.getSelect().getItems(), GroupingOperation.class).size() > 0
        && !node.getGroupBy().isPresent();
}

Try / catch

try { session.execute(sql); }
catch (PrestoException e) {
    if (e.getErrorCode() == INVALID_PROCEDURE_ARGUMENTS.toErrorCode()) {
        throw new QueryBuildException("GROUPING() used without GROUP BY", e);
    } else { throw e; }
}

Prevention

When it happens

Trigger: Calling `SELECT grouping(a) FROM t` (or in ORDER BY) without any `GROUP BY`/`GROUPING SETS`/`CUBE`/`ROLLUP` clause; thrown from analyzeGroupingOperations in StatementAnalyzer.

Common situations: 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().

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/527c8e4639fc85d3. Report an issue: GitHub.