Skip to content

Commit bbefc33

Browse files
committed
disallow wrapping conversions for mssql
1 parent d3faa99 commit bbefc33

File tree

7 files changed

+18
-10
lines changed

7 files changed

+18
-10
lines changed

sqlx-core/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#![recursion_limit = "512"]
44
#![warn(future_incompatible, rust_2018_idioms)]
55
#![allow(clippy::needless_doctest_main, clippy::type_complexity, dead_code)]
6+
#![deny(cast_possible_truncation, cast_possible_wrap, cast_precision_loss, cast_sign_loss)]
67
// See `clippy.toml` at the workspace root
78
#![deny(clippy::disallowed_methods)]
89
//

sqlx-core/src/mssql/types/float.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ impl Decode<'_, Mssql> for f64 {
7979
}
8080
}
8181
}
82+
83+
#[allow(clippy::cast_precision_loss)]
8284
fn decode_numeric(bytes: &[u8], _precision: u8, mut scale: u8) -> Result<f64, BoxDynError> {
8385
let sign = if bytes[0] == 0 { -1. } else { 1. };
8486
let rest = &bytes[1..];

sqlx-core/src/mssql/types/int.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ impl Encode<'_, Mssql> for i8 {
2727

2828
impl Decode<'_, Mssql> for i8 {
2929
fn decode(value: MssqlValueRef<'_>) -> Result<Self, BoxDynError> {
30-
Ok(value.as_bytes()?[0] as i8)
30+
Ok(i8::from_le_bytes(value.as_bytes()?[0..1].try_into()?))
3131
}
3232
}
3333

sqlx-core/src/mssql/types/str.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,11 @@ impl Type<Mssql> for String {
3838
impl Encode<'_, Mssql> for &'_ str {
3939
fn produces(&self) -> Option<MssqlTypeInfo> {
4040
let len = self.len().checked_mul(2)?;
41-
let size = if len <= 4000 {
41+
let size = if len <= 2 {
42+
2
43+
} else if len <= 4000 {
4244
// an empty string needs to be encoded as `nvarchar(2)`
43-
(len as u32).max(2)
45+
u32::try_from(len).unwrap()
4446
} else {
4547
0xFF_FF
4648
};

src/macros/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,12 @@
4949
/// below.
5050
///
5151
/// * The query must be a string literal, or concatenation of string literals using `+` (useful
52-
/// for queries generated by macro), or else it cannot be introspected (and thus cannot be dynamic
53-
/// or the result of another macro).
52+
/// for queries generated by macro), or else it cannot be introspected (and thus cannot be dynamic
53+
/// or the result of another macro).
5454
///
5555
/// * The `QueryAs` instance will be bound to the same database type as `query!()` was compiled
56-
/// against (e.g. you cannot build against a Postgres database and then run the query against
57-
/// a MySQL database).
56+
/// against (e.g. you cannot build against a Postgres database and then run the query against
57+
/// a MySQL database).
5858
///
5959
/// * The schema of the database URL (e.g. `postgres://` or `mysql://`) will be used to
6060
/// determine the database type.
@@ -415,7 +415,7 @@ macro_rules! query_file_unchecked (
415415
/// * The query must output at least one column.
416416
/// * The column names of the query must match the field names of the struct.
417417
/// * The field types must be the Rust equivalent of their SQL counterparts; see the corresponding
418-
/// module for your database for mappings:
418+
/// module for your database for mappings:
419419
/// * Postgres: [crate::postgres::types]
420420
/// * MySQL: [crate::mysql::types]
421421
/// * SQLite: [crate::sqlite::types]

tests/mssql/macros.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#[allow(unused_imports)]
12
use sqlx_oldapi as sqlx;
23
use sqlx_oldapi::Mssql;
34
use sqlx_test::new;

tests/mssql/types.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use core::f32;
2+
13
use sqlx_oldapi::mssql::Mssql;
24
use sqlx_test::test_type;
35

@@ -43,7 +45,7 @@ test_type!(i64(Mssql, "CAST(32324324432 AS BIGINT)" == 32324324432_i64));
4345

4446
test_type!(f32(
4547
Mssql,
46-
"CAST(3.1410000324249268 AS REAL)" == 3.141f32 as f64 as f32
48+
"CAST(3.14159265358979323846264338327950288 AS REAL)" == f32::consts::PI
4749
));
4850

4951
test_type!(f64(
@@ -70,7 +72,7 @@ test_type!(numeric<f64>(Mssql,
7072
"CAST(1.0000000000000001 AS NUMERIC(18,16))" == 1.0000000000000001_f64,
7173
"CAST(0.99999999999999 AS NUMERIC(18,14))" == 0.99999999999999_f64,
7274
"CAST(2.00000000000001 AS NUMERIC(18,14))" == 2.00000000000001_f64,
73-
"CAST(333.33333333333333 AS NUMERIC(18,14))" == 333.33333333333333_f64,
75+
"CAST(333.33333333333333 AS NUMERIC(18,14))" == 333.333_333_333_333_3_f64,
7476
"CAST(0.14285714285714 AS NUMERIC(18,14))" == 0.14285714285714_f64,
7577
"CAST(9999999.99999999 AS NUMERIC(16,8))" == 9999999.99999999_f64, // Close to the precision limit
7678
"CAST(9007199254740992 AS NUMERIC(16,0))" == 9007199254740992_f64, // 2^53, largest integer that can be exactly represented as a f64

0 commit comments

Comments
 (0)