Skip to content

Commit

Permalink
Allow folding IN criteria using variables to FetchXML
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkMpn committed Sep 28, 2024
1 parent e9d5d20 commit 384e94a
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 2 deletions.
32 changes: 32 additions & 0 deletions MarkMpn.Sql4Cds.Engine.Tests/ExecutionPlanTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8549,5 +8549,37 @@ public void DeleteByIdUsesConstantScan()
var delete = AssertNode<DeleteNode>(plans[0]);
var constant = AssertNode<ConstantScanNode>(delete.Source);
}

[TestMethod]
public void InVariables()
{
var planBuilder = new ExecutionPlanBuilder(_localDataSources.Values, this);

var query = "SELECT name FROM account WHERE accountid IN (@Id1, @Id2)";
var parameterTypes = new Dictionary<string, DataTypeReference>
{
["@Id1"] = DataTypeHelpers.UniqueIdentifier,
["@Id2"] = DataTypeHelpers.UniqueIdentifier
};

var plans = planBuilder.Build(query, parameterTypes, out _);

Assert.AreEqual(1, plans.Length);

var select = AssertNode<SelectNode>(plans[0]);
var fetch = AssertNode<FetchXmlScan>(select.Source);
AssertFetchXml(fetch, @"
<fetch xmlns:generator='MarkMpn.SQL4CDS'>
<entity name='account'>
<attribute name='name' />
<filter>
<condition attribute='accountid' operator='in'>
<value generator:IsVariable='true'>@Id1</value>
<value generator:IsVariable='true'>@Id2</value>
</condition>
</filter>
</entity>
</fetch>");
}
}
}
4 changes: 2 additions & 2 deletions MarkMpn.Sql4Cds.Engine/ExecutionPlan/BaseDataNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -709,7 +709,7 @@ private bool TranslateFetchXMLCriteria(NodeCompilationContext context, DataSourc
if (inPred.Subquery != null)
return false;

if (!inPred.Values.All(v => v is Literal))
if (!inPred.Values.All(v => v is ValueExpression))
return false;

var columnName = inCol.GetColumnName();
Expand All @@ -732,7 +732,7 @@ private bool TranslateFetchXMLCriteria(NodeCompilationContext context, DataSourc

var meta = dataSource.Metadata[entityName];

return TranslateFetchXMLCriteriaWithVirtualAttributes(context, meta, entityAlias, attrName, null, op, inPred.Values.Cast<Literal>().ToArray(), dataSource, targetEntityAlias, items, out condition, out filter);
return TranslateFetchXMLCriteriaWithVirtualAttributes(context, meta, entityAlias, attrName, null, op, inPred.Values.Cast<ValueExpression>().ToArray(), dataSource, targetEntityAlias, items, out condition, out filter);
}

if (criteria is BooleanIsNullExpression isNull)
Expand Down

0 comments on commit 384e94a

Please sign in to comment.