Skip to content

Commit 668a877

Browse files
authored
fix parameter binding order (#825)
* use numbered parameters in sqlite * implement parameter deduplication * implement parameter re-duplication for mysql * Improve error messages on invalid sqlpage function calls. The messages now contain actionable advice. * simplify extract_set_variable
1 parent 0041cb0 commit 668a877

File tree

4 files changed

+290
-95
lines changed

4 files changed

+290
-95
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66
- Fix a bug with date sorting in the table component.
77
- Center table descriptions.
88
- Fix a rare crash on startup in some restricted linux environments.
9+
- Fix a rare but serious issue when on SQLite and MySQL, some variable values were assigned incorrectly
10+
- `CASE WHEN $a THEN $x WHEN $b THEN $y` would be executed as `CASE WHEN $a THEN $b WHEN $x THEN $y` on these databases.
11+
- the issue only occured when using in case expressions where variables were used both in conditions and results.
12+
- Implement parameter deduplication.
13+
Now, when you write `select $x where $x is not null`, the value of `$x` is sent to the database only once. It used to be sent as many times as `$x` appeared in the statement.
14+
- Improve error messages on invalid sqlpage function calls. The messages now contain actionable advice.
915

1016
## 0.33.0 (2025-02-15)
1117

src/webserver/database/mod.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ mod syntax_tree;
99
mod error_highlighting;
1010
mod sql_to_json;
1111

12-
pub use sql::{make_placeholder, ParsedSqlFile};
12+
pub use sql::ParsedSqlFile;
13+
use sql::{DbPlaceHolder, DB_PLACEHOLDERS};
14+
use sqlx::any::AnyKind;
1315

1416
pub struct Database {
1517
pub connection: sqlx::AnyPool,
@@ -34,3 +36,16 @@ impl std::fmt::Display for Database {
3436
write!(f, "{:?}", self.connection.any_kind())
3537
}
3638
}
39+
40+
#[inline]
41+
#[must_use]
42+
pub fn make_placeholder(db_kind: AnyKind, arg_number: usize) -> String {
43+
if let Some((_, placeholder)) = DB_PLACEHOLDERS.iter().find(|(kind, _)| *kind == db_kind) {
44+
match *placeholder {
45+
DbPlaceHolder::PrefixedNumber { prefix } => format!("{prefix}{arg_number}"),
46+
DbPlaceHolder::Positional { placeholder } => placeholder.to_string(),
47+
}
48+
} else {
49+
unreachable!("missing db_kind: {db_kind:?} in DB_PLACEHOLDERS ({DB_PLACEHOLDERS:?})")
50+
}
51+
}

0 commit comments

Comments
 (0)