Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compiler hangs when using SQLite, query_as! and GROUP BY #981

Closed
Rigellute opened this issue Jan 13, 2021 · 2 comments · Fixed by #1002
Closed

Compiler hangs when using SQLite, query_as! and GROUP BY #981

Rigellute opened this issue Jan 13, 2021 · 2 comments · Fixed by #1002
Labels
bug db:sqlite Related to SQLite

Comments

@Rigellute
Copy link

On macOS.

$ sqlite3 --version
3.32.3 2020-06-18 14:16:19 

$ rustc --version
rustc 1.49.0 (e1884a8e3 2020-12-29)

Reproduction

# Create the db on the cli
sqlite3 parts.db "create table parts (Document TEXT)"
# .env
DATABASE_URL=sqlite:parts.db
# Cargo.toml
[dependencies]
sqlx = { version = "0.4", features = [ "sqlite", "runtime-async-std-rustls"  ] }
async-std = { version = "1.6", features = [ "attributes" ] }
// src/main.rs
use sqlx::sqlite::SqlitePool;
use std::env;

struct Document {
    name: Option<String>,
}

#[async_std::main]
async fn main() -> Result<(), sqlx::Error> {
    let connection_string = env::var("DATABASE_URL").unwrap();

    let db_pool = SqlitePool::connect(&connection_string).await.unwrap();

    let _result = sqlx::query_as!(
        Document,
        "
SELECT Document AS name
FROM parts
GROUP BY name
        ",
    )
    .fetch_all(&db_pool)
    .await;

    Ok(())
}

Try running.

$ cargo run
   Compiling sqlx-test v0.1.0 (/Users/me/Dev/Rust/sqlx-test)
   Building [=====================================================> ] 189/190: sqlx-test(bin)

# It gets stuck here and never finishes.

Observations

Removing the GROUP BY allows the program to compile.

Another observation is that this works

SELECT DISTINCT Document AS name
FROM parts

But then adding an ORDER BY causes the never ending compile again.

SELECT DISTINCT Document AS name
FROM parts
ORDER BY Document

When the compiler stalls, I am still able to interact with my sqlite3 db (make queries etc.).

@mehcode
Copy link
Member

mehcode commented Jan 13, 2021

Can you run the following (in the sqlite3 cli):

EXPLAIN
SELECT DISTINCT Document AS name
FROM parts
ORDER BY Document
EXPLAIN
SELECT Document AS name
FROM parts
GROUP BY name

@mehcode mehcode added bug db:sqlite Related to SQLite labels Jan 13, 2021
@Rigellute
Copy link
Author

Sure @mehcode

❯ sqlite3 parts.db "EXPLAIN SELECT DISTINCT Document AS name FROM parts ORDER BY Document"

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

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug db:sqlite Related to SQLite
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants