Skip to content

Commit

Permalink
Handle virtual entity providers that don't respect filters
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkMpn committed Jul 11, 2024
1 parent e56960e commit 79bf414
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 1 deletion.
9 changes: 8 additions & 1 deletion MarkMpn.Sql4Cds.Engine/ExecutionPlan/FetchXmlScan.cs
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,13 @@ private void OnRetrievedEntity(Entity entity, INodeSchema schema, IQueryExecutio
// than expected, e.g. msdyn_componentlayer returns string values as guids. Convert the CLR
// values to the correct type before converting to SQL types.
var expectedClrType = SqlTypeConverter.SqlToNetType(col.Value.Type.ToNetType(out _));

// Unwrap common types
if (value is OptionSetValue osv)
value = osv.Value;
else if (value is Money m)
value = m.Value;

if (value.GetType() != expectedClrType)
{
if (value is Guid guidValue)
Expand Down Expand Up @@ -806,7 +813,7 @@ private void OnRetrievedEntity(Entity entity, INodeSchema schema, IQueryExecutio
throw new QueryExecutionException($"Expected {expectedClrType.Name} value, got {value.GetType()}");
}
}
else
else if (value is IConvertible)
{
value = Convert.ChangeType(value, expectedClrType);
}
Expand Down
7 changes: 7 additions & 0 deletions MarkMpn.Sql4Cds.Engine/ExecutionPlan/FilterNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1492,6 +1492,8 @@ private bool FoldFiltersToDataSources(NodeCompilationContext context, IList<Opti
throw new NotSupportedQueryFragmentException("Missing datasource " + fetchXml.DataSource);

// If the criteria are ANDed, see if any of the individual conditions can be translated to FetchXML
var originalFilter = fetchXml.IsUnreliableVirtualEntityProvider ? Filter.Clone() : null;

Filter = ExtractFetchXMLFilters(
foldableContext,
dataSource,
Expand Down Expand Up @@ -1521,6 +1523,11 @@ private bool FoldFiltersToDataSources(NodeCompilationContext context, IList<Opti
fetchXml.Entity.Items = fetchXml.Entity.Items.Except(notNull).ToArray();
}
}

// Virtual entity providers are unreliable - fold the filters to the FetchXML but keep this
// node to filter again if necessary
if (originalFilter != null)
Filter = originalFilter;
}

if (source is MetadataQueryNode meta)
Expand Down

0 comments on commit 79bf414

Please sign in to comment.