Skip to content

Commit ff0252d

Browse files
authored
sqlite: fix inconsistent read-after-write (#3354)
* sqlite: fix inconsistent read-after-write fetch_one/fetch_optional * try pushing fetch_optional early-return into worker * run cargo fmt * fix "it_can_execute_multiple_statements" test failure * use Option<usize> instead of bespoke enum for rows returned
1 parent 572e2a4 commit ff0252d

File tree

3 files changed

+36
-8
lines changed

3 files changed

+36
-8
lines changed

sqlx-sqlite/src/any.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ impl AnyConnectionBackend for SqliteConnection {
8383

8484
Box::pin(
8585
self.worker
86-
.execute(query, args, self.row_channel_size, persistent)
86+
.execute(query, args, self.row_channel_size, persistent, None)
8787
.map_ok(flume::Receiver::into_stream)
8888
.try_flatten_stream()
8989
.map(
@@ -107,7 +107,7 @@ impl AnyConnectionBackend for SqliteConnection {
107107
Box::pin(async move {
108108
let stream = self
109109
.worker
110-
.execute(query, args, self.row_channel_size, persistent)
110+
.execute(query, args, self.row_channel_size, persistent, Some(1))
111111
.map_ok(flume::Receiver::into_stream)
112112
.await?;
113113
futures_util::pin_mut!(stream);

sqlx-sqlite/src/connection/executor.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ impl<'c> Executor<'c> for &'c mut SqliteConnection {
3232

3333
Box::pin(
3434
self.worker
35-
.execute(sql, arguments, self.row_channel_size, persistent)
35+
.execute(sql, arguments, self.row_channel_size, persistent, None)
3636
.map_ok(flume::Receiver::into_stream)
3737
.try_flatten_stream(),
3838
)
@@ -58,7 +58,7 @@ impl<'c> Executor<'c> for &'c mut SqliteConnection {
5858
Box::pin(async move {
5959
let stream = self
6060
.worker
61-
.execute(sql, arguments, self.row_channel_size, persistent)
61+
.execute(sql, arguments, self.row_channel_size, persistent, Some(1))
6262
.map_ok(flume::Receiver::into_stream)
6363
.try_flatten_stream();
6464

sqlx-sqlite/src/connection/worker.rs

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ enum Command {
5252
arguments: Option<SqliteArguments<'static>>,
5353
persistent: bool,
5454
tx: flume::Sender<Result<Either<SqliteQueryResult, SqliteRow>, Error>>,
55+
limit: Option<usize>,
5556
},
5657
Begin {
5758
tx: rendezvous_oneshot::Sender<Result<(), Error>>,
@@ -136,6 +137,7 @@ impl ConnectionWorker {
136137
arguments,
137138
persistent,
138139
tx,
140+
limit
139141
} => {
140142
let iter = match execute::iter(&mut conn, &query, arguments, persistent)
141143
{
@@ -146,10 +148,34 @@ impl ConnectionWorker {
146148
}
147149
};
148150

149-
for res in iter {
150-
if tx.send(res).is_err() {
151-
break;
152-
}
151+
match limit {
152+
None => {
153+
for res in iter {
154+
if tx.send(res).is_err() {
155+
break;
156+
}
157+
}
158+
},
159+
Some(limit) => {
160+
let mut iter = iter;
161+
let mut rows_returned = 0;
162+
163+
while let Some(res) = iter.next() {
164+
if let Ok(ok) = &res {
165+
if ok.is_right() {
166+
rows_returned += 1;
167+
if rows_returned >= limit {
168+
drop(iter);
169+
let _ = tx.send(res);
170+
break;
171+
}
172+
}
173+
}
174+
if tx.send(res).is_err() {
175+
break;
176+
}
177+
}
178+
},
153179
}
154180

155181
update_cached_statements_size(&conn, &shared.cached_statements_size);
@@ -284,6 +310,7 @@ impl ConnectionWorker {
284310
args: Option<SqliteArguments<'_>>,
285311
chan_size: usize,
286312
persistent: bool,
313+
limit: Option<usize>,
287314
) -> Result<flume::Receiver<Result<Either<SqliteQueryResult, SqliteRow>, Error>>, Error> {
288315
let (tx, rx) = flume::bounded(chan_size);
289316

@@ -294,6 +321,7 @@ impl ConnectionWorker {
294321
arguments: args.map(SqliteArguments::into_static),
295322
persistent,
296323
tx,
324+
limit,
297325
},
298326
Span::current(),
299327
))

0 commit comments

Comments
 (0)