Skip to content

Commit

Permalink
Fix SQL Server operator precedence table (#33875)
Browse files Browse the repository at this point in the history
Specifically, binary logical operators have the same precedence as `+`/`-`.

Fixes #30248
  • Loading branch information
ranma42 authored Jun 2, 2024
1 parent 510243d commit 77097ee
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -649,16 +649,16 @@ protected override bool TryGetOperatorInfo(SqlExpression expression, out int pre
ExpressionType.Multiply => (900, true),
ExpressionType.Divide => (900, false),
ExpressionType.Modulo => (900, false),
ExpressionType.Add => (800, true),
ExpressionType.Subtract => (800, false),
ExpressionType.Add => (700, true),
ExpressionType.Subtract => (700, false),
ExpressionType.And => (700, true),
ExpressionType.Or => (700, true),
ExpressionType.LeftShift => (700, true),
ExpressionType.RightShift => (700, true),
ExpressionType.LessThan => (600, false),
ExpressionType.LessThanOrEqual => (600, false),
ExpressionType.GreaterThan => (600, false),
ExpressionType.GreaterThanOrEqual => (600, false),
ExpressionType.LessThan => (500, false),
ExpressionType.LessThanOrEqual => (500, false),
ExpressionType.GreaterThan => (500, false),
ExpressionType.GreaterThanOrEqual => (500, false),
ExpressionType.Equal => (500, false),
ExpressionType.NotEqual => (500, false),
ExpressionType.AndAlso => (200, true),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ from o3 in context.Set<OperatorEntityBool>()
}
}

[ConditionalFact(Skip = "issue #30248")]
[ConditionalFact]
public virtual async Task Complex_predicate_with_bitwise_and_modulo_and_negation()
{
var contextFactory = await InitializeAsync<OperatorsContext>(seed: Seed);
Expand All @@ -77,6 +77,7 @@ public virtual async Task Complex_predicate_with_bitwise_and_modulo_and_negation
from e1 in ExpectedData.OperatorEntitiesLong
from e2 in ExpectedData.OperatorEntitiesLong
from e3 in ExpectedData.OperatorEntitiesLong
orderby e0.Id, e1.Id, e2.Id, e3.Id
where ((((e1.Value % 2) / e0.Value) & (((e3.Value | e2.Value) - e0.Value) - (e2.Value * e2.Value)))
>= (((e1.Value / ~(e3.Value)) % (1 + 1)) % (~(e0.Value) + 1)))
select new
Expand All @@ -91,6 +92,7 @@ from e3 in ExpectedData.OperatorEntitiesLong
from e1 in context.Set<OperatorEntityLong>()
from e2 in context.Set<OperatorEntityLong>()
from e3 in context.Set<OperatorEntityLong>()
orderby e0.Id, e1.Id, e2.Id, e3.Id
where ((((e1.Value % 2) / e0.Value) & (((e3.Value | e2.Value) - e0.Value) - (e2.Value * e2.Value)))
>= (((e1.Value / ~(e3.Value)) % (1 + 1)) % (~(e0.Value) + 1)))
select new
Expand All @@ -111,7 +113,7 @@ from e3 in context.Set<OperatorEntityLong>()
}
}

