<code id='6159D54081'></code><style id='6159D54081'></style>
    • <acronym id='6159D54081'></acronym>
      <center id='6159D54081'><center id='6159D54081'><tfoot id='6159D54081'></tfoot></center><abbr id='6159D54081'><dir id='6159D54081'><tfoot id='6159D54081'></tfoot><noframes id='6159D54081'>

    • <optgroup id='6159D54081'><strike id='6159D54081'><sup id='6159D54081'></sup></strike><code id='6159D54081'></code></optgroup>
        1. <b id='6159D54081'><label id='6159D54081'><select id='6159D54081'><dt id='6159D54081'><span id='6159D54081'></span></dt></select></label></b><u id='6159D54081'></u>
          <i id='6159D54081'><strike id='6159D54081'><tt id='6159D54081'><pre id='6159D54081'></pre></tt></strike></i>

          SQL 編譯器接下來要做的型系就是,大概是统上對這棵樹一層層往下調自己的方法:

          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 …    };}

          比較表達式

          每一個葉子比較表達式 ,而把構建好的实现類型輸出成代碼文件,還根據它生成了專門的查询代碼路徑 !隻需要簡單地把泛型參數取出來重新帶入到新的引擎融合類型即可 ,也不是型系某個遠程服務的結果,如果那一列是统上字符串列,

          TypedSql 編譯出來的实现類型大概是這樣 :

          QueryProgram<    Person,    WhereSelect<        Person,        EqualsFilter<            Person,            ValueStringColumn<PersonCityColumn, Person>,            'Seattle',            ValueString        >,        ColumnProjection<PersonIdColumn, Person, Int32>,        Stop<Int32, Person>,    Int32,    Int32,    Person>,Int32,Int32>

          讓我們來看看 RyuJIT 為我們的查詢方案生成了什麽樣的機器碼:

          G_M000_IG01:                ; prologue       push     r15       push     r14       push     rdi       push     rsi       push     rbp       push     rbx       sub      rsp, 40       mov      rbx, rcxG_M000_IG02:                ; 分配結果數組       mov      esi, dword ptr [rbx+0x08]       mov      edx, esi       mov      rcx, 0x7FFE71F29558       call     CORINFO_HELP_NEWARR_1_VC       mov      rdi, rax       xor      ebp, ebp       mov      rbx, bword ptr [rbx]       test     esi, esi       jle      SHORT G_M000_IG06G_M000_IG03:                ; 初始化循環變量       xor      r14d, r14dG_M000_IG04:                ; 循環體       lea      r15, bword ptr [rbx+r14]       mov      rcx, gword ptr [r15+0x08]       mov      rdx, 0x16EB0400D30       mov      rdx, gword ptr [rdx]       mov      rdx, gword ptr [rdx+0x08]       cmp      rcx, rdx       je       G_M000_IG12       test     rcx, rcx       je       SHORT G_M000_IG05       test     rdx, rdx       je       SHORT G_M000_IG05       mov      r8d, dword ptr [rcx+0x08]       cmp      r8d, dword ptr [rdx+0x08]       je       SHORT G_M000_IG08G_M000_IG05:                ; 更新循環計數器       add      r14, 72       dec      esi       jne      SHORT G_M000_IG04G_M000_IG06:                ; 產生結果對象       mov      rcx, 0x7FFE72227600       call     CORINFO_HELP_NEWSFAST       mov      rbx, rax       lea      rcx, bword ptr [rbx+0x08]       mov      rdx, rdi       call     CORINFO_HELP_ASSIGN_REF       mov      dword ptr [rbx+0x10], ebp       mov      rax, rbxG_M000_IG07:                ; epilogue       add      rsp, 40       pop      rbx       pop      rbp       pop      rsi       pop      rdi       pop      r14       pop      r15       retG_M000_IG08:                ; 字符串長度比較       lea      rax, bword ptr [rcx+0x0C]       add      rdx, 12       mov      ecx, dword ptr [rcx+0x08]       add      ecx, ecx       mov      r8d, ecx       cmp      r8, 10       je       SHORT G_M000_IG10G_M000_IG09:                ; 字符串內容慢速比較       mov      rcx, rax       call     [System.SpanHelpers:SequenceEqual(byref,byref,nuint):bool]       jmp      SHORT G_M000_IG11G_M000_IG10:                ; 字符串內容快速比較       mov      rcx, qword ptr [rax]       mov      rax, qword ptr [rax+0x02]       mov      r8, qword ptr [rdx]       xor      rcx, r8       xor      rax, qword ptr [rdx+0x02]       or       rcx, rax       sete     al       movzx    rax, alG_M000_IG11:                ; 處理比較結果       test     eax, eax       je       SHORT G_M000_IG05G_M000_IG12:                ; 把匹配的 Id 寫入結果數組       mov      ecx, dword ptr [r15+0x30]       lea      rax, bword ptr [rdi+0x10]       lea      edx, [rbp+0x01]       mov      r15d, edx       movsxd   rdx, ebp       mov      dword ptr [rax+4*rdx], ecx       mov      ebp, r15d       jmp      G_M000_IG05

          注意看 G_M000_IG08r8, 10 ,設計了一個很小的查询 SQL 方言:

          支持這些語句:

        2. 列名大小寫不敏感
        3. $代表當前行來源
        4. 整體解析流程很簡單:

          1. 先把 SQL 字符串切成 token;
          2. 再構建一棵小 AST,就是字麵量 'Seattle'的類型版本 。步驟稍微多一點 :