1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
use postgres::types::{accepts, FromSql, Type};
use serde::{Deserialize, Serialize};
/// Possible values of the pg_locks.mode column
#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize, Deserialize)]
pub enum LockMode {
/// Conflicts with the ACCESS EXCLUSIVE lock mode only.
///
/// The SELECT command acquires a lock of this mode on referenced tables. In
/// general, any query that only reads a table and does not modify it will
/// acquire this lock mode.
AccessShare,
/// Conflicts with the EXCLUSIVE and ACCESS EXCLUSIVE lock modes.
///
/// The SELECT command acquires a lock of this mode on all tables on which
/// one of the FOR UPDATE, FOR NO KEY UPDATE, FOR SHARE, or FOR KEY SHARE
/// options is specified (in addition to ACCESS SHARE locks on any other
/// tables that are referenced without any explicit FOR ... locking option).
RowShare,
/// Conflicts with the SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, and ACCESS
/// EXCLUSIVE lock modes.
///
/// The commands UPDATE, DELETE, INSERT, and MERGE acquire this lock mode on
/// the target table (in addition to ACCESS SHARE locks on any other
/// referenced tables). In general, this lock mode will be acquired by any
/// command that modifies data in a table.
RowExclusive,
/// Conflicts with the SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE,
/// EXCLUSIVE, and ACCESS EXCLUSIVE lock modes. This mode protects a table
/// against concurrent schema changes and VACUUM runs.
///
/// Acquired by VACUUM (without FULL), ANALYZE, CREATE INDEX CONCURRENTLY,
/// CREATE STATISTICS, COMMENT ON, REINDEX CONCURRENTLY, and certain ALTER
/// INDEX and ALTER TABLE variants (for full details see the documentation
/// of these commands).
ShareUpdateExclusive,
/// Conflicts with the ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE ROW
/// EXCLUSIVE, EXCLUSIVE, and ACCESS EXCLUSIVE lock modes. This mode
/// protects a table against concurrent data changes.
///
/// Acquired by CREATE INDEX (without CONCURRENTLY).
Share,
/// Conflicts with the ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE
/// ROW EXCLUSIVE, EXCLUSIVE, and ACCESS EXCLUSIVE lock modes. This mode
/// protects a table against concurrent data changes, and is self-exclusive
/// so that only one session can hold it at a time.
///
/// Acquired by CREATE TRIGGER and some forms of ALTER TABLE.
ShareRowExclusive,
/// Conflicts with the ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE,
/// SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, and ACCESS EXCLUSIVE lock
/// modes. This mode allows only concurrent ACCESS SHARE locks, i.e., only
/// reads from the table can proceed in parallel with a transaction holding
/// this lock mode.
///
/// Acquired by REFRESH MATERIALIZED VIEW CONCURRENTLY.
Exclusive,
/// Conflicts with locks of all modes (ACCESS SHARE, ROW SHARE, ROW
/// EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE,
/// EXCLUSIVE, and ACCESS EXCLUSIVE). This mode guarantees that the holder
/// is the only transaction accessing the table in any way.
///
/// Acquired by the DROP TABLE, TRUNCATE, REINDEX, CLUSTER, VACUUM FULL, and
/// REFRESH MATERIALIZED VIEW (without CONCURRENTLY) commands. Many forms of
/// ALTER INDEX and ALTER TABLE also acquire a lock at this level. This is
/// also the default lock mode for LOCK TABLE statements that do not specify
/// a mode explicitly.
AccessExclusive,
}
impl<'a> FromSql<'a> for LockMode {
accepts!(TEXT);
fn from_sql(
ty: &Type,
raw: &'a [u8],
) -> Result<Self, Box<(dyn std::error::Error + Send + Sync + 'static)>> {
let lock_mode = match String::from_sql(ty, raw)?.as_str() {
"ShareLock" => LockMode::Share,
"RowShareLock" => LockMode::RowShare,
"ExclusiveLock" => LockMode::Exclusive,
"AccessShareLock" => LockMode::AccessShare,
"RowExclusiveLock" => LockMode::RowExclusive,
"AccessExclusiveLock" => LockMode::AccessExclusive,
"ShareRowExclusiveLock" => LockMode::ShareRowExclusive,
"ShareUpdateExclusiveLock" => LockMode::ShareUpdateExclusive,
other => return Err(format!("unhandled TableLockMode {other}").into()),
};
Ok(lock_mode)
}
}