Skip to content
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

Refactored range type handler #2060

Merged
merged 1 commit into from
Jul 21, 2018
Merged

Refactored range type handler #2060

merged 1 commit into from
Jul 21, 2018

Conversation

YohDeadfall
Copy link
Contributor

This is my idea how the range handler should be refactored to fix #2040. The only one error I encountered is shown below. Will investigate this tomorrow.

\.nuget\packages\microsoft.dotnet.ilcompiler\1.0.0-alpha-26714-01\build\Microsoft.NETCore.Native.Windows.props(95,43): error MSB4184: The expression ""System.String[]".GetValue(1)" cannot be evaluated. Index was outside the bounds of the array.

@roji
Copy link
Member

roji commented Jul 15, 2018

I may be missing something, but I don't see how this PR solves the CoreRT issue (theoretical endless nested RangeHandler<RangeHandler<.....>>)... You still have CreateRangeHandler() defined on NpgsqlTypeHandler (non-generic), with RangeHandler extending NpgsqlTypeHandler and overriding that method to throw NotSupportedException. That means that any static analyzer that inspects the hierarchy still sees the theoretical possibility of calling CreateRangeHandler(), then calling CreateRangeHandler() on the returned value, and so ad infinitum... The same problem exists with CreateArrayHandler().

Some of the other changes you've done (unrelated cleanup/refactoring) could be fine though, but it's better to separate them out into another smaller PR.

@YohDeadfall
Copy link
Contributor Author

In short, you are missing that the RangeHandler<TElement> class is not NpgsqlTypeHandler<NpgsqlRange<TElement>> anymore. It inherits directly from non-generic NpgsqlTypeHandler (:

As you described #2042, the issue was caused by an instance of the NpgsqlTypeHandler<TDefault> class which could construct a NpgsqlTypeHandler<NpgsqlRange<TDefault>> which could construct a NpgsqlTypeHandler<NpgsqlRange<NpgsqlRange<TDefault>>> and so on. But now NpgsqlTypeHandler<TDefault>.CreateRangeHandler produces a RangeHandler<TDefault> which has it's own overriden implementation of the method and no base. So there is no reference from the range handler back to NpgsqlTypeHandler<TDefault>.

IEquatable<T> lower = (IEquatable<T>)lowerBound;
IEquatable<T> upper = (IEquatable<T>)upperBound;
var lower = (IEquatable<T>)lowerBound;
var upper = (IEquatable<T>)upperBound;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Move it to an additional PR?

Copy link
Member

Choose a reason for hiding this comment

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

I think it's small enough to leave in...

@roji
Copy link
Member

roji commented Jul 18, 2018

OK, I now understand the idea. I'm just not sure I completely understand precisely what CoreRT is doing and precisely what makes it fail on the current code.

Can I ask you to simply test CoreRT on your PR? If the error goes away I agree that it is a much better way to solve it than my PR...

@YohDeadfall
Copy link
Contributor Author

The code below compiles without any error.

static void Main(string[] args)
{
    using (var conn = new NpgsqlConnection("Server = localhost; User ID = npgsql_tests; Password = npgsql_tests; Database = npgsql_tests; Timeout = 0; Command Timeout = 0"))
    using (var cmd = new NpgsqlCommand("SELECT int4range(10, 20)", conn))
    {
        conn.Open();

        using (var rdr = cmd.ExecuteReader())
            if (rdr.Read()) Console.WriteLine(rdr.GetFieldValue<NpgsqlRange<int>>(0));
    }
}
PS D:\Source\Repos\npgsql\test\Npgsql.CoreRT> dotnet publish -r win-x64 -c release
Microsoft (R) Build Engine version 15.7.179.6572 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

  Restoring packages for D:\Source\Repos\npgsql\src\Npgsql\Npgsql.csproj...
  Restoring packages for D:\Source\Repos\npgsql\test\Npgsql.CoreRT\Npgsql.CoreRT.csproj...
  Restore completed in 219.55 ms for D:\Source\Repos\npgsql\src\Npgsql\Npgsql.csproj.
  Installing runtime.win-x64.Microsoft.DotNet.ILCompiler 1.0.0-alpha-26718-02.
  Generating MSBuild file D:\Source\Repos\npgsql\test\Npgsql.CoreRT\obj\Npgsql.CoreRT.csproj.nuget.g.targets.
  Restore completed in 42.22 sec for D:\Source\Repos\npgsql\test\Npgsql.CoreRT\Npgsql.CoreRT.csproj.
  Npgsql -> D:\Source\Repos\npgsql\src\Npgsql\bin\release\netstandard2.0\Npgsql.dll
  Npgsql.CoreRT -> D:\Source\Repos\npgsql\test\Npgsql.CoreRT\bin\release\netcoreapp2.0\win-x64\Npgsql.CoreRT.dll
  Generating native code
  Npgsql.CoreRT -> D:\Source\Repos\npgsql\test\Npgsql.CoreRT\bin\release\netcoreapp2.0\win-x64\publish\

@roji
Copy link
Member

roji commented Jul 19, 2018

OK, and just to be 100% sure you're also seeing an infinite type recursion issue when trying to build without your changes?

(FYI I actually tried to test with corert myself but there was a build failure trying to publish for linux-x64).

@roji roji force-pushed the dev branch 2 times, most recently from fe46200 to 1f156c8 Compare July 20, 2018 12:57
@YohDeadfall
Copy link
Contributor Author

Yes, I see it without that fix.

Copy link
Member

@roji roji left a comment

Choose a reason for hiding this comment

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

OK great, good to merge them!

It also means there are no other issues with corert, which is good news...

Do you think we should release this for 4.0.3? It seems like a pretty low-risk refactor...

@YohDeadfall YohDeadfall merged commit df65e0a into npgsql:dev Jul 21, 2018
@YohDeadfall YohDeadfall deleted the CoreRTCompilationFix branch July 21, 2018 06:40
@YohDeadfall
Copy link
Contributor Author

For now it compiles using the AOT compiler, but it doesn't work because of heavily used reflection in Npgsql. At least we should provide a basic rd.xml file or notify about it in the documentation. I will work on it, but it's not a blocking issue to release the fix in 4.0.3, I think.

@roji
Copy link
Member

roji commented Jul 21, 2018

@YohDeadfall thanks for your work on this. Maybe open an issue to track adding rd.xml?

@YohDeadfall
Copy link
Contributor Author

Opened #2073.

@YohDeadfall
Copy link
Contributor Author

Backported to 4.0.4 via 6487cc6.

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.

NpgsqlRange type recursion crashes corert compilation
2 participants