Skip to content

Commit 5fd1c75

Browse files
committed
Handle longer packets
mysql_common used to ignore `max_allowed_packet`, so we got away with it (erroneously) being set to a low value. We now set a larger value, and also do power-of-two growth of the read buffer.
1 parent 2673352 commit 5fd1c75

File tree

5 files changed

+35
-4
lines changed

5 files changed

+35
-4
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "msql-srv"
3-
version = "0.8.6"
3+
version = "0.8.7"
44
edition = "2018"
55

66
description = "Bindings for emulating a MySQL/MariaDB server"

src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,11 +281,11 @@ impl<B: MysqlShim<W>, R: Read, W: Write> MysqlIntermediary<B, R, W> {
281281
let cols = &[Column {
282282
table: String::new(),
283283
column: "@@max_allowed_packet".to_owned(),
284-
coltype: myc::constants::ColumnType::MYSQL_TYPE_SHORT,
284+
coltype: myc::constants::ColumnType::MYSQL_TYPE_LONG,
285285
colflags: myc::constants::ColumnFlags::UNSIGNED_FLAG,
286286
}];
287287
let mut w = w.start(cols)?;
288-
w.write_row(iter::once(1024u16))?;
288+
w.write_row(iter::once(67108864u32))?;
289289
w.finish()?;
290290
}
291291
_ => {

src/packet.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ impl<R: Read> PacketReader<R> {
113113
self.bytes.drain(0..self.start);
114114
self.start = 0;
115115
let end = self.bytes.len();
116-
self.bytes.resize(end + 1024, 0);
116+
self.bytes.resize(std::cmp::max(4096, end * 2), 0);
117117
let read = {
118118
let mut buf = &mut self.bytes[end..];
119119
self.r.read(&mut buf)?

tests/async.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,20 @@ fn no_columns_but_rows() {
205205
})
206206
}
207207

208+
#[test]
209+
fn really_long_query() {
210+
let long = "CREATE TABLE `stories` (`id` int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY, `always_null` int, `created_at` datetime, `user_id` int unsigned, `url` varchar(250) DEFAULT '', `title` varchar(150) DEFAULT '' NOT NULL, `description` mediumtext, `short_id` varchar(6) DEFAULT '' NOT NULL, `is_expired` tinyint(1) DEFAULT 0 NOT NULL, `is_moderated` tinyint(1) DEFAULT 0 NOT NULL, `markeddown_description` mediumtext, `story_cache` mediumtext, `merged_story_id` int, `unavailable_at` datetime, `twitter_id` varchar(20), `user_is_author` tinyint(1) DEFAULT 0, INDEX `index_stories_on_created_at` (`created_at`), fulltext INDEX `index_stories_on_description` (`description`), INDEX `is_idxes` (`is_expired`, `is_moderated`), INDEX `index_stories_on_is_expired` (`is_expired`), INDEX `index_stories_on_is_moderated` (`is_moderated`), INDEX `index_stories_on_merged_story_id` (`merged_story_id`), UNIQUE INDEX `unique_short_id` (`short_id`), fulltext INDEX `index_stories_on_story_cache` (`story_cache`), fulltext INDEX `index_stories_on_title` (`title`), INDEX `index_stories_on_twitter_id` (`twitter_id`), INDEX `url` (`url`(191)), INDEX `index_stories_on_user_id` (`user_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";
211+
TestingShim::new(
212+
move |q, w| {
213+
assert_eq!(q, long);
214+
w.start(&[])?.write_col(42).map(|_| ())
215+
},
216+
|_| unreachable!(),
217+
|_, _, _| unreachable!(),
218+
)
219+
.test(move |db| db.drop_query(long).map(|_| ()))
220+
}
221+
208222
#[test]
209223
fn error_response() {
210224
let err = (ErrorKind::ER_NO, "clearly not");

tests/main.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -866,3 +866,20 @@ fn prepared_no_cols() {
866866
assert_eq!(db.prep_exec("SELECT a, b FROM foo", ()).unwrap().count(), 0);
867867
})
868868
}
869+
870+
#[test]
871+
fn really_long_query() {
872+
let long = "CREATE TABLE `stories` (`id` int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY, `always_null` int, `created_at` datetime, `user_id` int unsigned, `url` varchar(250) DEFAULT '', `title` varchar(150) DEFAULT '' NOT NULL, `description` mediumtext, `short_id` varchar(6) DEFAULT '' NOT NULL, `is_expired` tinyint(1) DEFAULT 0 NOT NULL, `is_moderated` tinyint(1) DEFAULT 0 NOT NULL, `markeddown_description` mediumtext, `story_cache` mediumtext, `merged_story_id` int, `unavailable_at` datetime, `twitter_id` varchar(20), `user_is_author` tinyint(1) DEFAULT 0, INDEX `index_stories_on_created_at` (`created_at`), fulltext INDEX `index_stories_on_description` (`description`), INDEX `is_idxes` (`is_expired`, `is_moderated`), INDEX `index_stories_on_is_expired` (`is_expired`), INDEX `index_stories_on_is_moderated` (`is_moderated`), INDEX `index_stories_on_merged_story_id` (`merged_story_id`), UNIQUE INDEX `unique_short_id` (`short_id`), fulltext INDEX `index_stories_on_story_cache` (`story_cache`), fulltext INDEX `index_stories_on_title` (`title`), INDEX `index_stories_on_twitter_id` (`twitter_id`), INDEX `url` (`url`(191)), INDEX `index_stories_on_user_id` (`user_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";
873+
TestingShim::new(
874+
move |q, w| {
875+
assert_eq!(q, long);
876+
w.start(&[])?.finish()
877+
},
878+
|_| 0,
879+
|_, _, _| unreachable!(),
880+
|_, _| unreachable!(),
881+
)
882+
.test(move |db| {
883+
db.query(long).unwrap();
884+
})
885+
}

0 commit comments

Comments
 (0)