@Override
protected RelationType visitQuerySpecification(QuerySpecification node, AnalysisContext parentContext)
{
AnalysisContext context = new AnalysisContext(parentContext);
RelationType tupleDescriptor = analyzeFrom(node, context);
node.getWhere().ifPresent(where -> analyzeWhere(node, tupleDescriptor, context, where));
List<FieldOrExpression> outputExpressions = analyzeSelect(node, tupleDescriptor, context);
List<List<FieldOrExpression>> groupByExpressions = analyzeGroupBy(node, tupleDescriptor, context, outputExpressions);
List<FieldOrExpression> orderByExpressions = analyzeOrderBy(node, tupleDescriptor, context, outputExpressions);
analyzeHaving(node, tupleDescriptor, context);
analyzeAggregations(node, tupleDescriptor, groupByExpressions, outputExpressions, orderByExpressions, context, analysis.getColumnReferences());
analyzeWindowFunctions(node, outputExpressions, orderByExpressions);
RelationType descriptor = computeOutputDescriptor(node, tupleDescriptor);
analysis.setOutputDescriptor(node, descriptor);
return descriptor;
}