Bug 56789 - [15.2] "System.NotSupportedException: Cannot compile: Parameter" during certain sqlite operations with use of System.Linq, if app is compiled with `csc`
Summary: [15.2] "System.NotSupportedException: Cannot compile: Parameter" during certa...
Status: VERIFIED UPSTREAM
Alias: None
Product: Android
Classification: Xamarin
Component: General ()
Version: 7.3 (15.2)
Hardware: PC Mac OS
: --- major
Target Milestone: 15.3
Assignee: Jonathan Pryor
URL:
: 55689 ()
Depends on:
Blocks:
 
Reported: 2017-05-24 09:56 UTC by Brendan Zagaeski (Xamarin Team, assistant)
Modified: 2018-02-13 21:21 UTC (History)
4 users (show)

Tags: 15.1R
Is this bug a regression?: Yes
Last known good build: Xamarin 15.1 Release


Attachments
Test case (66.10 KB, application/zip)
2017-05-24 09:56 UTC, Brendan Zagaeski (Xamarin Team, assistant)
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
VERIFIED UPSTREAM

Description Brendan Zagaeski (Xamarin Team, assistant) 2017-05-24 09:56:59 UTC
Created attachment 22411 [details]
Test case

[15.2] "System.NotSupportedException: Cannot compile: Parameter" during certain sqlite operations with use of System.Linq, if app is compiled with `csc`




## Partial workaround

Temporarily switch back to `mcs` and `xbuild`:


1. Add the following PropertyGroup element to the bottom of the .csproj file for your app project just before the closing </Project> tag:

<PropertyGroup Condition=" '$(OS)' == 'Unix' ">
    <CscToolExe>mcs.exe</CscToolExe>
</PropertyGroup>


2. Disable "Visual Studio > Preferences > Build > Build with MSBuild instead of xbuild" in Visual Studio for Mac.


3. Close and reopen the solution to ensure the new setting is used.


4. Clean and rebuild the project.


