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));
		}
	}
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 ) ; 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 ) ; } for ( SqlNode node : groupList ) { switch ( node . getKind ( ) ) { case GROUPING_SETS : case ROLLUP : case CUBE : node . validate ( this , groupScope ) ; break ; default : node . validateExpr ( this , groupScope ) ; } } 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 ) ) ; } }
Validates the GROUP BY clause of a SELECT statement. This method is
called even if no GROUP BY clause is present.