in Microsoft.Azure.Cosmos/src/Linq/QueryUnderConstruction.cs [220:286]
public QueryUnderConstruction FlattenAsPossible()
{
// Flatten should be done when the current query can be translated without the need of using sub query
// The cases that need to use sub query are:
// 1. Select clause appears after Distinct
// 2. There are any operations after Take that is not a pure Select.
// 3. There are nested Select, Where or OrderBy
// 4. Group by clause appears after Select
QueryUnderConstruction parentQuery = null;
QueryUnderConstruction flattenQuery = null;
bool seenSelect = false;
bool seenAnyNonSelectOp = false;
for (QueryUnderConstruction query = this; query != null; query = query.inputQuery)
{
foreach (Binding binding in query.FromParameters.GetBindings())
{
if ((binding.ParameterDefinition != null) && (binding.ParameterDefinition is SqlSubqueryCollection))
{
flattenQuery = this;
break;
}
}
// In Select -> SelectMany cases, fromParameter substitution is not yet supported .
// Therefore these are un-flattenable.
if (query.inputQuery != null &&
(query.FromParameters.GetBindings().First().Parameter.Name == query.inputQuery.Alias.Name) &&
query.FromParameters.GetBindings().Any(b => b.ParameterDefinition != null))
{
flattenQuery = this;
break;
}
// In case of Select/Order By -> Group by cases, the Select/Order By query should not be flattened and kept as a subquery
if (((query.inputQuery?.selectClause != null) || (query.inputQuery?.orderByClause != null)) && (query.groupByClause != null))
{
flattenQuery = this;
break;
}
if (flattenQuery != null) break;
if (((query.topSpec != null || query.offsetSpec != null || query.limitSpec != null) && seenAnyNonSelectOp) ||
(query.selectClause != null && query.selectClause.HasDistinct && seenSelect))
{
parentQuery.inputQuery = query.FlattenAsPossible();
flattenQuery = this;
break;
}
seenSelect = seenSelect || ((query.selectClause != null) && !query.selectClause.HasDistinct);
seenAnyNonSelectOp |=
(query.whereClause != null) ||
(query.orderByClause != null) ||
(query.groupByClause != null) ||
(query.topSpec != null) ||
(query.offsetSpec != null) ||
query.FromParameters.GetBindings().Any(b => b.ParameterDefinition != null) ||
((query.selectClause != null) && (query.selectClause.HasDistinct ||
this.HasSelectAggregate()));
parentQuery = query;
}
if (flattenQuery == null) flattenQuery = this.Flatten();
return flattenQuery;
}