sqlkata / querybuilder

SQL query builder, written in c#, helps you build complex queries easily, supports SqlServer, MySql, PostgreSql, Oracle, Sqlite and Firebird
https://sqlkata.com
MIT License
3.08k stars 498 forks source link

System.Exception: Failed to locate a compiler for 'CompileBasicCondition' #639

Closed MaYiLagann closed 1 year ago

MaYiLagann commented 1 year ago

Summary

hi, i'm using SqlKata on Unity game engine (Unity-2020.3.40f1) i launched app on editor and it was fine, but app crashed after build. can i get some help here?

Error logs

System.Exception: Failed to locate a compiler for 'CompileBasicCondition'.
  at SqlKata.Compilers.ConditionsCompilerProvider.FindMethodInfo (System.Type clauseType, System.String methodName) [0x00000] in <00000000000000000000000000000000>:0 
  at SqlKata.Compilers.ConditionsCompilerProvider.GetMethodInfo (System.Type clauseType, System.String methodName) [0x00000] in <00000000000000000000000000000000>:0 
  at SqlKata.Compilers.Compiler.CompileCondition (SqlKata.SqlResult ctx, SqlKata.AbstractCondition clause) [0x00000] in <00000000000000000000000000000000>:0 
  at SqlKata.Compilers.Compiler.CompileConditions (SqlKata.SqlResult ctx, System.Collections.Generic.List`1[T] conditions) [0x00000] in <00000000000000000000000000000000>:0 
  at SqlKata.Compilers.Compiler.CompileWheres (SqlKata.SqlResult ctx) [0x00000] in <00000000000000000000000000000000>:0 
  at SqlKata.Compilers.Compiler.CompileSelectQuery (SqlKata.Query query) [0x00000] in <00000000000000000000000000000000>:0 
  at SqlKata.Compilers.Compiler.Compil

How to reproduce

  1. Create new project with unity 2020.3.40f1
  2. Import package NuGetForUnity
  3. Install package SqlKata 2.4.0
  4. Create script and write any new Query and SqliteCompiler.Compile
  5. Save and build application to android

Others

i test some logics in ConditionsCompilerProvider.FindMethodInfo, but it was not working for expected.

here the script i tested:

var query = new Query("ANY_TABLE_NAME");
var compiler = new SqliteCompiler();
var queryString = compiler.Compile(query);

Debug.Log($"SqliteCompiler methods: {string.Join(",", compiler.GetType().GetRuntimeMethods().Select(x => x.Name))}");

/*
Play on Editor says:
SqliteCompiler methods: get_EngineCode, get_parameterPlaceholder, set_parameterPlaceholder, get_parameterPrefix, set_parameterPrefix, get_OpeningIdentifier, set_OpeningIdentifier, get_ClosingIdentifier, set_ClosingIdentifier, get_LastId, set_LastId, CompileTrue, CompileFalse, CompileLimit, CompileBasicDateCondition, FindCompilerMethodInfo, CompileCondition, CompileConditions, CompileRawCondition, CompileQueryCondition, CompileSubQueryCondition, CompileBasicCondition, CompileBasicStringCondition, CompileNestedCondition, CompileTwoColumnsCondition, CompileBetweenCondition, CompileInCondition, CompileInQueryCondition, CompileNullCondition, CompileBooleanCondition, CompileExistsCondition, get_ColumnAsKeyword, set_ColumnAsKeyword, get_TableAsKeyword, set_TableAsKeyword, get_EscapeCharacter, set_EscapeCharacter, get_SingleRowDummyTableName, generateNamedBindings, PrepareResult, CompileRaw, Whitelist, Compile, Compile, CompileSelectQuery, CompileAdHocQuery, CompileDeleteQuery, CompileUpdateQuery, CompileInsertQuery, CompileCteQuery, CompileColumn, CompileCte, OnBeforeSelect, CompileColumns, CompileUnion, CompileTableExpression, CompileFrom, CompileJoins, CompileJoin, CompileWheres, CompileGroups, CompileOrders, CompileHaving, CompileRandom, CompileLower, CompileUpper, checkOperator, Wrap, WrapValue, Resolve, Parameter, Parameterize, WrapArray, WrapIdentifiers, Equals, Finalize, GetHashCode, GetType, MemberwiseClone, ToString

Play on After Build with Android says:
SqliteCompiler methods: get_EngineCode,get_parameterPlaceholder,get_parameterPrefix,get_OpeningIdentifier,get_ClosingIdentifier,get_LastId,CompileLimit,FindCompilerMethodInfo,CompileCondition,CompileConditions,get_ColumnAsKeyword,get_TableAsKeyword,get_EscapeCharacter,get_SingleRowDummyTableName,generateNamedBindings,PrepareResult,CompileRaw,Compile,CompileSelectQuery,CompileAdHocQuery,CompileDeleteQuery,CompileUpdateQuery,CompileInsertQuery,CompileCteQuery,CompileColumn,CompileCte,CompileColumns,CompileUnion,CompileTableExpression,CompileFrom,CompileJoins,CompileJoin,CompileWheres,CompileGroups,CompileOrders,CompileHaving,Wrap,WrapValue,Parameter,Parameterize,WrapArray,WrapIdentifiers,Equals,Finalize,GetHashCode,GetType,MemberwiseClone,ToString
*/
ahmad-moussawi commented 1 year ago

I am not familiar with Unity, but what comes to my mind, that what's happening is something similar to JavaScript tree shaking, where the compiler remove methods with no reference, and since CompileBasicCondition is called via reflection so there is no direct reference.

I am not sure what would be the solution here, but I am pretty sure that directly referencing the CompileBasicCondition method in your code, will do the trick

ahmad-moussawi commented 1 year ago

From their doc, I found this

Enable Strip Engine Code in the Unity Editor Player settings (go to Edit > Project Settings , then select the Player category). This option statically analyzes the managed code in the Project, and removes any unused code.

https://docs.unity3d.com/2020.3/Documentation/Manual/dotnetProfileLimitations.html

so maybe disabling this option will help in your case

MaYiLagann commented 1 year ago

thanks for quick response!

i solved this problem just writing link.xml

<!-- link.xml -->
<linker>
    <assembly fullname="SqlKata" preserve="all"/>
</linker>

unity build with il2cpp will always stripping unused codes, so it should be preserved manually.

image