自分用メモ: EXPLAINを利用してsqliteの集約の仕組みを追う

## はじめに

朝活の資料です.

## 資料

* https://www.sqlite.org/arch.html
* https://runebook.dev/ja/docs/sqlite/vdbe
* https://sqlite.org/opcode.html
* https://qiita.com/kahirokunn/items/be0712cc6997bb62d57d

## 解析

```sql
EXPLAIN select sum(two), one from examp group by one;
```

このsqlはこう出てくる

```
addr  opcode         p1    p2    p3    p4             p5  comment
----  -------------  ----  ----  ----  -------------  --  -------------
0     Init           0     43    0                    0   Start at 43
1     SorterOpen     1     2     0     k(1,B)         0
2     Integer        0     5     0                    0   r[5]=0; clear abort flag
3     Null           0     8     8                    0   r[8..8]=NULL
4     Gosub          7     39    0                    0
5     OpenRead       0     2     0     2              0   root=2 iDb=0; examp
6     Explain        6     0     0     SCAN TABLE examp  0
7     Rewind         0     13    0                    0
8       Column         0     0     10                   0   r[10]=examp.one
9       Column         0     1     11                   0   r[11]=examp.two
10      MakeRecord     10    2     12                   0   r[12]=mkrec(r[10..11])
11      SorterInsert   1     12    0                    0   key=r[12]
12    Next           0     8     0                    1
13    OpenPseudo     2     12    2                    0   2 columns in r[12]
14    SorterSort     1     42    0                    0   GROUP BY sort
15      SorterData     1     12    2                    0   r[12]=data
16      Column         2     0     9                    0   r[9]=
17      Compare        8     9     1     k(1,B)         0   r[8] <-> r[9]
18      Jump           19    23    19                   0
19      Move           9     8     1                    0   r[8]=r[9]
20      Gosub          6     33    0                    0   output one row
21      IfPos          5     42    0                    0   if r[5]>0 then r[5]-=0, goto 42; check abort flag
22      Gosub          7     39    0                    0   reset accumulator
23      Column         2     1     13                   0   r[13]=examp.two
24      AggStep        0     13    1     sum(1)         1   accum=r[1] step(r[13])
25      If             4     27    0                    0
26      Column         2     0     2                    0   r[2]=examp.one
27      Integer        1     4     0                    0   r[4]=1; indicate data in accumulator
28    SorterNext     1     15    0                    0
29    Gosub          6     33    0                    0   output final row
30    Goto           0     42    0                    0
31    Integer        1     5     0                    0   r[5]=1; set abort flag
32    Return         6     0     0                    0
33    IfPos          4     35    0                    0   if r[4]>0 then r[4]-=0, goto 35; Groupby result generator entry point
34    Return         6     0     0                    0
35    AggFinal       1     1     0     sum(1)         0   accum=r[1] N=1
36    Copy           1     14    1                    0   r[14..15]=r[1..2]
37    ResultRow      14    2     0                    0   output=r[14..15]
38    Return         6     0     0                    0   end groupby result generator
39    Null           0     1     3                    0   r[1..3]=NULL
40    Integer        0     4     0                    0   r[4]=0; indicate accumulator empty
41    Return         7     0     0                    0
42    Halt           0     0     0                    0
43    Transaction    0     0     3     0              1   usesStmtJournal=0
44    Goto           0     1     0                    0
```

SorterOpenで開始して、Rewindで読み込んで、レコードを作成し、そのレコードの項目はgroup byの項目で設定し、SorterInsertで、そのレコードをSorter objectに入れて、OpenPseudoでSorter objectを疑似テーブルとして扱い、SorterSortで並べ替えながら、AggStepを実行する.
集約関数は、基本並び順に影響しない. group_concat等、並び順に影響を受ける集約関数の場合は、集約関数内にorder byを書けるので、その時は、その順番で並び変えた後に計算するのではないか? (未確認
AggStepで集約の値を計算した後は、AggFinalで計算結果を出し、p1に格納し、その結果をいくつかのオペコードを組み合わせて返却し、最後はstringにして返して、Haltで完了です.

## TODO

whereを組み合わせた際だとOpenReadからRewind辺りのどこかにいくつかのオペコードが追加されるのかな？その辺は次回確認します.