Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/EFCore.Cosmos/Query/Internal/CosmosQuerySqlGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -476,8 +476,8 @@ protected override Expression VisitSqlBinary(SqlBinaryExpression sqlBinaryExpres
// Arithmetic
ExpressionType.Add => " + ",
ExpressionType.Subtract => " - ",
ExpressionType.Multiply => " * " ,
ExpressionType.Divide => " / " ,
ExpressionType.Multiply => " * ",
ExpressionType.Divide => " / ",
ExpressionType.Modulo => " % ",

// Bitwise >>> (zero-fill right shift) not available in C#
Expand Down Expand Up @@ -513,6 +513,11 @@ protected override Expression VisitSqlBinary(SqlBinaryExpression sqlBinaryExpres
{
op = " || ";
}
else if (sqlBinaryExpression.OperatorType == ExpressionType.ExclusiveOr
&& sqlBinaryExpression.Type == typeof(bool))
{
op = " != ";
}

_sqlBuilder.Append(op);

Expand Down
1 change: 1 addition & 0 deletions src/EFCore.Cosmos/Query/Internal/SqlExpressionFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ private SqlExpression ApplyTypeMappingOnSqlBinary(
case ExpressionType.RightShift:
case ExpressionType.And:
case ExpressionType.Or:
case ExpressionType.ExclusiveOr:
case ExpressionType.Coalesce:
{
inferredTypeMapping = typeMapping ?? ExpressionExtensions.InferTypeMapping(left, right);
Expand Down
1 change: 1 addition & 0 deletions src/EFCore.Relational/Query/QuerySqlGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1096,6 +1096,7 @@ protected virtual string GetOperator(SqlBinaryExpression binaryExpression)
ExpressionType.Modulo => " % ",
ExpressionType.And => " & ",
ExpressionType.Or => " | ",
ExpressionType.ExclusiveOr => " ^ ",

_ => throw new UnreachableException($"Unsupported unary OperatorType: {binaryExpression.OperatorType}")
};
Expand Down
1 change: 1 addition & 0 deletions src/EFCore.Relational/Query/SqlExpressionFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ private SqlExpression ApplyTypeMappingOnSqlBinary(
case ExpressionType.Modulo:
case ExpressionType.And:
case ExpressionType.Or:
case ExpressionType.ExclusiveOr:
{
inferredTypeMapping = typeMapping ?? ExpressionExtensions.InferTypeMapping(left, right);
resultType = inferredTypeMapping?.ClrType ?? left.Type;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ internal static bool IsValidOperator(ExpressionType operatorType)
case ExpressionType.Equal:
case ExpressionType.NotEqual:
case ExpressionType.Coalesce:
case ExpressionType.ExclusiveOr:
return true;
default:
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,7 @@ protected override bool TryGetOperatorInfo(SqlExpression expression, out int pre
ExpressionType.Subtract => (700, false),
ExpressionType.And => (700, true),
ExpressionType.Or => (700, true),
ExpressionType.ExclusiveOr => (700, true),
ExpressionType.LeftShift => (700, true),
ExpressionType.RightShift => (700, true),
ExpressionType.LessThan => (500, false),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,11 @@ protected override Expression VisitBinary(BinaryExpression binaryExpression)

if (visitedExpression is SqlBinaryExpression sqlBinary)
{
if (sqlBinary.OperatorType == ExpressionType.ExclusiveOr)
{
return QueryCompilationContext.NotTranslatedExpression;
}

if (sqlBinary.OperatorType == ExpressionType.Modulo
&& (ModuloFunctions.TryGetValue(GetProviderType(sqlBinary.Left), out var function)
|| ModuloFunctions.TryGetValue(GetProviderType(sqlBinary.Right), out function)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2369,6 +2369,20 @@ public override Task Where_bitwise_binary_or(bool async)
SELECT c
FROM root c
WHERE ((c["Discriminator"] = "Order") AND ((c["OrderID"] | 10248) = 10248))
""");
});

public override Task Where_bitwise_binary_xor(bool async)
=> Fixture.NoSyncTest(
async, async a =>
{
await base.Where_bitwise_binary_xor(async);

AssertSql(
"""
SELECT c
FROM root c
WHERE ((c["Discriminator"] = "Order") AND ((c["OrderID"] ^ 1) = 10249))
""");
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,15 +150,21 @@ FROM root c
""");
});

public override async Task Where_bitwise_xor(bool async)
{
// Bitwise operators on booleans. Issue #13168.
Assert.Equal(
CosmosStrings.UnsupportedOperatorForSqlExpression("ExclusiveOr", "SqlBinaryExpression"),
(await Assert.ThrowsAsync<InvalidOperationException>(() => base.Where_bitwise_xor(async))).Message);
[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public override Task Where_bitwise_xor(bool async)
=> Fixture.NoSyncTest(
async, async a =>
{
await base.Where_bitwise_xor(a);

AssertSql();
}
AssertSql(
"""
SELECT c
FROM root c
WHERE ((c["Discriminator"] = "Customer") AND ((c["CustomerID"] = "ALFKI") != true))
""");
});

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3265,6 +3265,16 @@ public virtual Task Where_bitwise_binary_or(bool async)
async,
ss => ss.Set<Order>().Where(o => (o.OrderID | 10248) == 10248));


[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Where_bitwise_binary_xor(bool async)
{
return AssertQuery(
async,
ss => ss.Set<Order>().Where(o => (o.OrderID ^ 1) == 10249));
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Select_bitwise_or_with_logical_or(bool async)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3257,6 +3257,18 @@ FROM [Orders] AS [o]
""");
}

public override async Task Where_bitwise_binary_xor(bool async)
{
await base.Where_bitwise_binary_xor(async);

AssertSql(
"""
SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate]
FROM [Orders] AS [o]
WHERE [o].[OrderID] ^ 1 = 10249
""");
}

public override async Task Select_bitwise_or_with_logical_or(bool async)
{
await base.Select_bitwise_or_with_logical_or(async);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2446,14 +2446,14 @@ public override async Task Projection_when_arithmetic_mixed_subqueries(bool asyn
"""
@__p_0='3'

SELECT CAST([e0].[EmployeeID] AS bigint) + CAST([o0].[OrderID] AS bigint), [e0].[EmployeeID], [e0].[City], [e0].[Country], [e0].[FirstName], [e0].[ReportsTo], [e0].[Title], [o0].[OrderID], [o0].[CustomerID], [o0].[EmployeeID], [o0].[OrderDate], [o0].[OrderID] % 2
SELECT CAST([e0].[EmployeeID] AS bigint) + CAST([o0].[OrderID] AS bigint) AS [Add], [e0].[Square], [e0].[EmployeeID], [e0].[City], [e0].[Country], [e0].[FirstName], [e0].[ReportsTo], [e0].[Title], 42 AS [Literal], [o0].[OrderID], [o0].[CustomerID], [o0].[EmployeeID], [o0].[OrderDate], [o0].[OrderID] % 2 AS [Mod]
FROM (
SELECT TOP(@__p_0) [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate]
FROM [Orders] AS [o]
ORDER BY [o].[OrderID]
) AS [o0]
CROSS JOIN (
SELECT TOP(2) [e].[EmployeeID], [e].[City], [e].[Country], [e].[FirstName], [e].[ReportsTo], [e].[Title]
SELECT TOP(2) [e].[EmployeeID], [e].[City], [e].[Country], [e].[FirstName], [e].[ReportsTo], [e].[Title], [e].[EmployeeID] ^ 2 AS [Square]
FROM [Employees] AS [e]
ORDER BY [e].[EmployeeID]
) AS [e0]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -515,10 +515,17 @@ FROM [Customers] AS [c]

public override async Task Where_bitwise_xor(bool async)
{
// Cannot eval 'where (([c].CustomerID == \"ALFKI\") ^ True)'. Issue #16645.
await AssertTranslationFailed(() => base.Where_bitwise_xor(async));
await base.Where_bitwise_xor(async);

AssertSql();
AssertSql(
"""
SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region]
FROM [Customers] AS [c]
WHERE CASE
WHEN [c].[CustomerID] = N'ALFKI' THEN CAST(1 AS bit)
ELSE CAST(0 AS bit)
END ^ CAST(1 AS bit) = CAST(1 AS bit)
""");
}

public override async Task Where_simple_shadow(bool async)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,11 @@ LIMIT @__p_0
""");
}

[ConditionalTheory(Skip = "Issue #16645 bitwise xor support")]
[MemberData(nameof(IsAsyncData))]
public override Task Where_bitwise_binary_xor(bool async)
=> AssertTranslationFailed(() => base.Where_bitwise_binary_xor(async));

public override Task Complex_nested_query_doesnt_try_binding_to_grandparent_when_parent_returns_complex_result(bool async)
=> null;

Expand Down