Skip to content

Commit

Permalink
Added not-null filter to index spool key fields
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkMpn committed May 28, 2024
1 parent bcfdaf0 commit 7702e46
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 5 deletions.
3 changes: 3 additions & 0 deletions MarkMpn.Sql4Cds.Engine.Tests/CteTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,9 @@ UNION ALL
<attribute name='firstname' />
<attribute name='lastname' />
<attribute name='parentcustomerid' />
<filter>
<condition attribute='parentcustomerid' operator='not-null' />
</filter>
</entity>
</fetch>");
}
Expand Down
35 changes: 30 additions & 5 deletions MarkMpn.Sql4Cds.Engine/ExecutionPlan/IndexSpoolNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,28 @@ public override IDataExecutionPlanNodeInternal FoldQuery(NodeCompilationContext
if (KeyColumn != null && SeekValue != null)
{
// Index and seek values must be the same type
var indexType = Source.GetSchema(context).Schema[KeyColumn].Type;
var indexCol = Source.GetSchema(context).Schema[KeyColumn];
var seekType = context.ParameterTypes[SeekValue];

if (!SqlTypeConverter.CanMakeConsistentTypes(indexType, seekType, context.PrimaryDataSource, null, null, out var consistentType))
throw new QueryExecutionException($"No type conversion available for {indexType.ToSql()} and {seekType.ToSql()}");
if (!SqlTypeConverter.CanMakeConsistentTypes(indexCol.Type, seekType, context.PrimaryDataSource, null, null, out var consistentType))
throw new QueryExecutionException(Sql4CdsError.TypeClash(null, indexCol.Type, seekType));

_keySelector = SqlTypeConverter.GetConversion(indexType, consistentType);
_keySelector = SqlTypeConverter.GetConversion(indexCol.Type, consistentType);
_seekSelector = SqlTypeConverter.GetConversion(seekType, consistentType);

if (!WithStack && indexCol.IsNullable)
{
// Try to fold a NOT NULL filter into the source - we'll never match a null value with an equality operator
Source = new FilterNode
{
Source = Source,
Filter = new BooleanIsNullExpression
{
Expression = KeyColumn.ToColumnReference(),
IsNot = true
}
}.FoldQuery(context, hints);
}
}

if (WithStack)
Expand Down Expand Up @@ -168,7 +182,18 @@ private IDataExecutionPlanNodeInternal FoldCTEToFetchXml(NodeCompilationContext
// 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;
{
// We might have added a not-null filter on the key column, so ignore that
var filters = spooledRecursiveFetchXml.Entity.Items.OfType<filter>().ToArray();
if (filters.Length != 1 ||
filters[0].Items.Length != 1 ||
!(filters[0].Items[0] is condition condition) ||
condition.attribute != adaptiveSpool.KeyColumn.SplitMultiPartIdentifier().Last() ||
condition.@operator != @operator.notnull)
{
return this;
}
}

// Check there are no extra calculated columns
if (initialDepthCompute.Columns.Count != 1 || incrementDepthCompute.Columns.Count != 1)
Expand Down
34 changes: 34 additions & 0 deletions MarkMpn.Sql4Cds.sln
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MarkMpn.Sql4Cds.SSMS.20", "
EndProject
Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "MarkMpn.Sql4Cds.SSMS.20.Setup", "MarkMpn.Sql4Cds.SSMS.20.Setup\MarkMpn.Sql4Cds.SSMS.20.Setup.wixproj", "{FE9EF004-BD77-49DA-85B5-D51DAEB76274}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MarkMpn.Sql4Cds.DebuggerVisualizer", "MarkMpn.Sql4Cds.DebuggerVisualizer\MarkMpn.Sql4Cds.DebuggerVisualizer.csproj", "{F35F82A7-29E5-4EE2-90A9-72EB913F1296}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MarkMpn.Sql4Cds.DebuggerVisualizer.Debugee", "MarkMpn.Sql4Cds.DebuggerVisualizer.Debugee\MarkMpn.Sql4Cds.DebuggerVisualizer.Debugee.csproj", "{6367A133-439D-4FA0-AA62-EEACC7A605FB}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DebuggerVisualizer", "DebuggerVisualizer", "{395CF6D2-5DDE-4A42-81A8-B1C4FF20C736}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -232,10 +238,38 @@ Global
{FE9EF004-BD77-49DA-85B5-D51DAEB76274}.Release|arm64.Build.0 = Release|x86
{FE9EF004-BD77-49DA-85B5-D51DAEB76274}.Release|x86.ActiveCfg = Release|x86
{FE9EF004-BD77-49DA-85B5-D51DAEB76274}.Release|x86.Build.0 = Release|x86
{F35F82A7-29E5-4EE2-90A9-72EB913F1296}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F35F82A7-29E5-4EE2-90A9-72EB913F1296}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F35F82A7-29E5-4EE2-90A9-72EB913F1296}.Debug|arm64.ActiveCfg = Debug|Any CPU
{F35F82A7-29E5-4EE2-90A9-72EB913F1296}.Debug|arm64.Build.0 = Debug|Any CPU
{F35F82A7-29E5-4EE2-90A9-72EB913F1296}.Debug|x86.ActiveCfg = Debug|Any CPU
{F35F82A7-29E5-4EE2-90A9-72EB913F1296}.Debug|x86.Build.0 = Debug|Any CPU
{F35F82A7-29E5-4EE2-90A9-72EB913F1296}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F35F82A7-29E5-4EE2-90A9-72EB913F1296}.Release|Any CPU.Build.0 = Release|Any CPU
{F35F82A7-29E5-4EE2-90A9-72EB913F1296}.Release|arm64.ActiveCfg = Release|Any CPU
{F35F82A7-29E5-4EE2-90A9-72EB913F1296}.Release|arm64.Build.0 = Release|Any CPU
{F35F82A7-29E5-4EE2-90A9-72EB913F1296}.Release|x86.ActiveCfg = Release|Any CPU
{F35F82A7-29E5-4EE2-90A9-72EB913F1296}.Release|x86.Build.0 = Release|Any CPU
{6367A133-439D-4FA0-AA62-EEACC7A605FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6367A133-439D-4FA0-AA62-EEACC7A605FB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6367A133-439D-4FA0-AA62-EEACC7A605FB}.Debug|arm64.ActiveCfg = Debug|Any CPU
{6367A133-439D-4FA0-AA62-EEACC7A605FB}.Debug|arm64.Build.0 = Debug|Any CPU
{6367A133-439D-4FA0-AA62-EEACC7A605FB}.Debug|x86.ActiveCfg = Debug|Any CPU
{6367A133-439D-4FA0-AA62-EEACC7A605FB}.Debug|x86.Build.0 = Debug|Any CPU
{6367A133-439D-4FA0-AA62-EEACC7A605FB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6367A133-439D-4FA0-AA62-EEACC7A605FB}.Release|Any CPU.Build.0 = Release|Any CPU
{6367A133-439D-4FA0-AA62-EEACC7A605FB}.Release|arm64.ActiveCfg = Release|Any CPU
{6367A133-439D-4FA0-AA62-EEACC7A605FB}.Release|arm64.Build.0 = Release|Any CPU
{6367A133-439D-4FA0-AA62-EEACC7A605FB}.Release|x86.ActiveCfg = Release|Any CPU
{6367A133-439D-4FA0-AA62-EEACC7A605FB}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{F35F82A7-29E5-4EE2-90A9-72EB913F1296} = {395CF6D2-5DDE-4A42-81A8-B1C4FF20C736}
{6367A133-439D-4FA0-AA62-EEACC7A605FB} = {395CF6D2-5DDE-4A42-81A8-B1C4FF20C736}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {5E960561-7FE2-4022-964B-57E990767108}
EndGlobalSection
Expand Down

0 comments on commit 7702e46

Please sign in to comment.