docs: protected void validateGroupClause(SqlSelect select) {
  		SqlNodeList groupList = select.getGroup();
  		if (groupList == null) {
  			return;
  		}
  		final String clause = "GROUP BY";
  		validateNoAggs(aggOrOverFinder, groupList, clause);
  		final SqlValidatorScope groupScope = getGroupScope(select);
  		inferUnknownTypes(unknownType, groupScope, groupList);
  
  		// expand the expression in group list.
  		List<SqlNode> expandedList = new ArrayList<>();
  		for (SqlNode groupItem : groupList) {
  			SqlNode expandedItem = expandGroupByOrHavingExpr(groupItem, groupScope, select, false);
  			expandedList.add(expandedItem);
  		}
  		groupList = new SqlNodeList(expandedList, groupList.getParserPosition());
  		select.setGroupBy(groupList);
  		for (SqlNode groupItem : expandedList) {
  			validateGroupByItem(select, groupItem);
  		}
  
  		// Nodes in the GROUP BY clause are expressions except if they are calls
  		// to the GROUPING SETS, ROLLUP or CUBE operators; this operators are not
  		// expressions, because they do not have a type.
  		for (SqlNode node : groupList) {
  			switch (node.getKind()) {
  				case GROUPING_SETS:
  				case ROLLUP:
  				case CUBE:
  					node.validate(this, groupScope);
  					break;
  				default:
  					node.validateExpr(this, groupScope);
  			}
  		}
  
  		// Derive the type of each GROUP BY item. We don't need the type, but
  		// it resolves functions, and that is necessary for deducing
  		// monotonicity.
  		final SqlValidatorScope selectScope = getSelectScope(select);
  		AggregatingSelectScope aggregatingScope = null;
  		if (selectScope instanceof AggregatingSelectScope) {
  			aggregatingScope = (AggregatingSelectScope) selectScope;
  		}
  		for (SqlNode groupItem : groupList) {
  			if (groupItem instanceof SqlNodeList
  				&& ((SqlNodeList) groupItem).size() == 0) {
  				continue;
  			}
  			validateGroupItem(groupScope, aggregatingScope, groupItem);
  		}
  
  		SqlNode agg = aggFinder.findAgg(groupList);
  		if (agg != null) {
  			throw newValidationError(agg, RESOURCE.aggregateIllegalInClause(clause));
  		}
  	}