(See also the "Temporarily switching back ..." section on https://releases.xamarin.com/common-issues-from-the-xamarin-15-2-release-being-tracked-by-the-xamarin-team/ for a little additional background information.)




## Regression status: regression in behavior in the Xamarin 15.2 release, possibly due to an incompatibility of Xamarin.Android with the new default `csc` compiler in Mono 5.0?

> BAD:  Xamarin.Android 7.3.1.1 (bc24645) + Mono 5.0.1.1 (2017-02/5077205), when using `csc`
> GOOD: Xamarin.Android 7.3.1.1 (bc24645) + Mono 5.0.1.1 (2017-02/5077205), when using `mcs`
> GOOD: Xamarin.Android 7.3.1.1 (bc24645) + Mono 4.8.1   (mono-4.8.0-branch/22a39d7)
> GOOD: Xamarin.Android 7.2.0.7 (b16fb82) + Mono 4.8.1   (mono-4.8.0-branch/22a39d7)




## Steps followed to test

Build and run the "test.Droid" test case in the "Debug" configuration.




## BAD Results with Xamarin.Android

The application hits an unhandled exception on the line `return db.Table<T>().FirstOrDefault(x => x.DBID == id);`:

> System.NotSupportedException: Cannot compile: Parameter
>    at SQLite.TableQuery`1[T].CompileExpr (System.Linq.Expressions.Expression expr, System.Collections.Generic.List`1[T] queryArgs) [0x0091f] in /Users/fak/Dropbox/Projects/sqlite-net/src/SQLite.cs:3032 
>    at SQLite.TableQuery`1[T].CompileExpr (System.Linq.Expressions.Expression expr, System.Collections.Generic.List`1[T] queryArgs) [0x00676] in /Users/fak/Dropbox/Projects/sqlite-net/src/SQLite.cs:2945 
>    at SQLite.TableQuery`1[T].CompileExpr (System.Linq.Expressions.Expression expr, System.Collections.Generic.List`1[T] queryArgs) [0x00748] in /Users/fak/Dropbox/Projects/sqlite-net/src/SQLite.cs:2963 
>    at SQLite.TableQuery`1[T].CompileExpr (System.Linq.Expressions.Expression expr, System.Collections.Generic.List`1[T] queryArgs) [0x0009d] in /Users/fak/Dropbox/Projects/sqlite-net/src/SQLite.cs:2869 
>    at SQLite.TableQuery`1[T].GenerateCommand (System.String selectionList) [0x00068] in /Users/fak/Dropbox/Projects/sqlite-net/src/SQLite.cs:2825 
>    at SQLite.TableQuery`1[T].GetEnumerator () [0x0000b] in /Users/fak/Dropbox/Projects/sqlite-net/src/SQLite.cs:3101 
>    at System.Collections.Generic.List`1[T]..ctor (System.Collections.Generic.IEnumerable`1[T] collection) [0x00062] in <d18287e1d683419a8ec3216fd78947b9>:0 
>    at System.Linq.Enumerable.ToList[TSource] (System.Collections.Generic.IEnumerable`1[T] source) [0x00018] in <cc41d889a5b24501ae882a5cc55746dd>:0 
>    at SQLite.TableQuery`1[T].FirstOrDefault () [0x00008] in /Users/fak/Dropbox/Projects/sqlite-net/src/SQLite.cs:3120 
>    at SQLite.TableQuery`1[T].FirstOrDefault (System.Linq.Expressions.Expression`1[TDelegate] predExpr) [0x00000] in /Users/fak/Dropbox/Projects/sqlite-net/src/SQLite.cs:3130 
>    at test.DL.MainDatabase.GetItem[T] (System.Int32 id) [0x00020] in /private/tmp/Working/foo/test/test/DL/MainDatabase.cs:115 
>    at test.DAL.DataManager.GetDataObject (System.Int32 dbid) [0x00001] in /private/tmp/Working/foo/test/test/DAL/DataManager.cs:71 
>    at test.BL.Managers.DataObjectManager.GetDataObject (System.Int32 dbid) [0x00001] in /private/tmp/Working/foo/test/test/BL/Managers/DataObjectManager.cs:19 
>    at test.Droid.MainActivity.<Initialise>b__4_2 () [0x00001] in /private/tmp/Working/foo/test/Droid/UI/MainActivity.cs:107 
>    at Java.Lang.Thread+RunnableImplementor.Run () [0x00008] in <8804aaaf21bc4f45b576b50092b57059>:0 
>    at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in <8804aaaf21bc4f45b576b50092b57059>:0 
>    at (wrapper dynamic-method) System.Object:dcb15fc7-d9f3-4016-b131-be4ee276f793 (intptr,intptr)



## Additional testing environment info (brief)

Android SDK Tools Version: 25.2.5
Android SDK Platform Tools Version: 25.0.3
Android SDK Build Tools Version: 25

Java JDK version "1.8.0_65" (64-bit)

Visual Studio for Mac version 7.0 (build 3146)
Git revision: 7553fda2e327d15807298d444007896e5b975dba

macOS 10.12.4
US English locale, US Eastern time zone



### Devices tested

Google API 23 x86 emulator
Comment 1 Brendan Zagaeski (Xamarin Team, assistant) 2017-05-24 09:59:44 UTC
*** Bug 55689 has been marked as a duplicate of this bug. ***
Comment 2 Sam 2017-05-30 09:05:45 UTC
Just to add that the work around does indeed work however proguard seems to fail when using them. Do we have any indication when a real fix may be available.
Comment 3 Jonathan Pryor 2017-06-01 02:03:03 UTC
As per the stack trace, this is happening in `SQLite.TableQuery<T>.CompileExpr()`, which is not code that we provide. This is in the SQLite-net-PCL NuGet:

https://www.nuget.org/packages/sqlite-net-pcl/

As a guess, it's throwing here:

