fix(sqlite): argument bind for sqlite is 1-indexed

fixes #467
This commit is contained in:
Ryan Leckey 2020-07-02 22:52:21 -07:00
parent 72700615c8
commit c7c46f237b
3 changed files with 39 additions and 5 deletions

View File

@ -55,7 +55,7 @@ impl SqliteArguments<'_> {
let mut arg_i = 0;
for handle in &statement.handles {
let cnt = handle.bind_parameter_count();
for param_i in 0..cnt {
for param_i in 1..=cnt {
// figure out the index of this bind parameter into our argument tuple
let n: usize = if let Some(name) = handle.bind_parameter_name(param_i) {
if name.starts_with('?') {
@ -77,7 +77,7 @@ impl SqliteArguments<'_> {
));
}
self.values[n - 1].bind(handle, param_i + 1)?;
self.values[n - 1].bind(handle, param_i)?;
}
}

View File

@ -142,6 +142,7 @@ impl StatementHandle {
}
// Name Of A Host Parameter
// NOTE: The first host parameter has an index of 1, not 0.
#[inline]
pub(crate) fn bind_parameter_name(&self, index: usize) -> Option<&str> {
unsafe {

View File

@ -1,7 +1,6 @@
use futures::TryStreamExt;
use sqlx::{
query, sqlite::Sqlite, Connect, Connection, Executor, Row, SqliteConnection, SqlitePool,
};
use sqlx::sqlite::{Sqlite, SqliteConnection, SqlitePool, SqliteRow};
use sqlx::{query, Connect, Connection, Executor, Row};
use sqlx_test::new;
#[sqlx_macros::test]
@ -75,6 +74,40 @@ async fn it_fetches_and_inflates_row() -> anyhow::Result<()> {
Ok(())
}
#[sqlx_macros::test]
async fn it_maths() -> anyhow::Result<()> {
let mut conn = new::<Sqlite>().await?;
let value = sqlx::query("select 1 + ?1")
.bind(5_i32)
.try_map(|row: SqliteRow| row.try_get::<i32, _>(0))
.fetch_one(&mut conn)
.await?;
assert_eq!(6i32, value);
Ok(())
}
#[sqlx_macros::test]
async fn it_binds_positional_parameters_issue_467() -> anyhow::Result<()> {
let mut conn = new::<Sqlite>().await?;
let row: (i32, i32, i32, i32) = sqlx::query_as("select ?1, ?1, ?3, ?2")
.bind(5_i32)
.bind(500_i32)
.bind(1020_i32)
.fetch_one(&mut conn)
.await?;
assert_eq!(row.0, 5);
assert_eq!(row.1, 5);
assert_eq!(row.2, 1020);
assert_eq!(row.3, 500);
Ok(())
}
#[sqlx_macros::test]
async fn it_fetches_in_loop() -> anyhow::Result<()> {
// this is trying to check for any data races