-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
[SQLite] INSERT ... RETURNING ... with a REAL column reports a type error in some cases #1596
Comments
Reduced testcase. Create a db with
and test with use sqlx::sqlite::SqlitePoolOptions;
use sqlx::Executor;
use sqlx::Row;
use sqlx::SqlitePool;
#[tokio::main]
async fn main() -> Result<(), sqlx::Error> {
let v: f64 = 5.0;
let pool: SqlitePool = SqlitePoolOptions::new()
.connect("sqlite://foobar.db?mode=rw")
.await?;
let insert_query = format!("INSERT INTO foo(bar) VALUES ({}) RETURNING *", v);
let insert_query = sqlx::query(&insert_query);
let row = pool.fetch_one(insert_query).await?;
assert_eq!(row.get::<f64, _>(0), v);
Ok(())
} Works with 5.1, crashes with 5.0. |
There's a confounding issue here, being in That's a known issue already, #1408. The actual problem is likely that SQLite is storing the value as an integer since it doesn't have a fractional value, and when we ask it the type of the value it tells us that it's an integer and not a floating point. However, what's strange is that the SQLite docs suggest that this shouldn't happen with a column using the
|
Oh, I think it might be a database bug! If you insert the value and select it back in separate statements, it works as expected. This test completes normally: conn.execute("CREATE TABLE foo(bar REAL)").await?;
conn.execute("INSERT INTO foo(bar) VALUES(5.0)").await?;
let (bar,): (f64,) = sqlx::query_as("SELECT * FROM foo").fetch_one(&mut conn).await?;
assert_eq!(bar, 5.0); It's only when you do // error occurred while decoding column 0: mismatched types; Rust type `f64` (as SQL type `REAL`) is not compatible with SQL type `INTEGER`
let (bar,): (f64,) = sqlx::query_as("INSERT INTO foo(bar) VALUES (5.0) RETURNING *")
.fetch_one(&mut conn)
.await?;
assert_eq!(bar, 5.0); |
Submitted a bug report on the SQLite forum: https://www.sqlite.org/forum/forumpost/e0c7574ab2 |
@abonander Thank you so much for following up on this! |
It is. You can see it using the SQLite CLI by entering the following SQL:
You get back "5" instead of "5.0" as you should. The problem should be fixed now at |
Incredible turnaround, thank you! |
Closed by #1763 |
I have hit the following backtrace while calling
row.get<f64, _>
on anAnyRow
over the results of a SQLite query:The query is an
INSERT INTO
with aRETURNING
clause and the sqlite table has the following schema:What makes me quite certain that this is a bug is that everything works well if
height
is5.11
but it fails if it is5
.I confirmed that in the sqlite shell, the values do show up as
5.0
and therefore a real.I can call
try_get_unchecked
and convert to a string, and then I see that the string is printed as "5" (without the dot)The text was updated successfully, but these errors were encountered: