Skip to content

Commit

Permalink
Improved folding CTE to FetchXML
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkMpn committed Oct 22, 2023
1 parent 41a0e3e commit a74a25b
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 4 deletions.
17 changes: 17 additions & 0 deletions MarkMpn.Sql4Cds.Engine.Tests/FakeXrmEasyTestsBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ public FakeXrmEasyTestsBase()

SetColumnNumber(_context);
SetColumnNumber(_context2);

SetRelationships(_context);
SetRelationships(_context2);
}

private void SetPrimaryNameAttributes(XrmFakedContext context)
Expand Down Expand Up @@ -243,5 +246,19 @@ private void SetColumnNumber(XrmFakedContext context)
context.SetEntityMetadata(entity);
}
}

private void SetRelationships(XrmFakedContext context)
{
foreach (var entity in context.CreateMetadataQuery())
{
if (entity.OneToManyRelationships == null)
typeof(EntityMetadata).GetProperty(nameof(EntityMetadata.OneToManyRelationships)).SetValue(entity, Array.Empty<OneToManyRelationshipMetadata>());

if (entity.ManyToOneRelationships == null)
typeof(EntityMetadata).GetProperty(nameof(EntityMetadata.ManyToOneRelationships)).SetValue(entity, Array.Empty<OneToManyRelationshipMetadata>());

context.SetEntityMetadata(entity);
}
}
}
}
1 change: 1 addition & 0 deletions MarkMpn.Sql4Cds.Engine/ExecutionPlan/AliasNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ internal void FoldToFetchXML(FetchXmlScan fetchXml)
// Add the mappings to the FetchXML to produce the columns with the expected names, and hide all other possible columns
var originalAlias = fetchXml.Alias.EscapeIdentifier();
fetchXml.Alias = Alias;
fetchXml.ColumnMappings.Clear();

var escapedAlias = Alias.EscapeIdentifier();

Expand Down
30 changes: 26 additions & 4 deletions MarkMpn.Sql4Cds.Engine/ExecutionPlan/IndexSpoolNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,34 @@ private IDataExecutionPlanNodeInternal FoldCTEToFetchXml(NodeCompilationContext
anchorFetchXml.Entity.name != spooledRecursiveFetchXml.Entity.name)
return this;

// TODO: Check for any other filters or link-entities
// Check for any other filters or link-entities
if (spooledRecursiveFetchXml.Entity.GetLinkEntities().Any() ||
spooledRecursiveFetchXml.Entity.Items != null && spooledRecursiveFetchXml.Entity.Items.OfType<filter>().Any())
return this;

// Check there are no extra calculated columns
if (initialDepthCompute.Columns.Count != 1 || incrementDepthCompute.Columns.Count != 1)
return this;

// Check all columns are consistent
var depthField = initialDepthCompute.Columns.Single().Key;

// TODO: Check all columns are consistent
for (var i = 0; i < concat.ColumnSet.Count; i++)
{
if (concat.ColumnSet[i].SourceColumns[0] == depthField)
continue;

var anchorAttribute = concat.ColumnSet[i].SourceColumns[0];
var recurseAttribute = concat.ColumnSet[i].SourceColumns[1];
recurseAttribute = recurseLoop.DefinedValues[recurseAttribute];

// TODO: Check there are no extra calculated columns
// Ignore any differences in the aliases used for the anchor and recursive parts
anchorAttribute = anchorAttribute.ToColumnReference().MultiPartIdentifier.Identifiers.Last().Value;
recurseAttribute = recurseAttribute.ToColumnReference().MultiPartIdentifier.Identifiers.Last().Value;

if (anchorAttribute != recurseAttribute)
return this;
}

var metadata = context.DataSources[anchorFetchXml.DataSource].Metadata[anchorFetchXml.Entity.name];
var hierarchicalRelationship = metadata.OneToManyRelationships.SingleOrDefault(r => r.IsHierarchical == true);
Expand Down Expand Up @@ -200,7 +223,6 @@ private IDataExecutionPlanNodeInternal FoldCTEToFetchXml(NodeCompilationContext
return this;

// The depth counter is no longer generated or used, so remove it from the concat column list
var depthField = initialDepthCompute.Columns.Single().Key;
var depthFieldConcatColumn = concat.ColumnSet.Single(c => c.SourceColumns[0] == depthField);
concat.ColumnSet.Remove(depthFieldConcatColumn);

Expand Down

0 comments on commit a74a25b

Please sign in to comment.