https://github.com/praeclarum/sqlite-net/blob/v1.3.0/src/SQLite.cs#L3032

...and it looks like v1.3.3 may have fixed it, as there are many changes in TableQuery<T>.CompileExpr() between v1.3.0 and v1.3.3:

https://github.com/praeclarum/sqlite-net/compare/v1.3.0...v1.3.3

@Brenden: Does upgrading the sqlite-net-pcl package fix it?
Comment 4 Sam 2017-06-01 10:22:27 UTC
Just checked with upgraded package and it made no difference for me.
Comment 5 Sam 2017-06-01 10:41:58 UTC
I have raised the issue on github as well in the hope it can be addressed there.
Comment 6 Jonathan Pryor 2017-06-02 14:32:22 UTC
This appears to be a bug in sqlite-net-pcl not supporting CSC-generated expression trees.

https://github.com/praeclarum/sqlite-net/issues/552
Comment 7 Brendan Zagaeski (Xamarin Team, assistant) 2017-06-02 16:40:28 UTC
Interesting, thanks!  Just to add a few details about the nature of the upstream problem for my own curiosity (and for any interested users who might be watching the bug):



- When the test case is compiled with `mcs`, the outermost expression that gets passed in to sqlite-net's `CompileExpr()` method is:

$x.DBID == .Constant<test.DL.MainDatabase+<GetItem>c__AnonStorey0`1[test.BL.DataObject]>(test.DL.MainDatabase+<GetItem>c__AnonStorey0`1[test.BL.DataObject]).id



- With `csc`, the outermost expression is a little different.  In particular notice the difference at the very beginning of the expression.  This difference in the expression means that the `$x` in the expression is now a Parameter by NodeType, and sqlite-net does not yet have a rule to handle Parameter nodes.

((test.BL.Contracts.IBusinessEntity)$x).DBID == .Constant<test.DL.MainDatabase+<>c__DisplayClass10_0`1[test.BL.DataObject]>(test.DL.MainDatabase+<>c__DisplayClass10_0`1[test.BL.DataObject]).id
Comment 8 Sam 2017-06-06 10:40:45 UTC
Is the only way to prevent this issue to compile with mcs, will this option be available to me for the forseeable future and are there any other issues with building this way ? as I am still on an old build of xamarin studio as I am concerned about moving to VS if this issue cannot be resolved.
Comment 9 Sam 2017-06-07 15:38:33 UTC
@Brenden Ok I have been having a play with the source code and changing 

if (mem.Expression != null && mem.Expression.NodeType == Expression.Parameter)

To

if (mem.Expression != null && (mem.Expression.NodeType == Expression.Parameter || mem.Expression.NodeType == Expression.Convert))

Seems to fix the issue for me, Not done any thorough testing but have submitted fix in the hope its at least a partial fix if not the complete one.
Comment 10 Frank A. Krueger 2017-08-01 20:22:19 UTC
This has been fixed in sqlite-net: https://github.com/praeclarum/sqlite-net/commit/2df530a3d2215ee4ac4b7c034a4d4fa0a46543bf
Comment 11 Sam 2017-08-03 14:58:48 UTC
I have just tested the new update and I am getting the exact same issue, having to revert to my fix.
Comment 12 J. 2018-02-13 13:04:06 UTC
Hi! I'm still facing this issue with the newest version of Xamarin Android and SQLite-net-PCL package.
Even when I switch to  mcs, still

System.NotSupported Exception:
Cannot compile: Parameter

On:
Table<T>().FirstOrDefault(x => x.Id == id);

Where T has a constraint on IEntity which has an Id
Comment 13 Brendan Zagaeski (Xamarin Team, assistant) 2018-02-13 21:21:50 UTC
The best place for follow-up discussion about the message "Cannot compile: Parameter" will be the discussion channels for the SQLite-net library (such as the GitHub Issues tracker for that library).  That message is specific to that library based and the particular expression types it understands.