Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 29a476e

Browse filesBrowse files
authored
QueryRouter: route to primary when locks exists (select for update) (#782)
Authored-by: Javier Goday <jgoday@gmail.com>
1 parent 81933b9 commit 29a476e
Copy full SHA for 29a476e

File tree

Expand file treeCollapse file tree

1 file changed

+29
-2
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+29
-2
lines changed

‎src/query_router.rs

Copy file name to clipboardExpand all lines: src/query_router.rs
+29-2Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -427,8 +427,12 @@ impl QueryRouter {
427427
None => (),
428428
};
429429

430-
// If we already visited a write statement, we should be going to the primary.
431-
if !visited_write_statement {
430+
let has_locks = !query.locks.is_empty();
431+
432+
if has_locks {
433+
self.active_role = Some(Role::Primary);
434+
} else if !visited_write_statement {
435+
// If we already visited a write statement, we should be going to the primary.
432436
self.active_role = match self.primary_reads_enabled() {
433437
false => Some(Role::Replica), // If primary should not be receiving reads, use a replica.
434438
true => None, // Any server role is fine in this case.
@@ -1158,6 +1162,29 @@ mod test {
11581162
}
11591163
}
11601164

1165+
#[test]
1166+
fn test_select_for_update() {
1167+
QueryRouter::setup();
1168+
let mut qr = QueryRouter::new();
1169+
qr.pool_settings.query_parser_read_write_splitting = true;
1170+
1171+
let queries_in_primary_role = vec![
1172+
simple_query("BEGIN"), // Transaction start
1173+
simple_query("SELECT * FROM items WHERE id = 5 FOR UPDATE"),
1174+
simple_query("UPDATE items SET name = 'pumpkin' WHERE id = 5"),
1175+
];
1176+
1177+
for query in queries_in_primary_role {
1178+
assert!(qr.infer(&qr.parse(&query).unwrap()).is_ok());
1179+
assert_eq!(qr.role(), Some(Role::Primary));
1180+
}
1181+
1182+
// query without lock do not change role
1183+
let query = simple_query("SELECT * FROM items WHERE id = 5");
1184+
assert!(qr.infer(&qr.parse(&query).unwrap()).is_ok());
1185+
assert_eq!(qr.role(), None);
1186+
}
1187+
11611188
#[test]
11621189
fn test_infer_primary_reads_enabled() {
11631190
QueryRouter::setup();

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.