[ConditionalFact(Skip = "issue #30248")]
[ConditionalFact]
public virtual async Task Complex_predicate_with_bitwise_and_arithmetic_operations()
{
var contextFactory = await InitializeAsync<OperatorsContext>(seed: Seed);
Expand All @@ -121,6 +123,7 @@ public virtual async Task Complex_predicate_with_bitwise_and_arithmetic_operatio
from e1 in ExpectedData.OperatorEntitiesInt
from e2 in ExpectedData.OperatorEntitiesBool
where (((((e1.Value & (e0.Value + e0.Value)) & e0.Value) / 1) > (e1.Value & 8 + 2)) && e2.Value)
orderby e0.Id, e1.Id, e2.Id
select new
{
Value0 = e0.Value,
Expand All @@ -132,6 +135,7 @@ from e2 in ExpectedData.OperatorEntitiesBool
from e1 in context.Set<OperatorEntityInt>()
from e2 in context.Set<OperatorEntityBool>()
where (((((e1.Value & (e0.Value + e0.Value)) & e0.Value) / 1) > (e1.Value & 8 + 2)) && e2.Value)
orderby e0.Id, e1.Id, e2.Id
select new
{
Value0 = e0.Value,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,31 @@ public override async Task Complex_predicate_with_bitwise_and_modulo_and_negatio
{
await base.Complex_predicate_with_bitwise_and_modulo_and_negation();

AssertSql("");
AssertSql(
"""
SELECT [o].[Value] AS [Value0], [o0].[Value] AS [Value1], [o1].[Value] AS [Value2], [o2].[Value] AS [Value3]
FROM [OperatorEntityLong] AS [o]
CROSS JOIN [OperatorEntityLong] AS [o0]
CROSS JOIN [OperatorEntityLong] AS [o1]
CROSS JOIN [OperatorEntityLong] AS [o2]
WHERE ([o0].[Value] % CAST(2 AS bigint)) / [o].[Value] & ((([o2].[Value] | [o1].[Value]) - [o].[Value]) - [o1].[Value] * [o1].[Value]) >= (([o0].[Value] / ~[o2].[Value]) % CAST(2 AS bigint)) % (~[o].[Value] + CAST(1 AS bigint))
ORDER BY [o].[Id], [o0].[Id], [o1].[Id], [o2].[Id]
""");
}

public override async Task Complex_predicate_with_bitwise_and_arithmetic_operations()
{
await base.Complex_predicate_with_bitwise_and_arithmetic_operations();

AssertSql("");
AssertSql(
"""
SELECT [o].[Value] AS [Value0], [o0].[Value] AS [Value1], [o1].[Value] AS [Value2]
FROM [OperatorEntityInt] AS [o]
CROSS JOIN [OperatorEntityInt] AS [o0]
CROSS JOIN [OperatorEntityBool] AS [o1]
WHERE ([o0].[Value] & ([o].[Value] + [o].[Value]) & [o].[Value]) / 1 > [o0].[Value] & 10 AND [o1].[Value] = CAST(1 AS bit)
ORDER BY [o].[Id], [o0].[Id], [o1].[Id]
""");
}

public override async Task Or_on_two_nested_binaries_and_another_simple_comparison()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,31 @@ public override async Task Complex_predicate_with_bitwise_and_modulo_and_negatio
{
await base.Complex_predicate_with_bitwise_and_modulo_and_negation();

AssertSql("");
AssertSql(
"""
SELECT "o"."Value" AS "Value0", "o0"."Value" AS "Value1", "o1"."Value" AS "Value2", "o2"."Value" AS "Value3"
FROM "OperatorEntityLong" AS "o"
CROSS JOIN "OperatorEntityLong" AS "o0"
CROSS JOIN "OperatorEntityLong" AS "o1"
CROSS JOIN "OperatorEntityLong" AS "o2"
WHERE ("o0"."Value" % 2) / "o"."Value" & (("o2"."Value" | "o1"."Value") - "o"."Value") - "o1"."Value" * "o1"."Value" >= (("o0"."Value" / ~"o2"."Value") % 2) % (~"o"."Value" + 1)
ORDER BY "o"."Id", "o0"."Id", "o1"."Id", "o2"."Id"
""");
}

public override async Task Complex_predicate_with_bitwise_and_arithmetic_operations()
{
await base.Complex_predicate_with_bitwise_and_arithmetic_operations();

AssertSql("");
AssertSql(
"""
SELECT "o"."Value" AS "Value0", "o0"."Value" AS "Value1", "o1"."Value" AS "Value2"
FROM "OperatorEntityInt" AS "o"
CROSS JOIN "OperatorEntityInt" AS "o0"
CROSS JOIN "OperatorEntityBool" AS "o1"
WHERE ("o0"."Value" & "o"."Value" + "o"."Value" & "o"."Value") / 1 > "o0"."Value" & 10 AND "o1"."Value"
ORDER BY "o"."Id", "o0"."Id", "o1"."Id"
""");
}

public override async Task Or_on_two_nested_binaries_and_another_simple_comparison()
Expand Down

0 comments on commit 77097ee

Please sign in to comment.