Skip to content

Commit 11f1cbd

Browse files
bgurmendirwasef1830
authored andcommitted
Translate 'case when X is null...' to 'coalesce(X,...)'.
1 parent c1cf255 commit 11f1cbd

2 files changed

Lines changed: 92 additions & 0 deletions

File tree

src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,23 @@ protected string GetDbType(EdmType edmType)
829829

830830
public override VisitedExpression Visit([NotNull] DbCaseExpression expression)
831831
{
832+
// Check for COALESCE like CASE
833+
if (expression.When.Count == 1 &&
834+
expression.When[0].ExpressionKind == DbExpressionKind.IsNull)
835+
{
836+
var isNullExpression = (DbIsNullExpression)expression.When[0];
837+
if (isNullExpression.Argument.Equals(expression.Else))
838+
{
839+
var coalesceExpression = new LiteralExpression("COALESCE(");
840+
coalesceExpression.Append(expression.Else.Accept(this));
841+
coalesceExpression.Append(",");
842+
coalesceExpression.Append(expression.Then[0].Accept(this));
843+
coalesceExpression.Append(")");
844+
return coalesceExpression;
845+
}
846+
}
847+
848+
// General CASE
832849
var caseExpression = new LiteralExpression(" CASE ");
833850
for (var i = 0; i < expression.When.Count && i < expression.Then.Count; ++i)
834851
{

test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
using System.Data.Entity.Core.Metadata.Edm;
3434
using System.Data.Entity.Core.Objects;
3535
using System.Data.Entity.Infrastructure;
36+
using System.Diagnostics.CodeAnalysis;
3637
using NpgsqlTypes;
3738

3839
namespace EntityFramework6.Npgsql.Tests
@@ -772,5 +773,79 @@ public void TestTableValuedStoredFunctions()
772773
Assert.AreEqual(1, list2[0].Something);
773774
}
774775
}
776+
777+
[Test]
778+
public void Test_string_type_inference_in_coalesce_statements()
779+
{
780+
using (var context = new BloggingContext(ConnectionString))
781+
{
782+
context.Database.Log = Console.Out.WriteLine;
783+
784+
context.Blogs.Add(new Blog { Name = "Hello" });
785+
context.SaveChanges();
786+
787+
string stringValue = "string_value";
788+
var query = context.Blogs.Select(b => stringValue + "_postfix");
789+
var blogTitle = query.First();
790+
Assert.That(blogTitle, Is.EqualTo("string_value_postfix"));
791+
Console.WriteLine(query.ToString());
792+
StringAssert.AreEqualIgnoringCase(
793+
"SELECT COALESCE(@p__linq__0,E'') || E'_postfix' AS \"C1\" FROM \"dbo\".\"Blogs\" AS \"Extent1\"",
794+
query.ToString());
795+
}
796+
}
797+
798+
[Test]
799+
[SuppressMessage("ReSharper", "ConstantNullCoalescingCondition")]
800+
public void Test_string_null_propagation()
801+
{
802+
using (var context = new BloggingContext(ConnectionString))
803+
{
804+
context.Database.Log = Console.Out.WriteLine;
805+
806+
context.Blogs.Add(new Blog { Name = "Hello" });
807+
context.SaveChanges();
808+
809+
string stringValue = "string_value";
810+
var query = context.Blogs.Select(b => (stringValue ?? "default_value") + "_postfix");
811+
var blog_title = query.First();
812+
Assert.That(blog_title, Is.EqualTo("string_value_postfix"));
813+
814+
Console.WriteLine(query.ToString());
815+
StringAssert.AreEqualIgnoringCase(
816+
"SELECT CASE WHEN (COALESCE(@p__linq__0,E'default_value') IS NULL) THEN (E'')"
817+
+ " WHEN (@p__linq__0 IS NULL) THEN (E'default_value') ELSE (@p__linq__0) END ||"
818+
+ " E'_postfix' AS \"C1\" FROM \"dbo\".\"Blogs\" AS \"Extent1\"",
819+
query.ToString());
820+
}
821+
}
822+
823+
[Test]
824+
[SuppressMessage("ReSharper", "ConstantNullCoalescingCondition")]
825+
public void Test_string_multiple_null_propagation()
826+
{
827+
using (var context = new BloggingContext(ConnectionString))
828+
{
829+
context.Database.Log = Console.Out.WriteLine;
830+
831+
context.Blogs.Add(new Blog { Name = "Hello" });
832+
context.SaveChanges();
833+
834+
string stringValue1 = "string_value1";
835+
string stringValue2 = "string_value2";
836+
string stringValue3 = "string_value3";
837+
838+
var query = context.Blogs.Select(b => (stringValue1 ?? stringValue2 ?? stringValue3) + "_postfix");
839+
var blog_title = query.First();
840+
Assert.That(blog_title, Is.EqualTo("string_value1_postfix"));
841+
842+
Console.WriteLine(query.ToString());
843+
StringAssert.AreEqualIgnoringCase(
844+
"SELECT CASE WHEN (COALESCE(@p__linq__0,COALESCE(@p__linq__1,@p__linq__2)) IS NULL)"
845+
+ " THEN (E'') WHEN (@p__linq__0 IS NULL) THEN (COALESCE(@p__linq__1,@p__linq__2)) ELSE"
846+
+ " (@p__linq__0) END || E'_postfix' AS \"C1\" FROM \"dbo\".\"Blogs\" AS \"Extent1\"",
847+
query.ToString());
848+
}
849+
}
775850
}
776851
}

0 commit comments

Comments
 (0)