mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-03 22:08:16 +00:00
Generalize locking clause (#759)
Postgres supports more generalized locking clauses, for example: FOR UPDATE OF <table_name> SKIP LOCKED also, multiple locking clauses. Generalize the parser to support these. Co-authored-by: Andrew Lamb <andrew@nerdnetworks.org>
This commit is contained in:
parent
6c545195e1
commit
fb02344131
7 changed files with 187 additions and 36 deletions
|
@ -253,7 +253,7 @@ fn parse_update_set_from() {
|
|||
limit: None,
|
||||
offset: None,
|
||||
fetch: None,
|
||||
lock: None,
|
||||
locks: vec![],
|
||||
}),
|
||||
alias: Some(TableAlias {
|
||||
name: Ident::new("t2"),
|
||||
|
@ -2296,7 +2296,7 @@ fn parse_create_table_as_table() {
|
|||
limit: None,
|
||||
offset: None,
|
||||
fetch: None,
|
||||
lock: None,
|
||||
locks: vec![],
|
||||
});
|
||||
|
||||
match verified_stmt(sql1) {
|
||||
|
@ -2319,7 +2319,7 @@ fn parse_create_table_as_table() {
|
|||
limit: None,
|
||||
offset: None,
|
||||
fetch: None,
|
||||
lock: None,
|
||||
locks: vec![],
|
||||
});
|
||||
|
||||
match verified_stmt(sql2) {
|
||||
|
@ -3456,7 +3456,7 @@ fn parse_interval_and_or_xor() {
|
|||
limit: None,
|
||||
offset: None,
|
||||
fetch: None,
|
||||
lock: None,
|
||||
locks: vec![],
|
||||
}))];
|
||||
|
||||
assert_eq!(actual_ast, expected_ast);
|
||||
|
@ -5604,7 +5604,7 @@ fn parse_merge() {
|
|||
limit: None,
|
||||
offset: None,
|
||||
fetch: None,
|
||||
lock: None,
|
||||
locks: vec![],
|
||||
}),
|
||||
alias: Some(TableAlias {
|
||||
name: Ident {
|
||||
|
@ -5729,12 +5729,106 @@ fn test_merge_with_delimiter() {
|
|||
#[test]
|
||||
fn test_lock() {
|
||||
let sql = "SELECT * FROM student WHERE id = '1' FOR UPDATE";
|
||||
let ast = verified_query(sql);
|
||||
assert_eq!(ast.lock.unwrap(), LockType::Update);
|
||||
let mut ast = verified_query(sql);
|
||||
assert_eq!(ast.locks.len(), 1);
|
||||
let lock = ast.locks.pop().unwrap();
|
||||
assert_eq!(lock.lock_type, LockType::Update);
|
||||
assert!(lock.of.is_none());
|
||||
assert!(lock.nonblock.is_none());
|
||||
|
||||
let sql = "SELECT * FROM student WHERE id = '1' FOR SHARE";
|
||||
let ast = verified_query(sql);
|
||||
assert_eq!(ast.lock.unwrap(), LockType::Share);
|
||||
let mut ast = verified_query(sql);
|
||||
assert_eq!(ast.locks.len(), 1);
|
||||
let lock = ast.locks.pop().unwrap();
|
||||
assert_eq!(lock.lock_type, LockType::Share);
|
||||
assert!(lock.of.is_none());
|
||||
assert!(lock.nonblock.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_lock_table() {
|
||||
let sql = "SELECT * FROM student WHERE id = '1' FOR UPDATE OF school";
|
||||
let mut ast = verified_query(sql);
|
||||
assert_eq!(ast.locks.len(), 1);
|
||||
let lock = ast.locks.pop().unwrap();
|
||||
assert_eq!(lock.lock_type, LockType::Update);
|
||||
assert_eq!(
|
||||
lock.of.unwrap().0,
|
||||
vec![Ident {
|
||||
value: "school".to_string(),
|
||||
quote_style: None
|
||||
}]
|
||||
);
|
||||
assert!(lock.nonblock.is_none());
|
||||
|
||||
let sql = "SELECT * FROM student WHERE id = '1' FOR SHARE OF school";
|
||||
let mut ast = verified_query(sql);
|
||||
assert_eq!(ast.locks.len(), 1);
|
||||
let lock = ast.locks.pop().unwrap();
|
||||
assert_eq!(lock.lock_type, LockType::Share);
|
||||
assert_eq!(
|
||||
lock.of.unwrap().0,
|
||||
vec![Ident {
|
||||
value: "school".to_string(),
|
||||
quote_style: None
|
||||
}]
|
||||
);
|
||||
assert!(lock.nonblock.is_none());
|
||||
|
||||
let sql = "SELECT * FROM student WHERE id = '1' FOR SHARE OF school FOR UPDATE OF student";
|
||||
let mut ast = verified_query(sql);
|
||||
assert_eq!(ast.locks.len(), 2);
|
||||
let lock = ast.locks.remove(0);
|
||||
assert_eq!(lock.lock_type, LockType::Share);
|
||||
assert_eq!(
|
||||
lock.of.unwrap().0,
|
||||
vec![Ident {
|
||||
value: "school".to_string(),
|
||||
quote_style: None
|
||||
}]
|
||||
);
|
||||
assert!(lock.nonblock.is_none());
|
||||
let lock = ast.locks.remove(0);
|
||||
assert_eq!(lock.lock_type, LockType::Update);
|
||||
assert_eq!(
|
||||
lock.of.unwrap().0,
|
||||
vec![Ident {
|
||||
value: "student".to_string(),
|
||||
quote_style: None
|
||||
}]
|
||||
);
|
||||
assert!(lock.nonblock.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_lock_nonblock() {
|
||||
let sql = "SELECT * FROM student WHERE id = '1' FOR UPDATE OF school SKIP LOCKED";
|
||||
let mut ast = verified_query(sql);
|
||||
assert_eq!(ast.locks.len(), 1);
|
||||
let lock = ast.locks.pop().unwrap();
|
||||
assert_eq!(lock.lock_type, LockType::Update);
|
||||
assert_eq!(
|
||||
lock.of.unwrap().0,
|
||||
vec![Ident {
|
||||
value: "school".to_string(),
|
||||
quote_style: None
|
||||
}]
|
||||
);
|
||||
assert_eq!(lock.nonblock.unwrap(), NonBlock::SkipLocked);
|
||||
|
||||
let sql = "SELECT * FROM student WHERE id = '1' FOR SHARE OF school NOWAIT";
|
||||
let mut ast = verified_query(sql);
|
||||
assert_eq!(ast.locks.len(), 1);
|
||||
let lock = ast.locks.pop().unwrap();
|
||||
assert_eq!(lock.lock_type, LockType::Share);
|
||||
assert_eq!(
|
||||
lock.of.unwrap().0,
|
||||
vec![Ident {
|
||||
value: "school".to_string(),
|
||||
quote_style: None
|
||||
}]
|
||||
);
|
||||
assert_eq!(lock.nonblock.unwrap(), NonBlock::Nowait);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue