Skip to content

Commit

Permalink
Fixed use of IS DISTINCT FROM in cross-column comparisons
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkMpn committed Aug 24, 2024
1 parent 7ce905b commit ac8ca3c
Showing 1 changed file with 67 additions and 0 deletions.
67 changes: 67 additions & 0 deletions MarkMpn.Sql4Cds.Engine/ExecutionPlan/BaseDataNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,73 @@ private bool TranslateFetchXMLCriteria(NodeCompilationContext context, DataSourc
};
condition = null;
}
else if (op == @operator.ne && type == BooleanComparisonType.IsDistinctFrom)
{
// FetchXML ne operator translates to field1 != field2 OR field1 IS NULL
// IS DISTINCT FROM is equivalent to field1 != field2 OR (field1 IS NULL AND field2 IS NOT NULL) OR (field1 IS NOT NULL AND field2 IS NULL)
// Need to add an extra condition to counteract the automatic "OR field1 IS NULL" part,
// and add the other null checks as well
filter = new filter
{
type = filterType.or,
Items = new object[]
{
new filter
{
type = filterType.and,
Items = new object[]
{
condition,
new condition
{
entityname = StandardizeAlias(entityAlias, targetEntityAlias, items),
attribute = RemoveAttributeAlias(attrName, entityAlias, targetEntityAlias, items),
@operator = @operator.notnull
}
}
},
new filter
{
type = filterType.and,
Items = new object[]
{
new condition
{
entityname = StandardizeAlias(entityAlias, targetEntityAlias, items),
attribute = RemoveAttributeAlias(attrName, entityAlias, targetEntityAlias, items),
@operator = @operator.@null
},
new condition
{
entityname = StandardizeAlias(entityAlias2, targetEntityAlias, items),
attribute = RemoveAttributeAlias(attrName2, entityAlias2, targetEntityAlias, items),
@operator = @operator.notnull
}
}
},
new filter
{
type = filterType.and,
Items = new object[]
{
new condition
{
entityname = StandardizeAlias(entityAlias, targetEntityAlias, items),
attribute = RemoveAttributeAlias(attrName, entityAlias, targetEntityAlias, items),
@operator = @operator.notnull
},
new condition
{
entityname = StandardizeAlias(entityAlias2, targetEntityAlias, items),
attribute = RemoveAttributeAlias(attrName2, entityAlias2, targetEntityAlias, items),
@operator = @operator.@null
}
}
}
}
};
condition = null;
}
else if (op == @operator.eq && type == BooleanComparisonType.IsNotDistinctFrom)
{
// FetchXML eq operator does not match records where both fields are null.
Expand Down

0 comments on commit ac8ca3c

Please sign in to comment.