From c7c46f237bc9436547587da7b88005f0febef321 Mon Sep 17 00:00:00 2001 From: Ryan Leckey Date: Thu, 2 Jul 2020 22:52:21 -0700 Subject: [PATCH] fix(sqlite): argument bind for sqlite is 1-indexed fixes #467 --- sqlx-core/src/sqlite/arguments.rs | 4 +-- sqlx-core/src/sqlite/statement/handle.rs | 1 + tests/sqlite/sqlite.rs | 39 ++++++++++++++++++++++-- 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/sqlx-core/src/sqlite/arguments.rs b/sqlx-core/src/sqlite/arguments.rs index 7ae9b6fe..cff26143 100644 --- a/sqlx-core/src/sqlite/arguments.rs +++ b/sqlx-core/src/sqlite/arguments.rs @@ -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)?; } } diff --git a/sqlx-core/src/sqlite/statement/handle.rs b/sqlx-core/src/sqlite/statement/handle.rs index 99edc352..c4f9325e 100644 --- a/sqlx-core/src/sqlite/statement/handle.rs +++ b/sqlx-core/src/sqlite/statement/handle.rs @@ -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 { diff --git a/tests/sqlite/sqlite.rs b/tests/sqlite/sqlite.rs index 35db78de..3a2cf453 100644 --- a/tests/sqlite/sqlite.rs +++ b/tests/sqlite/sqlite.rs @@ -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::().await?; + + let value = sqlx::query("select 1 + ?1") + .bind(5_i32) + .try_map(|row: SqliteRow| row.try_get::(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::().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