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

Expressions compiler extension #1277

Merged
merged 13 commits into from
Feb 4, 2021
Merged

Expressions compiler extension #1277

merged 13 commits into from
Feb 4, 2021

Conversation

MaceWindu
Copy link
Contributor

@MaceWindu MaceWindu commented Aug 12, 2018

Experemental stream to see if it makes sense to add extension point to replace expression compiler with something else. E.g. https://github.com/dadhi/FastExpressionCompiler

Doesn't make much sense right now as FastExpressionCompiler pretty unusable right now:

  • it miss strong name (not a big issue)
  • it is not yet production ready - I've tried to run our tests and after 4 failed tests it just hung on one of tests (went into infinite loop?)

I plan to report those issues and we can get back to this PR when they are fixed

@MaceWindu MaceWindu added this to the Future milestone Aug 12, 2018
@jogibear9988
Copy link
Member

Maybe we should add: ifFastFailedReturnNull = true to the compile fast. So we also get the expressions wich fail (otherwise fallback to compile is used (if I read correctly))

@MaceWindu
Copy link
Contributor Author

No, this flag controls behavior when unsupported expression node found in expression. In our case it just generate incorrect code.

@jogibear9988
Copy link
Member

What I don't like on this patches, is that we introduce more static settings...

@MaceWindu
Copy link
Contributor Author

It is just a test branch, which will be discarded. We can think how to do it if we decide to support compiler customization.

@jogibear9988
Copy link
Member

only wanted to say that! I think we still should think about how we could remove most of the static settings...
bit thats not part of this issue

@jogibear9988
Copy link
Member

@MaceWindu I've fixed all linq2db exception in FastExpressionCompiler. So you can check again.

@MaceWindu
Copy link
Contributor Author

@jogibear9988, Right now I'm busy preparing 2.3.0 release so maybe you can do it? Just run tests for databases you have.

@igor-tkachev
Copy link
Member

@jogibear9988 what is wrong with static settings?

@jogibear9988
Copy link
Member

For example you use linq2db in different projects with different settings. And these two projects are then used in another project.

Or you need different settings in some places at the code, and some need other.

}

internal static TDelegate CompileExpression<TDelegate>(this Expression<TDelegate> expression)
where TDelegate : Delegate
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this constraint needs C# 7.3, now it fails travis build

Copy link
Member

Choose a reason for hiding this comment

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

you introduced this. :-) see 201e094

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, just making notes. Looks like Travis environment will need some updates

@jogibear9988
Copy link
Member

@MaceWindu if done a few more changes. But atm, I could not run the linq2db tests, need to look why. But why don‘t the tests run on Appveyor?

@jogibear9988
Copy link
Member

Maybe you could test again with newest FastExpression Parser?

@MaceWindu
Copy link
Contributor Author

@jogibear9988

  • testcase I submited recently is fixed, but second similar test still fail (TypeAccessorTests.Test6 fails, TypeAccessorTests.Test5 is fixed). I would suspect it is due to use of structs, as if I remember, they use different il instructions for field access than reference types
  • cannot test sqlite, as now it again crashes test agent. Crashing test is EnumMappingTests.EnumMapInsertFromSelectWithParam3

@MaceWindu
Copy link
Contributor Author

And year, for sqlite one test fails before crash: CheckNullTest.ClientCoalesce2 with

System.InvalidProgramException : Common Language Runtime detected an invalid program.

@MaceWindu
Copy link
Contributor Author

About running tests - I think you can add FEC source file as link to test project to avoid Appveyor errors, because now to test it I buid it and sign using linq2db key.

@jogibear9988
Copy link
Member

Try again with newest FEC. Looks like many more tests work now.

@MaceWindu
Copy link
Contributor Author

MaceWindu commented Sep 7, 2018

Edit: sory, tested wrong version. Will retest

ok, retested with latest version:
Test6 still fails, and 10 more tests started to fail with InvalidProgramException

And SQLite testrun still hangs on EnumMapInsertFromSelectWithParam3

@jogibear9988
Copy link
Member

Now it Looks better

@jogibear9988
Copy link
Member

But the EnumMapInsertFromSelectWithParam3 still fails.

Exception is "Access Violation Exception", seams invalid IL is generated. But for this to find out, I have to find where the Expression for the IL is generated!

