Skip to content

Translate 'case when X is null...' to 'coalesce(X,...)' #93

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed

Conversation

bgurmendi
Copy link
Contributor

@bgurmendi bgurmendi commented Apr 30, 2018

This changes solves most cases of #62 #60 #87 #90

Copy link

@Emill Emill left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice solution! Just a few comments...


if (is_null.Argument.Equals(expression.Else))
{
LiteralExpression coalesceExpression = new LiteralExpression(" COALESCE( ");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aren't we missing coalesceExpression.Append(expression.Else.Accept(this)); here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You also right! I have deleted this line on some cleanup.

@@ -1191,6 +1209,12 @@ VisitedExpression VisitFunction(EdmFunction function, IList<DbExpression> args,
throw new NotSupportedException("cast type name argument must be a constant expression.");

return new CastExpression(args[0].Accept(this), typeNameExpression.Value.ToString());
}else if (functionName == "coalesce")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How can this code be triggered? Isn't it enough with the code above?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right! I have made a mistake cleaning code, this fragment is for general case to coalesce translation in other pull request #94

@bgurmendi bgurmendi closed this Apr 30, 2018
@bgurmendi bgurmendi reopened this Apr 30, 2018
@bgurmendi bgurmendi force-pushed the fix_Error_sql_42P18_issue_62_and_60 branch 2 times, most recently from c2304c6 to e32babe Compare May 2, 2018 09:31
{
var is_null = expression.When[0] as DbIsNullExpression;
if (is_null.Argument.Equals(expression.Else))
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nitpick: code naming conventions, is_null should be isNull. To be more consistent with code below, it should be isNullExpression.

@rwasef1830
Copy link
Contributor

@bgurmendi Also, add a unit test that tests the change this code makes by asserting the SQL generated, and a unit test that tests that the string scenarios in the unit tests linked are solved (I see there are some unit tests in the other pull request, maybe you can adapt them and make them part for this one). If the solution can be with only 19 lines of code, it is preferable to keep it to this pull only and close the other one.

Thanks a lot for your valuable contribution!

@bgurmendi bgurmendi force-pushed the fix_Error_sql_42P18_issue_62_and_60 branch from e32babe to 9522c2e Compare May 3, 2018 15:10
@bgurmendi
Copy link
Contributor Author

Thanks for the quick review.

Changes made:

  • Unit test were added.
  • Changed variable names

Copy link
Contributor

@rwasef1830 rwasef1830 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy you found a solution for those obscure type unknown issues, I'm ready to merge this as soon as code formatting and naming issues are fixed. Thanks a lot!

{
context.Database.Log = Console.Out.WriteLine;

context.Blogs.Add( new Blog { Name = "Hello" });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: Extra space before new keyword.

var blogTitle = query.First();
Assert.That(blogTitle, Is.EqualTo("string_value_postfix"));
Console.WriteLine(query.ToString());
StringAssert.AreEqualIgnoringCase("SELECT COALESCE( @p__linq__0,E'') || E'_postfix' AS \"C1\" FROM \"dbo\".\"Blogs\" AS \"Extent1\"", query.ToString());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Readability: This line is too long and is hard to read for other developers, break it at sensible points into 2 or more strings concatenated with "+" so that the length of each line is as near in length to surrounding code. Also there is extra spaces around COALESCE statement. You don't have to add these spaces in the expression. The parsing system automatically handles that.

var isNullExpression = expression.When[0] as DbIsNullExpression;
if (isNullExpression.Argument.Equals(expression.Else))
{
LiteralExpression coalesceExpression = new LiteralExpression(" COALESCE( ");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for extra space before and after the coalesce statement.

Assert.That(blog_title, Is.EqualTo("string_value_postfix"));

Console.WriteLine(query.ToString());
StringAssert.AreEqualIgnoringCase("SELECT CASE WHEN ( COALESCE( @p__linq__0,E'default_value') IS NULL) THEN (E'') WHEN (@p__linq__0 IS NULL) THEN (E'default_value') ELSE (@p__linq__0) END || E'_postfix' AS \"C1\" FROM \"dbo\".\"Blogs\" AS \"Extent1\"", query.ToString());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Readability: This line is too long and is hard to read for other developers, break it at sensible points into 2 or more strings concatenated with "+" so that the length of each line is as near in length to surrounding code.

Assert.That(blog_title, Is.EqualTo("string_value1_postfix"));

Console.WriteLine(query.ToString());
StringAssert.AreEqualIgnoringCase("SELECT CASE WHEN ( COALESCE( @p__linq__0, COALESCE( @p__linq__1,@p__linq__2) ) IS NULL) THEN (E'') WHEN (@p__linq__0 IS NULL) THEN ( COALESCE( @p__linq__1,@p__linq__2) ) ELSE (@p__linq__0) END || E'_postfix' AS \"C1\" FROM \"dbo\".\"Blogs\" AS \"Extent1\"", query.ToString());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Readability: This line is too long and is hard to read for other developers, break it at sensible points into 2 or more strings concatenated with "+" so that the length of each line is as near in length to surrounding code.

@@ -772,5 +772,67 @@ public void TestTableValuedStoredFunctions()
Assert.AreEqual(1, list2[0].Something);
}
}

[Test]
public void Test_issue_60_and_62()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test needs a better name, maybe: Test_string_type_inference_in_coalesce_statements

}

[Test]
public void TestNullPropagation_1()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test needs a better name, maybe: Test_string_null_propagation

}

[Test]
public void TestNullPropagation_2()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test needs a better name, maybe: Test_string_multiple_null_propagation

@rwasef1830
Copy link
Contributor

@bgurmendi Are you still interested on this ? If you are busy, I don't mind making the needed changes and merging this.

@bgurmendi
Copy link
Contributor Author

bgurmendi commented Jun 1, 2018 via email

@rwasef1830
Copy link
Contributor

Merged via 11f1cbd

@rwasef1830 rwasef1830 closed this Jun 1, 2018
@bgurmendi
Copy link
Contributor Author

@rwasef1830 thanks!!! Any estimation for release of this changes on Nuget?

Anyway thanks for the great work on EntityFramework6.Npgsql

@rwasef1830
Copy link
Contributor

@bgurmendi I don't have a way to make releases on NuGet. I am just implementing a few missing full text search functions and then I will ask @roji to make a release.

@roji
Copy link
Member

roji commented Jun 1, 2018

@rwasef1830 let me know when you're ready and we'll release a version.

I propose we also update the dependency for Npgsql 4.0 and bump the EF6 provider version 4.0 as well...

@rwasef1830
Copy link
Contributor

rwasef1830 commented Jun 1, 2018

@roji I committed and pushed the missing tsquery_phrase function.

I suggest making a release as-is to fix annoying "unknown type" errors for people using Npgsql 3.x and then update dependencies and make another release referencing Npgsql 4.0

I tried to update the Npgsql dependency to 4.0 but there are compile errors related to Postgis types.

@roji
Copy link
Member

roji commented Jun 1, 2018

I suggest making a release as-is to fix annoying "unknown type" errors for people using Npgsql 3.x and then update dependencies and make another release referencing Npgsql 4.0

Makes sense, I'll do that this weekend.

I tried to update the Npgsql dependency to 4.0 but there are compile errors related to Postgis types.

Ah of course, we moves the Postgis types out to the Npgsql.LegacyPostgis plugin. I think the EF6 provider will have to simply reference it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants