diff --git a/tests/mod.rs b/tests/mod.rs index e0c0b99a..eca6edb1 100644 --- a/tests/mod.rs +++ b/tests/mod.rs @@ -7,6 +7,7 @@ mod data_formats; mod errors; mod exec; mod oidc; +mod parameter_binding; mod requests; mod server_timing; pub mod sql_test_files; diff --git a/tests/parameter_binding/echo_parameter.sql b/tests/parameter_binding/echo_parameter.sql new file mode 100644 index 00000000..157fa943 --- /dev/null +++ b/tests/parameter_binding/echo_parameter.sql @@ -0,0 +1 @@ +select 'text' as component, max(n) as contents from (select $x as n) as t; diff --git a/tests/parameter_binding/mod.rs b/tests/parameter_binding/mod.rs new file mode 100644 index 00000000..5fe31a4d --- /dev/null +++ b/tests/parameter_binding/mod.rs @@ -0,0 +1,40 @@ +use actix_web::{http::StatusCode, test}; +use sqlx::any::AnyKind; +use sqlx::connection::Connection as _; + +use sqlpage::webserver::http::main_handler; + +use crate::common::{get_request_to_with_data, make_app_data}; + +#[actix_web::test] +async fn test_parameterized_pages_leave_a_prepared_statement_in_the_cache() -> actix_web::Result<()> +{ + let data = make_app_data().await; + if data.db.info.kind == AnyKind::Mssql { + return Ok(()); // the MSSQL backend keeps no statement cache + } + + for _ in 0..3 { + let req = get_request_to_with_data( + "/tests/parameter_binding/echo_parameter.sql?x=1447", + data.clone(), + ) + .await? + .to_srv_request(); + let resp = main_handler(req).await?; + assert_eq!(resp.status(), StatusCode::OK); + let page = String::from_utf8(test::read_body(resp).await.to_vec()).unwrap(); + assert!( + page.contains("1447"), + "{page}\nexpected the bound parameter to reach the query" + ); + } + + let connection = data.db.connection.acquire().await.unwrap(); + assert!( + connection.cached_statements_size() > 0, + "{:?} ran a parameterized query three times without caching a prepared statement", + data.db.info.kind + ); + Ok(()) +} diff --git a/tests/sql_test_files/data/parameter_bound_twice_in_a_projection.sql b/tests/sql_test_files/data/parameter_bound_twice_in_a_projection.sql new file mode 100644 index 00000000..66d458ea --- /dev/null +++ b/tests/sql_test_files/data/parameter_bound_twice_in_a_projection.sql @@ -0,0 +1,9 @@ +-- One variable bound twice in a single statement, in the projection rather than +-- only in the predicate. https://github.com/sqlpage/SQLPage/issues/1474 +drop table if exists parameter_bound_twice_t; +create table parameter_bound_twice_t(id int primary key); +insert into parameter_bound_twice_t (id) values (1); + +select 'It works !' as expected, + case when $x is not null and $x = '1' then 'It works !' else 'fail' end as actual +from parameter_bound_twice_t;