diff --git a/QueryBaseline.cs b/QueryBaseline.cs index ae7130b75..c0803e86f 100644 --- a/QueryBaseline.cs +++ b/QueryBaseline.cs @@ -3796,3 +3796,221 @@ +System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions) : + AssertSql( + @"SELECT (o.""OrderDate"" + MAKE_INTERVAL(secs => 1)) AS ""OrderDate"" +FROM ""Orders"" AS o +WHERE o.""OrderDate"" IS NOT NULL"); + + + +System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions) : + AssertSql( + @"SELECT (o.""OrderDate"" + MAKE_INTERVAL(years => 1)) AS ""OrderDate"" +FROM ""Orders"" AS o +WHERE o.""OrderDate"" IS NOT NULL"); + + + +System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions) : + AssertSql( + @"SELECT (o.""OrderDate"" + MAKE_INTERVAL(mins => 1)) AS ""OrderDate"" +FROM ""Orders"" AS o +WHERE o.""OrderDate"" IS NOT NULL"); + + + +System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions) : + AssertSql( + @"@__years_0='2' + +SELECT (o.""OrderDate"" + MAKE_INTERVAL(years => @__years_0)) AS ""OrderDate"" +FROM ""Orders"" AS o +WHERE o.""OrderDate"" IS NOT NULL"); + + + +System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions) : + AssertSql( + @"SELECT (o.""OrderDate"" + MAKE_INTERVAL(months => 1)) AS ""OrderDate"" +FROM ""Orders"" AS o +WHERE o.""OrderDate"" IS NOT NULL"); + + + +System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions) : + AssertSql( + @"SELECT (o.""OrderDate"" + MAKE_INTERVAL(hours => 1)) AS ""OrderDate"" +FROM ""Orders"" AS o +WHERE o.""OrderDate"" IS NOT NULL"); + + + +System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions) : + AssertSql( + @"SELECT (to_tsquery('a & b') && to_tsquery('c & d')) +FROM ""Customers"" AS c +LIMIT 1"); + + + +System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions) : + AssertSql( + @"SELECT (to_tsquery('a & b') || to_tsquery('c & d')) +FROM ""Customers"" AS c +LIMIT 1"); + + + +System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions) : + AssertSql( + @"SELECT (to_tsvector('a') @@ 'b') +FROM ""Customers"" AS c +LIMIT 1"); + + + +System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions) : + AssertSql( + @"SELECT (to_tsvector('a') @@ to_tsquery('b')) +FROM ""Customers"" AS c +LIMIT 1"); + + + +System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions) : + AssertSql( + @"SELECT (to_tsquery('b') <@ to_tsquery('a & b')) +FROM ""Customers"" AS c +LIMIT 1"); + + + +System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions) : + AssertSql( + @"SELECT (to_tsquery('a & b') @> to_tsquery('b')) +FROM ""Customers"" AS c +LIMIT 1"); + + + +System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions) : + AssertSql( + @"SELECT (to_tsvector('b') || to_tsvector('c')) +FROM ""Customers"" AS c +LIMIT 1"); + + + +System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions) : + AssertSql( + @"SELECT (to_tsquery('a & b') && to_tsquery('c & d')) +FROM ""Customers"" AS c +LIMIT 1"); + + + +System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions) : + AssertSql( + @"SELECT (to_tsquery('a & b') || to_tsquery('c & d')) +FROM ""Customers"" AS c +LIMIT 1"); + + + +System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions) : + AssertSql( + @"SELECT (to_tsvector('a') @@ 'b') +FROM ""Customers"" AS c +LIMIT 1"); + + + +System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions) : + AssertSql( + @"SELECT (to_tsvector('a') @@ to_tsquery('b')) +FROM ""Customers"" AS c +LIMIT 1"); + + + +System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions) : + AssertSql( + @"SELECT (to_tsquery('b') <@ to_tsquery('a & b')) +FROM ""Customers"" AS c +LIMIT 1"); + + + +System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions) : + AssertSql( + @"SELECT (to_tsquery('a & b') @> to_tsquery('b')) +FROM ""Customers"" AS c +LIMIT 1"); + + + +System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions) : + AssertSql( + @"SELECT (to_tsvector('b') || to_tsvector('c')) +FROM ""Customers"" AS c +LIMIT 1"); + + + +Npgsql.EntityFrameworkCore.PostgreSQL.Query.FullTextSearchDbFunctionsNpgsqlTest.TsQueryAnd() : + AssertSql( + @"SELECT (to_tsquery('a & b') && to_tsquery('c & d')) +FROM ""Customers"" AS c +LIMIT 1"); + + + +Npgsql.EntityFrameworkCore.PostgreSQL.Query.FullTextSearchDbFunctionsNpgsqlTest.TsQueryOr() : + AssertSql( + @"SELECT (to_tsquery('a & b') || to_tsquery('c & d')) +FROM ""Customers"" AS c +LIMIT 1"); + + + +Npgsql.EntityFrameworkCore.PostgreSQL.Query.FullTextSearchDbFunctionsNpgsqlTest.Matches_With_String() : + AssertSql( + @"SELECT (to_tsvector('a') @@ 'b') +FROM ""Customers"" AS c +LIMIT 1"); + + + +Npgsql.EntityFrameworkCore.PostgreSQL.Query.FullTextSearchDbFunctionsNpgsqlTest.Matches_With_Tsquery() : + AssertSql( + @"SELECT (to_tsvector('a') @@ to_tsquery('b')) +FROM ""Customers"" AS c +LIMIT 1"); + + + +Npgsql.EntityFrameworkCore.PostgreSQL.Query.FullTextSearchDbFunctionsNpgsqlTest.TsQueryIsContainedIn() : + AssertSql( + @"SELECT (to_tsquery('b') <@ to_tsquery('a & b')) +FROM ""Customers"" AS c +LIMIT 1"); + + + +Npgsql.EntityFrameworkCore.PostgreSQL.Query.FullTextSearchDbFunctionsNpgsqlTest.TsQueryContains() : + AssertSql( + @"SELECT (to_tsquery('a & b') @> to_tsquery('b')) +FROM ""Customers"" AS c +LIMIT 1"); + + + +Npgsql.EntityFrameworkCore.PostgreSQL.Query.FullTextSearchDbFunctionsNpgsqlTest.TsVectorConcat() : + AssertSql( + @"SELECT (to_tsvector('b') || to_tsvector('c')) +FROM ""Customers"" AS c +LIMIT 1"); + + + diff --git a/src/EFCore.PG/Query/Sql/Internal/NpgsqlQuerySqlGenerator.cs b/src/EFCore.PG/Query/Sql/Internal/NpgsqlQuerySqlGenerator.cs index 7d7bde9ea..287764238 100644 --- a/src/EFCore.PG/Query/Sql/Internal/NpgsqlQuerySqlGenerator.cs +++ b/src/EFCore.PG/Query/Sql/Internal/NpgsqlQuerySqlGenerator.cs @@ -322,11 +322,13 @@ public virtual Expression VisitCustomBinary(CustomBinaryExpression expression) { Check.NotNull(expression, nameof(expression)); + Sql.Append('('); Visit(expression.Left); - Sql.Append(" "); + Sql.Append(' '); Sql.Append(expression.Operator); - Sql.Append(" "); + Sql.Append(' '); Visit(expression.Right); + Sql.Append(')'); return expression; } diff --git a/test/EFCore.PG.FunctionalTests/Query/FullTextSearchDbFunctionsNpgsqlTest.cs b/test/EFCore.PG.FunctionalTests/Query/FullTextSearchDbFunctionsNpgsqlTest.cs index 9178914cc..6d8acf722 100644 --- a/test/EFCore.PG.FunctionalTests/Query/FullTextSearchDbFunctionsNpgsqlTest.cs +++ b/test/EFCore.PG.FunctionalTests/Query/FullTextSearchDbFunctionsNpgsqlTest.cs @@ -208,7 +208,7 @@ public void TsQueryAnd() } AssertSql( - @"SELECT to_tsquery('a & b') && to_tsquery('c & d') + @"SELECT (to_tsquery('a & b') && to_tsquery('c & d')) FROM ""Customers"" AS c LIMIT 1"); } @@ -225,7 +225,7 @@ public void TsQueryOr() } AssertSql( - @"SELECT to_tsquery('a & b') || to_tsquery('c & d') + @"SELECT (to_tsquery('a & b') || to_tsquery('c & d')) FROM ""Customers"" AS c LIMIT 1"); } @@ -259,7 +259,7 @@ public void TsQueryContains() } AssertSql( - @"SELECT to_tsquery('a & b') @> to_tsquery('b') + @"SELECT (to_tsquery('a & b') @> to_tsquery('b')) FROM ""Customers"" AS c LIMIT 1"); } @@ -276,7 +276,7 @@ public void TsQueryIsContainedIn() } AssertSql( - @"SELECT to_tsquery('b') <@ to_tsquery('a & b') + @"SELECT (to_tsquery('b') <@ to_tsquery('a & b')) FROM ""Customers"" AS c LIMIT 1"); } @@ -436,7 +436,7 @@ public void Matches_With_String() } AssertSql( - @"SELECT to_tsvector('a') @@ 'b' + @"SELECT (to_tsvector('a') @@ 'b') FROM ""Customers"" AS c LIMIT 1"); } @@ -453,7 +453,7 @@ public void Matches_With_Tsquery() } AssertSql( - @"SELECT to_tsvector('a') @@ to_tsquery('b') + @"SELECT (to_tsvector('a') @@ to_tsquery('b')) FROM ""Customers"" AS c LIMIT 1"); } @@ -470,7 +470,7 @@ public void TsVectorConcat() } AssertSql( - @"SELECT to_tsvector('b') || to_tsvector('c') + @"SELECT (to_tsvector('b') || to_tsvector('c')) FROM ""Customers"" AS c LIMIT 1"); } diff --git a/test/EFCore.PG.FunctionalTests/Query/RangeQueryNpgsqlTest.cs b/test/EFCore.PG.FunctionalTests/Query/RangeQueryNpgsqlTest.cs index c31d32016..7d08e0763 100644 --- a/test/EFCore.PG.FunctionalTests/Query/RangeQueryNpgsqlTest.cs +++ b/test/EFCore.PG.FunctionalTests/Query/RangeQueryNpgsqlTest.cs @@ -47,7 +47,7 @@ public void RangeContainsRange(NpgsqlRange range) .Where(x => x.Range.Contains(range)) .ToArray(); - AssertContainsSql("WHERE x.\"Range\" @> @__range_0 = TRUE"); + AssertContainsSql("WHERE (x.\"Range\" @> @__range_0) = TRUE"); } } @@ -65,7 +65,7 @@ public void RangeDoesNotContainRange(NpgsqlRange range) .Where(x => !x.Range.Contains(range)) .ToArray(); - AssertContainsSql("WHERE NOT (x.\"Range\" @> @__range_0 = TRUE)"); + AssertContainsSql("WHERE NOT ((x.\"Range\" @> @__range_0) = TRUE)"); } } @@ -83,7 +83,7 @@ public void RangeContainsValue(int value) .Where(x => x.Range.Contains(value)) .ToArray(); - AssertContainsSql("WHERE x.\"Range\" @> @__value_0"); + AssertContainsSql("WHERE (x.\"Range\" @> @__value_0)"); } } @@ -101,7 +101,7 @@ public void RangeDoesNotContainValue(int value) .Where(x => !x.Range.Contains(value)) .ToArray(); - AssertContainsSql("WHERE NOT (x.\"Range\" @> @__value_0 = TRUE)"); + AssertContainsSql("WHERE NOT ((x.\"Range\" @> @__value_0) = TRUE)"); } } @@ -119,7 +119,7 @@ public void RangeContainedByRange(NpgsqlRange range) .Where(x => range.ContainedBy(x.Range)) .ToArray(); - AssertContainsSql("WHERE @__range_0 <@ x.\"Range\" = TRUE"); + AssertContainsSql("WHERE (@__range_0 <@ x.\"Range\") = TRUE"); } } @@ -137,7 +137,7 @@ public void RangeNotContainedByRange(NpgsqlRange range) .Where(x => !range.ContainedBy(x.Range)) .ToArray(); - AssertContainsSql("WHERE NOT (@__range_0 <@ x.\"Range\" = TRUE)"); + AssertContainsSql("WHERE NOT ((@__range_0 <@ x.\"Range\") = TRUE)"); } } @@ -227,7 +227,7 @@ public void RangeOvelapsRange(NpgsqlRange range) .Where(x => x.Range.Overlaps(range)) .ToArray(); - AssertContainsSql("WHERE x.\"Range\" && @__range_0"); + AssertContainsSql("WHERE (x.\"Range\" && @__range_0)"); } } @@ -245,7 +245,7 @@ public void RangeDoesNotOvelapRange(NpgsqlRange range) .Where(x => !x.Range.Overlaps(range)) .ToArray(); - AssertContainsSql("WHERE NOT (x.\"Range\" && @__range_0 = TRUE)"); + AssertContainsSql("WHERE NOT ((x.\"Range\" && @__range_0) = TRUE)"); } } @@ -263,7 +263,7 @@ public void RangeIsStrictlyLeftOfRange(NpgsqlRange range) .Where(x => x.Range.IsStrictlyLeftOf(range)) .ToArray(); - AssertContainsSql("WHERE x.\"Range\" << @__range_0"); + AssertContainsSql("WHERE (x.\"Range\" << @__range_0)"); } } @@ -281,7 +281,7 @@ public void RangeIsNotStrictlyLeftOfRange(NpgsqlRange range) .Where(x => !x.Range.IsStrictlyLeftOf(range)) .ToArray(); - AssertContainsSql("WHERE NOT (x.\"Range\" << @__range_0 = TRUE)"); + AssertContainsSql("WHERE NOT ((x.\"Range\" << @__range_0) = TRUE)"); } } @@ -299,7 +299,7 @@ public void RangeIsStrictlyRightOfRange(NpgsqlRange range) .Where(x => x.Range.IsStrictlyRightOf(range)) .ToArray(); - AssertContainsSql("WHERE x.\"Range\" >> @__range_0"); + AssertContainsSql("WHERE (x.\"Range\" >> @__range_0)"); } } @@ -317,7 +317,7 @@ public void RangeIsNotStrictlyRightOfRange(NpgsqlRange range) .Where(x => !x.Range.IsStrictlyRightOf(range)) .ToArray(); - AssertContainsSql("WHERE NOT (x.\"Range\" >> @__range_0 = TRUE)"); + AssertContainsSql("WHERE NOT ((x.\"Range\" >> @__range_0) = TRUE)"); } } @@ -335,7 +335,7 @@ public void RangeDoesNotExtendLeftOfRange(NpgsqlRange range) .Where(x => x.Range.DoesNotExtendLeftOf(range)) .ToArray(); - AssertContainsSql("WHERE x.\"Range\" &> @__range_0"); + AssertContainsSql("WHERE (x.\"Range\" &> @__range_0)"); } } @@ -353,7 +353,7 @@ public void RangeDoesExtendLeftOfRange(NpgsqlRange range) .Where(x => !x.Range.DoesNotExtendLeftOf(range)) .ToArray(); - AssertContainsSql("WHERE NOT (x.\"Range\" &> @__range_0 = TRUE)"); + AssertContainsSql("WHERE NOT ((x.\"Range\" &> @__range_0) = TRUE)"); } } @@ -371,7 +371,7 @@ public void RangeDoesNotExtendRightOfRange(NpgsqlRange range) .Where(x => x.Range.DoesNotExtendRightOf(range)) .ToArray(); - AssertContainsSql("WHERE x.\"Range\" &< @__range_0"); + AssertContainsSql("WHERE (x.\"Range\" &< @__range_0)"); } } @@ -389,7 +389,7 @@ public void RangeDoesExtendRightOfRange(NpgsqlRange range) .Where(x => !x.Range.DoesNotExtendRightOf(range)) .ToArray(); - AssertContainsSql("WHERE NOT (x.\"Range\" &< @__range_0 = TRUE)"); + AssertContainsSql("WHERE NOT ((x.\"Range\" &< @__range_0) = TRUE)"); } } @@ -407,7 +407,7 @@ public void RangeIsAdjacentToRange(NpgsqlRange range) .Where(x => x.Range.IsAdjacentTo(range)) .ToArray(); - AssertContainsSql("WHERE x.\"Range\" -|- @__range_0"); + AssertContainsSql("WHERE (x.\"Range\" -|- @__range_0) = TRUE"); } } @@ -425,7 +425,7 @@ public void RangeIsNotAdjacentToRange(NpgsqlRange range) .Where(x => !x.Range.IsAdjacentTo(range)) .ToArray(); - AssertContainsSql("WHERE NOT (x.\"Range\" -|- @__range_0 = TRUE)"); + AssertContainsSql("WHERE NOT ((x.\"Range\" -|- @__range_0) = TRUE)"); } } @@ -443,7 +443,7 @@ public void RangeUnionRange(NpgsqlRange range) .Select(x => x.Range.Union(range)) .ToArray(); - AssertContainsSql("SELECT x.\"Range\" + @__range_0"); + AssertContainsSql("SELECT (x.\"Range\" + @__range_0)"); } } @@ -461,7 +461,7 @@ public void RangeIntersectsRange(NpgsqlRange range) .Select(x => x.Range.Intersect(range)) .ToArray(); - AssertContainsSql("SELECT x.\"Range\" * @__range_0"); + AssertContainsSql("SELECT (x.\"Range\" * @__range_0)"); } } @@ -486,7 +486,7 @@ public void RangeExceptRange(NpgsqlRange range) // ignore: Npgsql.PostgresException : 22000: result of range difference would not be contiguous. } - AssertContainsSql("SELECT x.\"Range\" - @__range_0"); + AssertContainsSql("SELECT (x.\"Range\" - @__range_0)"); } } diff --git a/test/EFCore.PG.FunctionalTests/Query/SimpleQueryNpgsqlTest.cs b/test/EFCore.PG.FunctionalTests/Query/SimpleQueryNpgsqlTest.cs index 368702d9c..333ea6777 100644 --- a/test/EFCore.PG.FunctionalTests/Query/SimpleQueryNpgsqlTest.cs +++ b/test/EFCore.PG.FunctionalTests/Query/SimpleQueryNpgsqlTest.cs @@ -1,5 +1,4 @@ -using System; -using System.Linq; +using System.Linq; using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.TestModels.Northwind; using Microsoft.EntityFrameworkCore.TestUtilities; @@ -20,7 +19,7 @@ public override void Select_expression_date_add_year() base.Select_expression_date_add_year(); AssertSql( - @"SELECT o.""OrderDate"" + MAKE_INTERVAL(years => 1) AS ""OrderDate"" + @"SELECT (o.""OrderDate"" + MAKE_INTERVAL(years => 1)) AS ""OrderDate"" FROM ""Orders"" AS o WHERE o.""OrderDate"" IS NOT NULL"); } @@ -42,7 +41,7 @@ public void Select_expression_date_add_year_param() AssertSql( @"@__years_0='2' -SELECT o.""OrderDate"" + MAKE_INTERVAL(years => @__years_0) AS ""OrderDate"" +SELECT (o.""OrderDate"" + MAKE_INTERVAL(years => @__years_0)) AS ""OrderDate"" FROM ""Orders"" AS o WHERE o.""OrderDate"" IS NOT NULL"); } @@ -62,7 +61,7 @@ public void Select_expression_datetime_add_month() e => e.OrderDate); AssertSql( - @"SELECT o.""OrderDate"" + MAKE_INTERVAL(months => 1) AS ""OrderDate"" + @"SELECT (o.""OrderDate"" + MAKE_INTERVAL(months => 1)) AS ""OrderDate"" FROM ""Orders"" AS o WHERE o.""OrderDate"" IS NOT NULL"); } @@ -80,7 +79,7 @@ public void Select_expression_datetime_add_hour() e => e.OrderDate); AssertSql( - @"SELECT o.""OrderDate"" + MAKE_INTERVAL(hours => 1) AS ""OrderDate"" + @"SELECT (o.""OrderDate"" + MAKE_INTERVAL(hours => 1)) AS ""OrderDate"" FROM ""Orders"" AS o WHERE o.""OrderDate"" IS NOT NULL"); } @@ -98,7 +97,7 @@ public void Select_expression_datetime_add_minute() e => e.OrderDate); AssertSql( - @"SELECT o.""OrderDate"" + MAKE_INTERVAL(mins => 1) AS ""OrderDate"" + @"SELECT (o.""OrderDate"" + MAKE_INTERVAL(mins => 1)) AS ""OrderDate"" FROM ""Orders"" AS o WHERE o.""OrderDate"" IS NOT NULL"); } @@ -116,7 +115,7 @@ public void Select_expression_datetime_add_second() e => e.OrderDate); AssertSql( - @"SELECT o.""OrderDate"" + MAKE_INTERVAL(secs => 1) AS ""OrderDate"" + @"SELECT (o.""OrderDate"" + MAKE_INTERVAL(secs => 1)) AS ""OrderDate"" FROM ""Orders"" AS o WHERE o.""OrderDate"" IS NOT NULL"); }