penberg / limbo

Limbo is a work-in-progress, in-process OLTP database management system, compatible with SQLite.
MIT License
896 stars 49 forks source link

Adds group_concat and string_agg aggregate functions #134

Closed Ramkarthik closed 1 month ago

Ramkarthik commented 1 month ago

Implements the remaining aggregate functions part of #93: group_concat(x) group_concat(x, y) string_agg(x, y)

@penberg @pereman2 I'm fairly new to both Rust and database internals, so please do let me know if I need to change the solution approach (specifically the introduction of the delimiter param for the AggStep enum and assigning 0 for other aggregate operations).

opcodes

> explain select group_concat(name) from products;
addr  opcode             p1    p2    p3    p4             p5  comment
----  -----------------  ----  ----  ----  -------------  --  -------
0     Init               0     13    0                    0   Start at 13
1     OpenReadAsync      0     3     0                    0   root=3
2     OpenReadAwait      0     0     0                    0
3     RewindAsync        0     0     0                    0
4     RewindAwait        0     10    0                    0
5       Column           0     1     1                    0   r[1]= cursor 0 column 1
6       String8          2     0     0     ,              0   r[2]= ','
7       AggStep          0     1     0     group_concat   0   accum=r[0] step(1)
8     NextAsync          0     0     0                    0
9     NextAwait          0     4     0                    0
10    AggFinal           0     0     0     group_concat   0   accum=r[0]
11    ResultRow          0     1     0                    0   output=r[0..1]
12    Halt               0     0     0                    0
13    Transaction        0     0     0                    0
14    Goto               0     1     0                    0
> explain select group_concat(name, ',') from products;
addr  opcode             p1    p2    p3    p4             p5  comment
----  -----------------  ----  ----  ----  -------------  --  -------
0     Init               0     13    0                    0   Start at 13
1     OpenReadAsync      0     3     0                    0   root=3
2     OpenReadAwait      0     0     0                    0
3     RewindAsync        0     0     0                    0
4     RewindAwait        0     10    0                    0
5       Column           0     1     1                    0   r[1]= cursor 0 column 1
6       String8          2     0     0     ,              0   r[2]= ','
7       AggStep          0     1     0     group_concat   0   accum=r[0] step(1)
8     NextAsync          0     0     0                    0
9     NextAwait          0     4     0                    0
10    AggFinal           0     0     0     group_concat   0   accum=r[0]
11    ResultRow          0     1     0                    0   output=r[0..1]
12    Halt               0     0     0                    0
13    Transaction        0     0     0                    0
14    Goto               0     1     0                    0
> explain select group_concat(name, id) from products;
addr  opcode             p1    p2    p3    p4             p5  comment
----  -----------------  ----  ----  ----  -------------  --  -------
0     Init               0     13    0                    0   Start at 13
1     OpenReadAsync      0     3     0                    0   root=3
2     OpenReadAwait      0     0     0                    0
3     RewindAsync        0     0     0                    0
4     RewindAwait        0     10    0                    0
5       Column           0     1     1                    0   r[1]= cursor 0 column 1
6       RowId            0     2     0                    0
7       AggStep          0     1     0     group_concat   0   accum=r[0] step(1)
8     NextAsync          0     0     0                    0
9     NextAwait          0     4     0                    0
10    AggFinal           0     0     0     group_concat   0   accum=r[0]
11    ResultRow          0     1     0                    0   output=r[0..1]
12    Halt               0     0     0                    0
13    Transaction        0     0     0                    0
14    Goto               0     1     0                    0
> explain select string_agg(name, ',') from products;
addr  opcode             p1    p2    p3    p4             p5  comment
----  -----------------  ----  ----  ----  -------------  --  -------
0     Init               0     13    0                    0   Start at 13
1     OpenReadAsync      0     3     0                    0   root=3
2     OpenReadAwait      0     0     0                    0
3     RewindAsync        0     0     0                    0
4     RewindAwait        0     10    0                    0
5       Column           0     1     1                    0   r[1]= cursor 0 column 1
6       String8          2     0     0     ,              0   r[2]= ','
7       AggStep          0     1     0     string_agg     0   accum=r[0] step(1)
8     NextAsync          0     0     0                    0
9     NextAwait          0     4     0                    0
10    AggFinal           0     0     0     string_agg     0   accum=r[0]
11    ResultRow          0     1     0                    0   output=r[0..1]
12    Halt               0     0     0                    0
13    Transaction        0     0     0                    0
14    Goto               0     1     0                    0
> explain select string_agg(name, id) from products;
addr  opcode             p1    p2    p3    p4             p5  comment
----  -----------------  ----  ----  ----  -------------  --  -------
0     Init               0     13    0                    0   Start at 13
1     OpenReadAsync      0     3     0                    0   root=3
2     OpenReadAwait      0     0     0                    0
3     RewindAsync        0     0     0                    0
4     RewindAwait        0     10    0                    0
5       Column           0     1     1                    0   r[1]= cursor 0 column 1
6       RowId            0     2     0                    0
7       AggStep          0     1     0     string_agg     0   accum=r[0] step(1)
8     NextAsync          0     0     0                    0
9     NextAwait          0     4     0                    0
10    AggFinal           0     0     0     string_agg     0   accum=r[0]
11    ResultRow          0     1     0                    0   output=r[0..1]
12    Halt               0     0     0                    0
13    Transaction        0     0     0                    0
14    Goto               0     1     0                    0
penberg commented 1 month ago

Looks good to me, but let's give @pereman2 a chance to review this too

pereman2 commented 1 month ago

Looks good @Ramkarthik !