Skip to content

Commit

Permalink
Test fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkMpn committed Nov 30, 2021
1 parent 2cc1e6c commit e2a2843
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 28 deletions.
129 changes: 108 additions & 21 deletions MarkMpn.Sql4Cds.Engine.Tests/ExecutionPlanTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -460,8 +460,9 @@ public void SimpleGroupAggregate()
Assert.AreEqual(1, plans.Length);

var select = AssertNode<SelectNode>(plans[0]);
var tryCatch = AssertNode<TryCatchNode>(select.Source);
var aggregateFetch = AssertNode<FetchXmlScan>(tryCatch.TrySource);
var tryCatch1 = AssertNode<TryCatchNode>(select.Source);
var tryCatch2 = AssertNode<TryCatchNode>(tryCatch1.TrySource);
var aggregateFetch = AssertNode<FetchXmlScan>(tryCatch2.TrySource);
AssertFetchXml(aggregateFetch, @"
<fetch aggregate='true'>
<entity name='account'>
Expand All @@ -470,7 +471,17 @@ public void SimpleGroupAggregate()
<order alias='name' />
</entity>
</fetch>");
var aggregate = AssertNode<HashMatchAggregateNode>(tryCatch.CatchSource);
var partitionAggregate = AssertNode<PartitionedAggregateNode>(tryCatch2.CatchSource);
var partitionFetch = AssertNode<FetchXmlScan>(partitionAggregate.Source);
AssertFetchXml(partitionFetch, @"
<fetch aggregate='true'>
<entity name='account'>
<attribute name='name' groupby='true' alias='name' />
<attribute name='accountid' aggregate='count' alias='count' />
<order alias='name' />
</entity>
</fetch>");
var aggregate = AssertNode<HashMatchAggregateNode>(tryCatch1.CatchSource);
var scalarFetch = AssertNode<FetchXmlScan>(aggregate.Source);
AssertFetchXml(scalarFetch, @"
<fetch>
Expand Down Expand Up @@ -499,8 +510,9 @@ public void AliasedAggregate()
Assert.AreEqual(1, plans.Length);

var select = AssertNode<SelectNode>(plans[0]);
var tryCatch = AssertNode<TryCatchNode>(select.Source);
var aggregateFetch = AssertNode<FetchXmlScan>(tryCatch.TrySource);
var tryCatch1 = AssertNode<TryCatchNode>(select.Source);
var tryCatch2 = AssertNode<TryCatchNode>(tryCatch1.TrySource);
var aggregateFetch = AssertNode<FetchXmlScan>(tryCatch2.TrySource);
AssertFetchXml(aggregateFetch, @"
<fetch aggregate='true'>
<entity name='account'>
Expand All @@ -509,7 +521,17 @@ public void AliasedAggregate()
<order alias='name' />
</entity>
</fetch>");
var aggregate = AssertNode<HashMatchAggregateNode>(tryCatch.CatchSource);
var partitionAggregate = AssertNode<PartitionedAggregateNode>(tryCatch2.CatchSource);
var partitionFetch = AssertNode<FetchXmlScan>(partitionAggregate.Source);
AssertFetchXml(partitionFetch, @"
<fetch aggregate='true'>
<entity name='account'>
<attribute name='name' groupby='true' alias='name' />
<attribute name='accountid' aggregate='count' alias='test' />
<order alias='name' />
</entity>
</fetch>");
var aggregate = AssertNode<HashMatchAggregateNode>(tryCatch1.CatchSource);
var scalarFetch = AssertNode<FetchXmlScan>(aggregate.Source);
AssertFetchXml(scalarFetch, @"
<fetch>
Expand Down Expand Up @@ -538,8 +560,9 @@ public void AliasedGroupingAggregate()
Assert.AreEqual(1, plans.Length);

var select = AssertNode<SelectNode>(plans[0]);
var tryCatch = AssertNode<TryCatchNode>(select.Source);
var aggregateFetch = AssertNode<FetchXmlScan>(tryCatch.TrySource);
var tryCatch1 = AssertNode<TryCatchNode>(select.Source);
var tryCatch2 = AssertNode<TryCatchNode>(tryCatch1.TrySource);
var aggregateFetch = AssertNode<FetchXmlScan>(tryCatch2.TrySource);
AssertFetchXml(aggregateFetch, @"
<fetch aggregate='true'>
<entity name='account'>
Expand All @@ -548,7 +571,17 @@ public void AliasedGroupingAggregate()
<order alias='name' />
</entity>
</fetch>");
var aggregate = AssertNode<HashMatchAggregateNode>(tryCatch.CatchSource);
var partitionAggregate = AssertNode<PartitionedAggregateNode>(tryCatch2.CatchSource);
var partitionFetch = AssertNode<FetchXmlScan>(partitionAggregate.Source);
AssertFetchXml(partitionFetch, @"
<fetch aggregate='true'>
<entity name='account'>
<attribute name='name' groupby='true' alias='name' />
<attribute name='accountid' aggregate='count' alias='count' />
<order alias='name' />
</entity>
</fetch>");
var aggregate = AssertNode<HashMatchAggregateNode>(tryCatch1.CatchSource);
var scalarFetch = AssertNode<FetchXmlScan>(aggregate.Source);
AssertFetchXml(scalarFetch, @"
<fetch>
Expand Down Expand Up @@ -614,8 +647,9 @@ GROUP BY name
Assert.IsInstanceOfType(gt.SecondExpression, typeof(IntegerLiteral));
var val = (IntegerLiteral)gt.SecondExpression;
Assert.AreEqual("1", val.Value);
var tryCatch = AssertNode<TryCatchNode>(filter.Source);
var aggregateFetch = AssertNode<FetchXmlScan>(tryCatch.TrySource);
var tryCatch1 = AssertNode<TryCatchNode>(filter.Source);
var tryCatch2 = AssertNode<TryCatchNode>(tryCatch1.TrySource);
var aggregateFetch = AssertNode<FetchXmlScan>(tryCatch2.TrySource);
AssertFetchXml(aggregateFetch, @"
<fetch aggregate='true'>
<entity name='account'>
Expand All @@ -624,7 +658,17 @@ GROUP BY name
<order alias='name' />
</entity>
</fetch>");
var aggregate = AssertNode<HashMatchAggregateNode>(tryCatch.CatchSource);
var partitionAggregate = AssertNode<PartitionedAggregateNode>(tryCatch2.CatchSource);
var partitionFetch = AssertNode<FetchXmlScan>(partitionAggregate.Source);
AssertFetchXml(partitionFetch, @"
<fetch aggregate='true'>
<entity name='account'>
<attribute name='name' groupby='true' alias='name' />
<attribute name='accountid' aggregate='count' alias='count' />
<order alias='name' />
</entity>
</fetch>");
var aggregate = AssertNode<HashMatchAggregateNode>(tryCatch1.CatchSource);
Assert.AreEqual("account.name", aggregate.GroupBy[0].ToSql());
Assert.AreEqual("count", aggregate.Aggregates.Single().Key);
var scalarFetch = AssertNode<FetchXmlScan>(aggregate.Source);
Expand Down Expand Up @@ -657,8 +701,9 @@ public void GroupByDatePart()
var select = AssertNode<SelectNode>(plans[0]);
Assert.AreEqual("createdon_month", select.ColumnSet[0].SourceColumn);
Assert.AreEqual("count", select.ColumnSet[1].SourceColumn);
var tryCatch = AssertNode<TryCatchNode>(select.Source);
var aggregateFetch = AssertNode<FetchXmlScan>(tryCatch.TrySource);
var tryCatch1 = AssertNode<TryCatchNode>(select.Source);
var tryCatch2 = AssertNode<TryCatchNode>(tryCatch1.TrySource);
var aggregateFetch = AssertNode<FetchXmlScan>(tryCatch2.TrySource);
AssertFetchXml(aggregateFetch, @"
<fetch aggregate='true'>
<entity name='account'>
Expand All @@ -667,7 +712,19 @@ public void GroupByDatePart()
<order alias='createdon_month' />
</entity>
</fetch>");
var aggregate = AssertNode<HashMatchAggregateNode>(tryCatch.CatchSource);
var partitionAggregate = AssertNode<PartitionedAggregateNode>(tryCatch2.CatchSource);
Assert.AreEqual("createdon_month", partitionAggregate.GroupBy[0].ToSql());
Assert.AreEqual("count", partitionAggregate.Aggregates.Single().Key);
var partitionFetch = AssertNode<FetchXmlScan>(partitionAggregate.Source);
AssertFetchXml(partitionFetch, @"
<fetch aggregate='true'>
<entity name='account'>
<attribute name='createdon' groupby='true' alias='createdon_month' dategrouping='month' />
<attribute name='accountid' aggregate='count' alias='count' />
<order alias='createdon_month' />
</entity>
</fetch>");
var aggregate = AssertNode<HashMatchAggregateNode>(tryCatch1.CatchSource);
Assert.AreEqual("createdon_month", aggregate.GroupBy[0].ToSql());
Assert.AreEqual("count", aggregate.Aggregates.Single().Key);
var computeScalar = AssertNode<ComputeScalarNode>(aggregate.Source);
Expand Down Expand Up @@ -2228,8 +2285,9 @@ public void AggregateSort()
var select = AssertNode<SelectNode>(plans[0]);
Assert.AreEqual("account.name", select.ColumnSet[0].SourceColumn);
Assert.AreEqual("count", select.ColumnSet[1].SourceColumn);
var tryCatch = AssertNode<TryCatchNode>(select.Source);
var aggregateFetch = AssertNode<FetchXmlScan>(tryCatch.TrySource);
var tryCatch1 = AssertNode<TryCatchNode>(select.Source);
var tryCatch2 = AssertNode<TryCatchNode>(tryCatch1.TrySource);
var aggregateFetch = AssertNode<FetchXmlScan>(tryCatch2.TrySource);
AssertFetchXml(aggregateFetch, @"
<fetch aggregate='true'>
<entity name='account'>
Expand All @@ -2238,7 +2296,20 @@ public void AggregateSort()
<order alias='count' descending='true' />
</entity>
</fetch>");
var sort = AssertNode<SortNode>(tryCatch.CatchSource);
var partitionSort = AssertNode<SortNode>(tryCatch2.CatchSource);
Assert.AreEqual("count", partitionSort.Sorts.Single().Expression.ToSql());
Assert.AreEqual(SortOrder.Descending, partitionSort.Sorts.Single().SortOrder);
var partitionAggregate = AssertNode<PartitionedAggregateNode>(partitionSort.Source);
var partitionFetch = AssertNode<FetchXmlScan>(partitionAggregate.Source);
AssertFetchXml(partitionFetch, @"
<fetch aggregate='true'>
<entity name='account'>
<attribute name='name' groupby='true' alias='name' />
<attribute name='accountid' aggregate='count' alias='count' />
<order alias='name' />
</entity>
</fetch>");
var sort = AssertNode<SortNode>(tryCatch1.CatchSource);
Assert.AreEqual("count", sort.Sorts.Single().Expression.ToSql());
Assert.AreEqual(SortOrder.Descending, sort.Sorts.Single().SortOrder);
var aggregate = AssertNode<HashMatchAggregateNode>(sort.Source);
Expand Down Expand Up @@ -2805,8 +2876,9 @@ GROUP BY firstname
Assert.AreEqual("Expr1", innerAlias.Alias);
var innerFilter = AssertNode<FilterNode>(innerAlias.Source);
Assert.AreEqual("count > 1", innerFilter.Filter.ToSql());
var innerTry = AssertNode<TryCatchNode>(innerFilter.Source);
var innerAggregateFetch = AssertNode<FetchXmlScan>(innerTry.TrySource);
var innerTry1 = AssertNode<TryCatchNode>(innerFilter.Source);
var innerTry2 = AssertNode<TryCatchNode>(innerTry1.TrySource);
var innerAggregateFetch = AssertNode<FetchXmlScan>(innerTry2.TrySource);

AssertFetchXml(innerAggregateFetch, @"
<fetch aggregate='true'>
Expand All @@ -2817,7 +2889,22 @@ GROUP BY firstname
</entity>
</fetch>");

var innerAggregate = AssertNode<HashMatchAggregateNode>(innerTry.CatchSource);
var innerPartitionAggregate = AssertNode<PartitionedAggregateNode>(innerTry2.CatchSource);
Assert.AreEqual("contact.firstname", innerPartitionAggregate.GroupBy[0].GetColumnName());
Assert.AreEqual("count", innerPartitionAggregate.Aggregates.First().Key);
Assert.AreEqual(AggregateType.CountStar, innerPartitionAggregate.Aggregates.First().Value.AggregateType);
var innerPartitionFetch = AssertNode<FetchXmlScan>(innerPartitionAggregate.Source);

AssertFetchXml(innerPartitionFetch, @"
<fetch aggregate='true'>
<entity name='contact'>
<attribute name='firstname' groupby='true' alias='firstname' />
<attribute name='contactid' aggregate='count' alias='count' />
<order alias='firstname' />
</entity>
</fetch>");

var innerAggregate = AssertNode<HashMatchAggregateNode>(innerTry1.CatchSource);
Assert.AreEqual("contact.firstname", innerAggregate.GroupBy[0].GetColumnName());
Assert.AreEqual("count", innerAggregate.Aggregates.First().Key);
Assert.AreEqual(AggregateType.CountStar, innerAggregate.Aggregates.First().Value.AggregateType);
Expand Down
25 changes: 18 additions & 7 deletions MarkMpn.Sql4Cds.Engine/ExecutionPlan/SortNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,12 @@ public override IDataExecutionPlanNode FoldQuery(IDictionary<string, DataSource>

private IDataExecutionPlanNode FoldSorts(IDictionary<string, DataSource> dataSources, IQueryExecutionOptions options, IDictionary<string, Type> parameterTypes)
{
if (Source is TryCatchNode tryCatch && tryCatch.TrySource is FetchXmlScan tryFetch && tryFetch.FetchXml.aggregate)
var tryCatch = Source as TryCatchNode;

while (tryCatch?.TrySource is TryCatchNode subTry)
tryCatch = subTry;

if (tryCatch != null && tryCatch.TrySource is FetchXmlScan tryFetch && tryFetch.FetchXml.aggregate)
{
// We're sorting on the results of an aggregate that will try to go as a single FetchXML request first, then to a separate plan
// if that fails. Try to fold the sorts in to the aggregate FetchXML first
Expand All @@ -198,13 +203,19 @@ private IDataExecutionPlanNode FoldSorts(IDictionary<string, DataSource> dataSou
tryCatch.TrySource = sortedFetchResult;
sortedFetchResult.Parent = tryCatch;

var nonFetchAggregateSort = new SortNode { Source = tryCatch.CatchSource };
nonFetchAggregateSort.Sorts.AddRange(Sorts);
while (tryCatch != null)
{
var nonFetchAggregateSort = new SortNode { Source = tryCatch.CatchSource };
nonFetchAggregateSort.Sorts.AddRange(Sorts);

var sortedNonFetchResult = nonFetchAggregateSort.FoldSorts(dataSources, options, parameterTypes);
tryCatch.CatchSource = sortedNonFetchResult;
sortedNonFetchResult.Parent = tryCatch;

tryCatch = tryCatch.Parent as TryCatchNode;
}

var sortedNonFetchResult = nonFetchAggregateSort.FoldSorts(dataSources, options, parameterTypes);
tryCatch.CatchSource = sortedNonFetchResult;
sortedNonFetchResult.Parent = tryCatch;
return tryCatch;
return Source;
}
}

Expand Down

0 comments on commit e2a2843

Please sign in to comment.