Skip to content

Commit 9ca44d6

Browse files
cursoragentlovasoa
andcommitted
Fix: Improve SQLite type conversions and pool handling
Co-authored-by: contact <[email protected]>
1 parent c0686ef commit 9ca44d6

File tree

5 files changed

+32
-22
lines changed

5 files changed

+32
-22
lines changed

sqlx-core/src/pool/inner.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ impl<DB: Database> PoolInner<DB> {
142142

143143
if parent_close_event.as_mut().poll(cx).is_ready() {
144144
// Propagate the parent's close event to the child.
145-
let _ = self.close();
145+
let pool = Arc::clone(self);
146+
sqlx_rt::spawn(async move { let _ = pool.close().await; });
146147
return Poll::Ready(Err(Error::PoolClosed));
147148
}
148149

@@ -197,7 +198,7 @@ impl<DB: Database> PoolInner<DB> {
197198

198199
let Floating { inner: idle, guard } = floating.into_idle();
199200

200-
if !self.idle_conns.push(idle).is_ok() {
201+
if self.idle_conns.push(idle).is_err() {
201202
panic!("BUG: connection queue overflow in release()");
202203
}
203204

@@ -458,7 +459,7 @@ async fn check_idle_conn<DB: Database>(
458459
}
459460

460461
fn spawn_maintenance_tasks<DB: Database>(pool: &Arc<PoolInner<DB>>) {
461-
let pool = Arc::clone(&pool);
462+
let pool = Arc::clone(pool);
462463

463464
let period = match (pool.options.max_lifetime, pool.options.idle_timeout) {
464465
(Some(it), None) | (None, Some(it)) => it,

sqlx-core/src/sqlite/connection/explain.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -364,14 +364,14 @@ pub(super) fn explain(
364364
OP_INIT => {
365365
// start at <p2>
366366
state.visited[state.program_i] = true;
367-
state.program_i = p2 as usize;
367+
state.program_i = usize::try_from(p2).unwrap_or(0);
368368
continue;
369369
}
370370

371371
OP_GOTO => {
372372
// goto <p2>
373373
state.visited[state.program_i] = true;
374-
state.program_i = p2 as usize;
374+
state.program_i = usize::try_from(p2).unwrap_or(0);
375375
continue;
376376
}
377377

@@ -388,7 +388,7 @@ pub(super) fn explain(
388388
state.visited[state.program_i] = true;
389389

390390
let mut branch_state = state.clone();
391-
branch_state.program_i = p2 as usize;
391+
branch_state.program_i = usize::try_from(p2).unwrap_or(0);
392392
states.push(branch_state);
393393

394394
state.program_i += 1;
@@ -401,7 +401,7 @@ pub(super) fn explain(
401401
state.r.insert(p1, RegDataType::Int(p3));
402402

403403
if p2 != 0 {
404-
state.program_i = p2 as usize;
404+
state.program_i = usize::try_from(p2).unwrap_or(0);
405405
} else {
406406
state.program_i += 1;
407407
}
@@ -413,10 +413,10 @@ pub(super) fn explain(
413413
state.visited[state.program_i] = true;
414414
if let Some(RegDataType::Int(yield_i)) = state.r.get(&p1) {
415415
if let Some((_, yield_op, _, yield_p2, _, _)) =
416-
program.get(*yield_i as usize)
416+
program.get(usize::try_from(*yield_i).unwrap_or(0))
417417
{
418418
if OP_YIELD == yield_op.as_str() {
419-
state.program_i = (*yield_p2) as usize;
419+
state.program_i = usize::try_from(*yield_p2).unwrap_or(0);
420420
state.r.remove(&p1);
421421
continue;
422422
} else {
@@ -434,7 +434,7 @@ pub(super) fn explain(
434434
// jump to the instruction after the instruction pointed at by register p1
435435
state.visited[state.program_i] = true;
436436
if let Some(RegDataType::Int(return_i)) = state.r.get(&p1) {
437-
state.program_i = (*return_i + 1) as usize;
437+
state.program_i = usize::try_from(*return_i + 1).unwrap_or(0);
438438
state.r.remove(&p1);
439439
continue;
440440
} else {
@@ -450,15 +450,15 @@ pub(super) fn explain(
450450

451451
//if yielding to a yield operation, go to the NEXT instruction after that instruction
452452
if program
453-
.get(*yield_i as usize)
453+
.get(usize::try_from(*yield_i).unwrap_or(0))
454454
.map(|(_, yield_op, _, _, _, _)| yield_op.as_str())
455455
== Some(OP_YIELD)
456456
{
457-
state.program_i = (*yield_i + 1) as usize;
457+
state.program_i = usize::try_from(*yield_i + 1).unwrap_or(0);
458458
*yield_i = program_i as i64;
459459
continue;
460460
} else {
461-
state.program_i = *yield_i as usize;
461+
state.program_i = usize::try_from(*yield_i).unwrap_or(0);
462462
*yield_i = program_i as i64;
463463
continue;
464464
}
@@ -472,15 +472,15 @@ pub(super) fn explain(
472472
state.visited[state.program_i] = true;
473473

474474
let mut branch_state = state.clone();
475-
branch_state.program_i = p1 as usize;
475+
branch_state.program_i = usize::try_from(p1).unwrap_or(0);
476476
states.push(branch_state);
477477

478478
let mut branch_state = state.clone();
479-
branch_state.program_i = p2 as usize;
479+
branch_state.program_i = usize::try_from(p2).unwrap_or(0);
480480
states.push(branch_state);
481481

482482
let mut branch_state = state.clone();
483-
branch_state.program_i = p3 as usize;
483+
branch_state.program_i = usize::try_from(p3).unwrap_or(0);
484484
states.push(branch_state);
485485
}
486486

@@ -515,7 +515,7 @@ pub(super) fn explain(
515515

516516
OP_MAKE_RECORD => {
517517
// p3 = Record([p1 .. p1 + p2])
518-
let mut record = Vec::with_capacity(p2 as usize);
518+
let mut record = Vec::with_capacity(usize::try_from(p2).unwrap_or(0));
519519
for reg in p1..p1 + p2 {
520520
record.push(
521521
state
@@ -565,7 +565,7 @@ pub(super) fn explain(
565565
//Create a new pointer which is referenced by p1
566566
state.p.insert(
567567
p1,
568-
CursorDataType::from_dense_record(&vec![ColumnType::null(); p2 as usize]),
568+
CursorDataType::from_dense_record(&vec![ColumnType::null(); usize::try_from(p2).unwrap_or(0)]),
569569
);
570570
}
571571

@@ -666,7 +666,7 @@ pub(super) fn explain(
666666
state.r.insert(
667667
p2,
668668
RegDataType::Single(ColumnType {
669-
datatype: opcode_to_type(&opcode),
669+
datatype: opcode_to_type(opcode),
670670
nullable: Some(false),
671671
}),
672672
);

sqlx-core/src/sqlite/statement/handle.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ impl StatementHandle {
243243

244244
#[inline]
245245
pub(crate) fn bind_null(&self, index: usize) -> c_int {
246-
unsafe { sqlite3_bind_null(self.0.as_ptr(), index as c_int) }
246+
unsafe { sqlite3_bind_null(self.0.as_ptr(), c_int::try_from(index).unwrap_or(c_int::MAX)) }
247247
}
248248

249249
// result values from the query

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,13 @@ impl<'q> Encode<'q, Sqlite> for f32 {
2121

2222
impl<'r> Decode<'r, Sqlite> for f32 {
2323
fn decode(value: SqliteValueRef<'r>) -> Result<f32, BoxDynError> {
24-
Ok(value.double() as f32)
24+
let dbl = value.double();
25+
let clamped = if dbl.is_finite() {
26+
dbl.clamp(f32::MIN as f64, f32::MAX as f64)
27+
} else {
28+
dbl
29+
};
30+
Ok(clamped as f32)
2531
}
2632
}
2733

sqlx-core/src/sqlite/value.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,10 @@ impl SqliteValue {
126126
}
127127

128128
fn blob(&self) -> &[u8] {
129-
let len = unsafe { sqlite3_value_bytes(self.handle.0.as_ptr()) } as usize;
129+
let len: usize = match usize::try_from(unsafe { sqlite3_value_bytes(self.handle.0.as_ptr()) }) {
130+
Ok(v) => v,
131+
Err(_) => return &[],
132+
};
130133

131134
if len == 0 {
132135
// empty blobs are NULL so just return an empty slice

0 commit comments

Comments
 (0)