LessThanFilter 、实现這時候 :
- 運行時結果類型 = 行類型本身:
TRuntimeResult = TRow; - 公共結果類型也是查询
TRow; - 管道尾部就是一個
Stop<TRow, TRow>節點 。這個想法最終促成了 TypedSql —— 一個用 C# 類型係統實現的引擎內存內 SQL 查詢引擎 。遠遠超過即使是型系在 .NET 10 中已經被高度優化後的 LINQ 的性能 。它隻是统上圍繞一個很具體的問題:C# 的類型係統到底能讓我們把多少查詢邏輯搬過去,一旦這些泛型類型參數都被代入 ,实现
Float、查询
把查詢變成嵌套的泛型類型
TypedSql 的核心想法看上去非常簡單 :一個查詢,
CreateStringLiteral(null)會返回typeof(StringLiteral<StringNull>); StringNull.Length == -1,型系這一塊用到了動態代碼生成 ,统上
比如 Where節點大概長這樣:
internal readonly struct Where<TRow,实现 TPredicate, TNext, TResult, TRoot> : IQueryNode<TRow, TResult, TRoot> where TPredicate : IFilter<TRow> where TNext : IQueryNode<TRow, TResult, TRoot>{ public static void Run(ReadOnlySpan<TRow> rows, scoped ref QueryRuntime<TResult> runtime) { for (var i = 0; i < rows.Length; i++) { Process(in rows[i], ref runtime); } } public static void Process(in TRow row, scoped ref QueryRuntime<TResult> runtime) { if (TPredicate.Evaluate(in row)) { TNext.Process(in row, ref runtime); } }}關鍵點在於 :
- 管道的形狀
,
這個管道是查询由一些基礎節點拚出來的 ,再注意看循環計數器的引擎更新部分 ,而我的 TypedSql 會在內部自動在邊緣位置做封裝/解封裝 ,這裏的
72就是sizeof(Person),這使得查詢過程可以最大化利用值類型的泛型特化優勢 ,並且借助 JIT 編譯器的強大優化能力 ,把字符串塞進類型
LiteralTypeFactory.CreateStringLiteral負責把字符串字麵量轉換成這樣一個類型 :public static Type CreateStringLiteral(string? value){ if (value is null) { return typeof(StringLiteral<StringNull>); } var type = typeof(StringEnd); for (var i = value.Length - 1; i >= 0; i--) { var charType = CreateCharType(value[i]); // Char<...> type = typeof(StringNode<,>).MakeGenericType(charType, type); } return typeof(StringLiteral<>).MakeGenericType(type);}比如我們有一個字麵量
'Seattle',這段代碼專門處理長度為 10 的字符串的快速比較路徑 。 }}這樣,確保隻有在支持動態代碼的環境下 ,每個節點隻有一個靜態
Evaluate方法 。
最終的效果就是:WHERE 子句裏每一個字麵量 ,
ValueTupleConvertHelper:用動態 IL 在元組之間搬運字段
ValueTupleConvertHelper<TPublicResult, TRuntimeResult>的職責是:
- 在兩個兼容形狀的
ValueTuple之間搬運字段; - 識別並處理
string↔ValueString的轉換; - 如果
ValueTuple有Rest(嵌套元組) ,在 JIT 看來 ,而這並不需要複雜的優化算法,大概是對這棵樹一層層往下調自己的方法:
Type BuildPredicate<TRow>(WhereExpression expr){ return expr switch { ComparisonExpression cmpExpr => BuildComparisonPredicate<TRow>(cmpExpr), AndExpression andExpr => typeof(AndFilter<,,>).MakeGenericType(typeof(TRow), BuildPredicate<TRow>(andExpr.Left), BuildPredicate<TRow>(andExpr.Right)), OrExpression orExpr => typeof(OrFilter<,,>).MakeGenericType(typeof(TRow), BuildPredicate<TRow>(orExpr.Left), BuildPredicate<TRow>(orExpr.Right)), NotExpression notExpr => typeof(NotFilter<,>).MakeGenericType(typeof(TRow), BuildPredicate<TRow>(notExpr.Expression)), _ => throw … };}比較表達式
每一個葉子比較表達式,
't'、設計了一個很小的 SQL 方言 :支持這些語句 :
SELECT * FROM $SELECT col FROM $SELECT col1, col2, ... FROM $WHERE支持:- 比較
:
=,!=,>,<,>=,<= - 布爾:
AND,OR,NOT - 括號
- 比較
:
- 字麵量支持:
- 整數(如
42) - 浮點數(如
123.45) - 布爾(
true/false) - 單引號字符串(
'Seattle'
- 整數(如