The IL looks like this: (it's very big ;-)

IL_0000: ldarg.0    
IL_0001: castclass  System.Linq.Expressions.MethodCallExpression
IL_0006: call       System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.Expression] get_Arguments()/System.Linq.Expressions.MethodCallExpression
IL_000b: ldc.i4.0   
IL_000c: callvirt   System.Linq.Expressions.Expression get_Item(Int32)/System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.Expression]
IL_0011: castclass  System.Linq.Expressions.MethodCallExpression
IL_0016: call       System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.Expression] get_Arguments()/System.Linq.Expressions.MethodCallExpression
IL_001b: ldc.i4.1   
IL_001c: callvirt   System.Linq.Expressions.Expression get_Item(Int32)/System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.Expression]
IL_0021: castclass  System.Linq.Expressions.UnaryExpression
IL_0026: call       System.Linq.Expressions.Expression get_Operand()/System.Linq.Expressions.UnaryExpression
IL_002b: castclass  System.Linq.Expressions.LambdaExpression
IL_0030: call       System.Linq.Expressions.Expression get_Body()/System.Linq.Expressions.LambdaExpression
IL_0035: castclass  System.Linq.Expressions.MemberInitExpression
IL_003a: call       System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.MemberBinding] get_Bindings()/System.Linq.Expressions.MemberInitExpression
IL_003f: ldc.i4.1   
IL_0040: callvirt   System.Linq.Expressions.MemberBinding get_Item(Int32)/System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.MemberBinding]
IL_0045: castclass  System.Linq.Expressions.MemberAssignment
IL_004a: call       System.Linq.Expressions.Expression get_Expression()/System.Linq.Expressions.MemberAssignment
IL_004f: castclass  System.Linq.Expressions.UnaryExpression
IL_0054: call       System.Linq.Expressions.Expression get_Operand()/System.Linq.Expressions.UnaryExpression
IL_0059: castclass  System.Linq.Expressions.MemberExpression
IL_005e: call       System.Linq.Expressions.Expression get_Expression()/System.Linq.Expressions.MemberExpression
IL_0063: castclass  System.Linq.Expressions.ConstantExpression
IL_0068: call       System.Object get_Value()/System.Linq.Expressions.ConstantExpression
IL_006d: castclass  Tests.Linq.EnumMappingTests+<>c__DisplayClass55_0
IL_0072: ldfld      TestEnum1 param/Tests.Linq.EnumMappingTests+<>c__DisplayClass55_0
IL_0077: call       System.Nullable`1[Tests.Linq.EnumMappingTests+TestEnum1] op_Implicit(TestEnum1)/System.Nullable`1[Tests.Linq.EnumMappingTests+TestEnum1]
IL_007c: stloc.0    
IL_007d: ldloca.s   V_0
IL_007f: call       Boolean get_HasValue()/System.Nullable`1[Tests.Linq.EnumMappingTests+TestEnum1]
IL_0084: brfalse    IL_040d
IL_0089: ldarg.0    
IL_008a: castclass  System.Linq.Expressions.MethodCallExpression
IL_008f: call       System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.Expression] get_Arguments()/System.Linq.Expressions.MethodCallExpression
IL_0094: ldc.i4.0   
IL_0095: callvirt   System.Linq.Expressions.Expression get_Item(Int32)/System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.Expression]
IL_009a: castclass  System.Linq.Expressions.MethodCallExpression
IL_009f: call       System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.Expression] get_Arguments()/System.Linq.Expressions.MethodCallExpression
IL_00a4: ldc.i4.1   
IL_00a5: callvirt   System.Linq.Expressions.Expression get_Item(Int32)/System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.Expression]
IL_00aa: castclass  System.Linq.Expressions.UnaryExpression
IL_00af: call       System.Linq.Expressions.Expression get_Operand()/System.Linq.Expressions.UnaryExpression
IL_00b4: castclass  System.Linq.Expressions.LambdaExpression
IL_00b9: call       System.Linq.Expressions.Expression get_Body()/System.Linq.Expressions.LambdaExpression
IL_00be: castclass  System.Linq.Expressions.MemberInitExpression
IL_00c3: call       System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.MemberBinding] get_Bindings()/System.Linq.Expressions.MemberInitExpression
IL_00c8: ldc.i4.1   
IL_00c9: callvirt   System.Linq.Expressions.MemberBinding get_Item(Int32)/System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.MemberBinding]
IL_00ce: castclass  System.Linq.Expressions.MemberAssignment
IL_00d3: call       System.Linq.Expressions.Expression get_Expression()/System.Linq.Expressions.MemberAssignment
IL_00d8: castclass  System.Linq.Expressions.UnaryExpression
IL_00dd: call       System.Linq.Expressions.Expression get_Operand()/System.Linq.Expressions.UnaryExpression
IL_00e2: castclass  System.Linq.Expressions.MemberExpression
IL_00e7: call       System.Linq.Expressions.Expression get_Expression()/System.Linq.Expressions.MemberExpression
IL_00ec: castclass  System.Linq.Expressions.ConstantExpression
IL_00f1: call       System.Object get_Value()/System.Linq.Expressions.ConstantExpression
IL_00f6: castclass  Tests.Linq.EnumMappingTests+<>c__DisplayClass55_0
IL_00fb: ldfld      TestEnum1 param/Tests.Linq.EnumMappingTests+<>c__DisplayClass55_0
IL_0100: call       System.Nullable`1[Tests.Linq.EnumMappingTests+TestEnum1] op_Implicit(TestEnum1)/System.Nullable`1[Tests.Linq.EnumMappingTests+TestEnum1]
IL_0105: brtrue     IL_0118
IL_010a: ldloca.s   V_1
IL_010c: initobj    Tests.Linq.EnumMappingTests+TestEnum1
IL_0112: ldloc.1    
IL_0113: br         IL_0199
IL_0118: ldarg.0    
IL_0119: castclass  System.Linq.Expressions.MethodCallExpression
IL_011e: call       System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.Expression] get_Arguments()/System.Linq.Expressions.MethodCallExpression
IL_0123: ldc.i4.0   
IL_0124: callvirt   System.Linq.Expressions.Expression get_Item(Int32)/System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.Expression]
IL_0129: castclass  System.Linq.Expressions.MethodCallExpression
IL_012e: call       System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.Expression] get_Arguments()/System.Linq.Expressions.MethodCallExpression
IL_0133: ldc.i4.1   
IL_0134: callvirt   System.Linq.Expressions.Expression get_Item(Int32)/System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.Expression]
IL_0139: castclass  System.Linq.Expressions.UnaryExpression
IL_013e: call       System.Linq.Expressions.Expression get_Operand()/System.Linq.Expressions.UnaryExpression
IL_0143: castclass  System.Linq.Expressions.LambdaExpression
IL_0148: call       System.Linq.Expressions.Expression get_Body()/System.Linq.Expressions.LambdaExpression
IL_014d: castclass  System.Linq.Expressions.MemberInitExpression
IL_0152: call       System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.MemberBinding] get_Bindings()/System.Linq.Expressions.MemberInitExpression
IL_0157: ldc.i4.1   
IL_0158: callvirt   System.Linq.Expressions.MemberBinding get_Item(Int32)/System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.MemberBinding]
IL_015d: castclass  System.Linq.Expressions.MemberAssignment
IL_0162: call       System.Linq.Expressions.Expression get_Expression()/System.Linq.Expressions.MemberAssignment
IL_0167: castclass  System.Linq.Expressions.UnaryExpression
IL_016c: call       System.Linq.Expressions.Expression get_Operand()/System.Linq.Expressions.UnaryExpression
IL_0171: castclass  System.Linq.Expressions.MemberExpression
IL_0176: call       System.Linq.Expressions.Expression get_Expression()/System.Linq.Expressions.MemberExpression
IL_017b: castclass  System.Linq.Expressions.ConstantExpression
IL_0180: call       System.Object get_Value()/System.Linq.Expressions.ConstantExpression
IL_0185: castclass  Tests.Linq.EnumMappingTests+<>c__DisplayClass55_0
IL_018a: ldfld      TestEnum1 param/Tests.Linq.EnumMappingTests+<>c__DisplayClass55_0
IL_018f: call       System.Nullable`1[Tests.Linq.EnumMappingTests+TestEnum1] op_Implicit(TestEnum1)/System.Nullable`1[Tests.Linq.EnumMappingTests+TestEnum1]
IL_0194: call       TestEnum1 op_Explicit(System.Nullable`1[Tests.Linq.EnumMappingTests+TestEnum1])/System.Nullable`1[Tests.Linq.EnumMappingTests+TestEnum1]
IL_0199: ldc.i4.3   
IL_019a: ceq        
IL_019c: brtrue     IL_03e7
IL_01a1: ldarg.0    
IL_01a2: castclass  System.Linq.Expressions.MethodCallExpression
IL_01a7: call       System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.Expression] get_Arguments()/System.Linq.Expressions.MethodCallExpression
IL_01ac: ldc.i4.0   
IL_01ad: callvirt   System.Linq.Expressions.Expression get_Item(Int32)/System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.Expression]
IL_01b2: castclass  System.Linq.Expressions.MethodCallExpression
IL_01b7: call       System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.Expression] get_Arguments()/System.Linq.Expressions.MethodCallExpression
IL_01bc: ldc.i4.1   
IL_01bd: callvirt   System.Linq.Expressions.Expression get_Item(Int32)/System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.Expression]
IL_01c2: castclass  System.Linq.Expressions.UnaryExpression
IL_01c7: call       System.Linq.Expressions.Expression get_Operand()/System.Linq.Expressions.UnaryExpression
IL_01cc: castclass  System.Linq.Expressions.LambdaExpression
IL_01d1: call       System.Linq.Expressions.Expression get_Body()/System.Linq.Expressions.LambdaExpression
IL_01d6: castclass  System.Linq.Expressions.MemberInitExpression
IL_01db: call       System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.MemberBinding] get_Bindings()/System.Linq.Expressions.MemberInitExpression
IL_01e0: ldc.i4.1   
IL_01e1: callvirt   System.Linq.Expressions.MemberBinding get_Item(Int32)/System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.MemberBinding]
IL_01e6: castclass  System.Linq.Expressions.MemberAssignment
IL_01eb: call       System.Linq.Expressions.Expression get_Expression()/System.Linq.Expressions.MemberAssignment
IL_01f0: castclass  System.Linq.Expressions.UnaryExpression
IL_01f5: call       System.Linq.Expressions.Expression get_Operand()/System.Linq.Expressions.UnaryExpression
IL_01fa: castclass  System.Linq.Expressions.MemberExpression
IL_01ff: call       System.Linq.Expressions.Expression get_Expression()/System.Linq.Expressions.MemberExpression
IL_0204: castclass  System.Linq.Expressions.ConstantExpression
IL_0209: call       System.Object get_Value()/System.Linq.Expressions.ConstantExpression
IL_020e: castclass  Tests.Linq.EnumMappingTests+<>c__DisplayClass55_0
IL_0213: ldfld      TestEnum1 param/Tests.Linq.EnumMappingTests+<>c__DisplayClass55_0
IL_0218: call       System.Nullable`1[Tests.Linq.EnumMappingTests+TestEnum1] op_Implicit(TestEnum1)/System.Nullable`1[Tests.Linq.EnumMappingTests+TestEnum1]
IL_021d: brtrue     IL_0230
IL_0222: ldloca.s   V_2
IL_0224: initobj    Tests.Linq.EnumMappingTests+TestEnum1
IL_022a: ldloc.2    
IL_022b: br         IL_02b1
IL_0230: ldarg.0    
IL_0231: castclass  System.Linq.Expressions.MethodCallExpression
IL_0236: call       System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.Expression] get_Arguments()/System.Linq.Expressions.MethodCallExpression
IL_023b: ldc.i4.0   
IL_023c: callvirt   System.Linq.Expressions.Expression get_Item(Int32)/System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.Expression]
IL_0241: castclass  System.Linq.Expressions.MethodCallExpression
IL_0246: call       System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.Expression] get_Arguments()/System.Linq.Expressions.MethodCallExpression
IL_024b: ldc.i4.1   
IL_024c: callvirt   System.Linq.Expressions.Expression get_Item(Int32)/System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.Expression]
IL_0251: castclass  System.Linq.Expressions.UnaryExpression
IL_0256: call       System.Linq.Expressions.Expression get_Operand()/System.Linq.Expressions.UnaryExpression
IL_025b: castclass  System.Linq.Expressions.LambdaExpression
IL_0260: call       System.Linq.Expressions.Expression get_Body()/System.Linq.Expressions.LambdaExpression
IL_0265: castclass  System.Linq.Expressions.MemberInitExpression
IL_026a: call       System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.MemberBinding] get_Bindings()/System.Linq.Expressions.MemberInitExpression
IL_026f: ldc.i4.1   
IL_0270: callvirt   System.Linq.Expressions.MemberBinding get_Item(Int32)/System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.MemberBinding]
IL_0275: castclass  System.Linq.Expressions.MemberAssignment
IL_027a: call       System.Linq.Expressions.Expression get_Expression()/System.Linq.Expressions.MemberAssignment
IL_027f: castclass  System.Linq.Expressions.UnaryExpression
IL_0284: call       System.Linq.Expressions.Expression get_Operand()/System.Linq.Expressions.UnaryExpression
IL_0289: castclass  System.Linq.Expressions.MemberExpression
IL_028e: call       System.Linq.Expressions.Expression get_Expression()/System.Linq.Expressions.MemberExpression
IL_0293: castclass  System.Linq.Expressions.ConstantExpression
IL_0298: call       System.Object get_Value()/System.Linq.Expressions.ConstantExpression
IL_029d: castclass  Tests.Linq.EnumMappingTests+<>c__DisplayClass55_0
IL_02a2: ldfld      TestEnum1 param/Tests.Linq.EnumMappingTests+<>c__DisplayClass55_0
IL_02a7: call       System.Nullable`1[Tests.Linq.EnumMappingTests+TestEnum1] op_Implicit(TestEnum1)/System.Nullable`1[Tests.Linq.EnumMappingTests+TestEnum1]
IL_02ac: call       TestEnum1 op_Explicit(System.Nullable`1[Tests.Linq.EnumMappingTests+TestEnum1])/System.Nullable`1[Tests.Linq.EnumMappingTests+TestEnum1]
IL_02b1: ldc.i4.4   
IL_02b2: ceq        
IL_02b4: brtrue     IL_03fa
IL_02b9: ldarg.0    
IL_02ba: castclass  System.Linq.Expressions.MethodCallExpression
IL_02bf: call       System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.Expression] get_Arguments()/System.Linq.Expressions.MethodCallExpression
IL_02c4: ldc.i4.0   
IL_02c5: callvirt   System.Linq.Expressions.Expression get_Item(Int32)/System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.Expression]
IL_02ca: castclass  System.Linq.Expressions.MethodCallExpression
IL_02cf: call       System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.Expression] get_Arguments()/System.Linq.Expressions.MethodCallExpression
IL_02d4: ldc.i4.1   
IL_02d5: callvirt   System.Linq.Expressions.Expression get_Item(Int32)/System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.Expression]
IL_02da: castclass  System.Linq.Expressions.UnaryExpression
IL_02df: call       System.Linq.Expressions.Expression get_Operand()/System.Linq.Expressions.UnaryExpression
IL_02e4: castclass  System.Linq.Expressions.LambdaExpression
IL_02e9: call       System.Linq.Expressions.Expression get_Body()/System.Linq.Expressions.LambdaExpression
IL_02ee: castclass  System.Linq.Expressions.MemberInitExpression
IL_02f3: call       System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.MemberBinding] get_Bindings()/System.Linq.Expressions.MemberInitExpression
IL_02f8: ldc.i4.1   
IL_02f9: callvirt   System.Linq.Expressions.MemberBinding get_Item(Int32)/System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.MemberBinding]
IL_02fe: castclass  System.Linq.Expressions.MemberAssignment
IL_0303: call       System.Linq.Expressions.Expression get_Expression()/System.Linq.Expressions.MemberAssignment
IL_0308: castclass  System.Linq.Expressions.UnaryExpression
IL_030d: call       System.Linq.Expressions.Expression get_Operand()/System.Linq.Expressions.UnaryExpression
IL_0312: castclass  System.Linq.Expressions.MemberExpression
IL_0317: call       System.Linq.Expressions.Expression get_Expression()/System.Linq.Expressions.MemberExpression
IL_031c: castclass  System.Linq.Expressions.ConstantExpression
IL_0321: call       System.Object get_Value()/System.Linq.Expressions.ConstantExpression
IL_0326: castclass  Tests.Linq.EnumMappingTests+<>c__DisplayClass55_0
IL_032b: ldfld      TestEnum1 param/Tests.Linq.EnumMappingTests+<>c__DisplayClass55_0
IL_0330: call       System.Nullable`1[Tests.Linq.EnumMappingTests+TestEnum1] op_Implicit(TestEnum1)/System.Nullable`1[Tests.Linq.EnumMappingTests+TestEnum1]
IL_0335: brtrue     IL_0348
IL_033a: ldloca.s   V_3
IL_033c: initobj    Tests.Linq.EnumMappingTests+TestEnum1
IL_0342: ldloc.3    
IL_0343: br         IL_03c9
IL_0348: ldarg.0    
IL_0349: castclass  System.Linq.Expressions.MethodCallExpression
IL_034e: call       System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.Expression] get_Arguments()/System.Linq.Expressions.MethodCallExpression
IL_0353: ldc.i4.0   
IL_0354: callvirt   System.Linq.Expressions.Expression get_Item(Int32)/System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.Expression]
IL_0359: castclass  System.Linq.Expressions.MethodCallExpression
IL_035e: call       System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.Expression] get_Arguments()/System.Linq.Expressions.MethodCallExpression
IL_0363: ldc.i4.1   
IL_0364: callvirt   System.Linq.Expressions.Expression get_Item(Int32)/System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.Expression]
IL_0369: castclass  System.Linq.Expressions.UnaryExpression
IL_036e: call       System.Linq.Expressions.Expression get_Operand()/System.Linq.Expressions.UnaryExpression
IL_0373: castclass  System.Linq.Expressions.LambdaExpression
IL_0378: call       System.Linq.Expressions.Expression get_Body()/System.Linq.Expressions.LambdaExpression
IL_037d: castclass  System.Linq.Expressions.MemberInitExpression
IL_0382: call       System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.MemberBinding] get_Bindings()/System.Linq.Expressions.MemberInitExpression
IL_0387: ldc.i4.1   
IL_0388: callvirt   System.Linq.Expressions.MemberBinding get_Item(Int32)/System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.MemberBinding]
IL_038d: castclass  System.Linq.Expressions.MemberAssignment
IL_0392: call       System.Linq.Expressions.Expression get_Expression()/System.Linq.Expressions.MemberAssignment
IL_0397: castclass  System.Linq.Expressions.UnaryExpression
IL_039c: call       System.Linq.Expressions.Expression get_Operand()/System.Linq.Expressions.UnaryExpression
IL_03a1: castclass  System.Linq.Expressions.MemberExpression
IL_03a6: call       System.Linq.Expressions.Expression get_Expression()/System.Linq.Expressions.MemberExpression
IL_03ab: castclass  System.Linq.Expressions.ConstantExpression
IL_03b0: call       System.Object get_Value()/System.Linq.Expressions.ConstantExpression
IL_03b5: castclass  Tests.Linq.EnumMappingTests+<>c__DisplayClass55_0
IL_03ba: ldfld      TestEnum1 param/Tests.Linq.EnumMappingTests+<>c__DisplayClass55_0
IL_03bf: call       System.Nullable`1[Tests.Linq.EnumMappingTests+TestEnum1] op_Implicit(TestEnum1)/System.Nullable`1[Tests.Linq.EnumMappingTests+TestEnum1]
IL_03c4: call       TestEnum1 op_Explicit(System.Nullable`1[Tests.Linq.EnumMappingTests+TestEnum1])/System.Nullable`1[Tests.Linq.EnumMappingTests+TestEnum1]
IL_03c9: box        Tests.Linq.EnumMappingTests+TestEnum1
IL_03ce: ldtoken    System.Nullable`1[System.Int64]/
IL_03d3: call       System.Type GetTypeFromHandle(System.RuntimeTypeHandle)/System.Type
IL_03d8: call       System.Object ConvertDefault(System.Object, System.Type)/LinqToDB.Common.ConvertBuilder
IL_03dd: unbox.any  System.Nullable`1[System.Int64]
IL_03e2: br         IL_0408
IL_03e7: ldc.i8     11
IL_03f0: newobj     Void .ctor(Int64)/System.Nullable`1[System.Int64]
IL_03f5: br         IL_0408
IL_03fa: ldc.i8     12
IL_0403: newobj     Void .ctor(Int64)/System.Nullable`1[System.Int64]
IL_0408: br         IL_0417
IL_040d: ldloca.s   V_4
IL_040f: initobj    System.Nullable`1[System.Int64]
IL_0415: ldloc.s    V_4
IL_0417: box        System.Nullable`1[System.Int64]
IL_041c: ret        

@jogibear9988
Copy link
Member

@MaceWindu don't know why the test hangs forever,

  var value = p.Accessor(expression, parameters); 

crashes with exception!

@MaceWindu
Copy link
Contributor Author

it doesn't hang really. Visual studio test runner waits for test to finish, but because test agent process crashed without a chance to report error to host, VS is not aware of it

@jogibear9988
Copy link
Member

This is the Debug view of the failing Expression Tree:

.Lambda #Lambda1<System.Func`3[System.Linq.Expressions.Expression,System.Object[],System.Object]>(
	System.Linq.Expressions.Expression $expr,
	System.Object[] $ps) {
	(System.Object).If (
		((System.Nullable`1[Tests.Linq.EnumMappingTests+TestEnum1])((Tests.Linq.EnumMappingTests+<>c__DisplayClass55_0)((System.Linq.Expressions.ConstantExpression)((System.Linq.Expressions.MemberExpression)((System.Linq.Expressions.UnaryExpression)((System.Linq.Expressions.MemberAssignment).Call (((System.Linq.Expressions.MemberInitExpression)((System.Linq.Expressions.LambdaExpression)((System.Linq.Expressions.UnaryExpression).Call (((System.Linq.Expressions.MethodCallExpression).Call (((System.Linq.Expressions.MethodCallExpression)$expr).Arguments).get_Item(0)
		).Arguments).get_Item(1)).Operand).Body).Bindings).get_Item(1)).Expression).Operand).Expression).Value).param).HasValue
	) {
		.Switch (.If ((System.Nullable`1[Tests.Linq.EnumMappingTests+TestEnum1])((Tests.Linq.EnumMappingTests+<>c__DisplayClass55_0)((System.Linq.Expressions.ConstantExpression)((System.Linq.Expressions.MemberExpression)((System.Linq.Expressions.UnaryExpression)((System.Linq.Expressions.MemberAssignment).Call (((System.Linq.Expressions.MemberInitExpression)((System.Linq.Expressions.LambdaExpression)((System.Linq.Expressions.UnaryExpression).Call (((System.Linq.Expressions.MethodCallExpression).Call (((System.Linq.Expressions.MethodCallExpression)$expr).Arguments).get_Item(0)
		).Arguments).get_Item(1)).Operand).Body).Bindings).get_Item(1)).Expression).Operand).Expression).Value).param == null) {
			.Default(Tests.Linq.EnumMappingTests+TestEnum1)
		} .Else {
			(Tests.Linq.EnumMappingTests+TestEnum1)((System.Nullable`1[Tests.Linq.EnumMappingTests+TestEnum1])((Tests.Linq.EnumMappingTests+<>c__DisplayClass55_0)((System.Linq.Expressions.ConstantExpression)((System.Linq.Expressions.MemberExpression)((System.Linq.Expressions.UnaryExpression)((System.Linq.Expressions.MemberAssignment).Call (((System.Linq.Expressions.MemberInitExpression)((System.Linq.Expressions.LambdaExpression)((System.Linq.Expressions.UnaryExpression).Call (((System.Linq.Expressions.MethodCallExpression).Call (((System.Linq.Expressions.MethodCallExpression)$expr).Arguments).get_Item(0)
			).Arguments).get_Item(1)).Operand).Body).Bindings).get_Item(1)).Expression).Operand).Expression).Value).param)
		}) {
		.Case (.Constant<Tests.Linq.EnumMappingTests+TestEnum1>(Value1)):
				.Constant<System.Nullable`1[System.Int64]>(11)
		.Case (.Constant<Tests.Linq.EnumMappingTests+TestEnum1>(Value2)):
				.Constant<System.Nullable`1[System.Int64]>(12)
		.Default:
				(System.Nullable`1[System.Int64]).Call LinqToDB.Common.ConvertBuilder.ConvertDefault(
					(System.Object).If ((System.Nullable`1[Tests.Linq.EnumMappingTests+TestEnum1])((Tests.Linq.EnumMappingTests+<>c__DisplayClass55_0)((System.Linq.Expressions.ConstantExpression)((System.Linq.Expressions.MemberExpression)((System.Linq.Expressions.UnaryExpression)((System.Linq.Expressions.MemberAssignment).Call (((System.Linq.Expressions.MemberInitExpression)((System.Linq.Expressions.LambdaExpression)((System.Linq.Expressions.UnaryExpression).Call (((System.Linq.Expressions.MethodCallExpression).Call (((System.Linq.Expressions.MethodCallExpression)$expr).Arguments).get_Item(0)
					).Arguments).get_Item(1)).Operand).Body).Bindings).get_Item(1)).Expression).Operand).Expression).Value).param == null) {
						.Default(Tests.Linq.EnumMappingTests+TestEnum1)
					} .Else {
						(Tests.Linq.EnumMappingTests+TestEnum1)((System.Nullable`1[Tests.Linq.EnumMappingTests+TestEnum1])((Tests.Linq.EnumMappingTests+<>c__DisplayClass55_0)((System.Linq.Expressions.ConstantExpression)((System.Linq.Expressions.MemberExpression)((System.Linq.Expressions.UnaryExpression)((System.Linq.Expressions.MemberAssignment).Call (((System.Linq.Expressions.MemberInitExpression)((System.Linq.Expressions.LambdaExpression)((System.Linq.Expressions.UnaryExpression).Call (((System.Linq.Expressions.MethodCallExpression).Call (((System.Linq.Expressions.MethodCallExpression)$expr).Arguments).get_Item(0)
						).Arguments).get_Item(1)).Operand).Body).Bindings).get_Item(1)).Expression).Operand).Expression).Value).param)
					},
					.Constant<System.RuntimeType>(System.Nullable`1[System.Int64]))
		}
	} .Else {
		null
	}
}

@MaceWindu
Copy link
Contributor Author

MaceWindu commented Sep 7, 2018

But for this to find out, I have to find where the Expression for the IL is generated!

well, just put breakpoint on compiler call and inspect passed expression (could be multiple calls within one test with different expressions)

@MaceWindu
Copy link
Contributor Author

MaceWindu commented Sep 7, 2018

BTW, don't fully trust debug view. It could have rendering bugs. At least it doesn't handle \0 characters properly in string constants. Also it doesn't consistent with variables naming - it could name different variables with the same name sometimes or name them as parameters

@jogibear9988
Copy link
Member

I found the Expression, but it's huge. I now have to create a test, then try to track down whats wrong. Will take some time!

@dadhi
Copy link

dadhi commented Sep 7, 2018

ok.

@jogibear9988
Copy link
Member

@MaceWindu Maybe once more again when my pull req is merged. With my newest patched Version it seems to work

@MaceWindu
Copy link
Contributor Author

/azp run test-all

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@MaceWindu
Copy link
Contributor Author

/azp run test-all

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@MaceWindu
Copy link
Contributor Author

/azp run test-all

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@MaceWindu
Copy link
Contributor Author

/azp run test-all

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@MaceWindu
Copy link
Contributor Author

/azp run test-all

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@linq2dbot
Copy link

Test baselines changed by this PR. Don't forget to merge/close baselines PR after this pr merged/closed.

@MaceWindu
Copy link
Contributor Author

/azp run test-all

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@MaceWindu
Copy link
Contributor Author

/azp run test-all

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@MaceWindu MaceWindu merged commit f005a8a into master Feb 4, 2021
@MaceWindu MaceWindu deleted the expressions_compilation branch February 4, 2021 13:58
MaceWindu pushed a commit to linq2db/linq2db.baselines that referenced this pull request Feb 4, 2021
* [Windows / NET 5.0 / SQL Server 2019 (Microsoft.Data.SqlClient)] baselines

* [Windows / NET472 / SQL Server 2019 (System.Data.SqlClient)] baselines

* [Windows / NET472 / SQL Server 2005 (System.Data.SqlClient)] baselines

* [Windows / NET472 / SQL Server 2019 (Microsoft.Data.SqlClient)] baselines

* [Windows / NET472 / SQL Server 2012 (System.Data.SqlClient)] baselines

* [Windows / NET472 / SQL Server 2008 (System.Data.SqlClient)] baselines

* [Windows / NET472 / SQL Server 2014 (System.Data.SqlClient)] baselines

* [Windows / NET472 / SQL Server 2017 (System.Data.SqlClient)] baselines

* [Windows / NET472 / SQL Server 2016 (System.Data.SqlClient)] baselines

* [Windows / NETCOREAPP2.1 / SQL Server 2005 (System.Data.SqlClient)] baselines

* [Windows / NETCOREAPP2.1 / SQL Server 2012 (System.Data.SqlClient)] baselines

* [Windows / NETCOREAPP2.1 / SQL Server 2008 (System.Data.SqlClient)] baselines

* [Windows / NETCOREAPP2.1 / SQL Server 2014 (System.Data.SqlClient)] baselines

* [Windows / NETCOREAPP2.1 / SQL Server 2017 (System.Data.SqlClient)] baselines

* [Windows / NETCOREAPP2.1 / SQL Server 2016 (System.Data.SqlClient)] baselines

Co-authored-by: Azure Pipelines Bot <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants