@@ -4624,6 +4624,12 @@ pub enum Statement {
46244624 is_eq : bool ,
46254625 } ,
46264626 /// ```sql
4627+ /// LOCK [ TABLE ] [ ONLY ] name [ * ] [, ...] [ IN lockmode MODE ] [ NOWAIT ]
4628+ /// ```
4629+ ///
4630+ /// See <https://www.postgresql.org/docs/current/sql-lock.html>
4631+ Lock ( Lock ) ,
4632+ /// ```sql
46274633 /// LOCK TABLES <table_name> [READ [LOCAL] | [LOW_PRIORITY] WRITE]
46284634 /// ```
46294635 /// Note: this is a MySQL-specific statement. See <https://dev.mysql.com/doc/refman/8.0/en/lock-tables.html>
@@ -4847,6 +4853,12 @@ impl From<ddl::Truncate> for Statement {
48474853 }
48484854}
48494855
4856+ impl From < Lock > for Statement {
4857+ fn from ( lock : Lock ) -> Self {
4858+ Statement :: Lock ( lock)
4859+ }
4860+ }
4861+
48504862impl From < ddl:: Msck > for Statement {
48514863 fn from ( msck : ddl:: Msck ) -> Self {
48524864 Statement :: Msck ( msck)
@@ -6141,6 +6153,7 @@ impl fmt::Display for Statement {
61416153 }
61426154 Ok ( ( ) )
61436155 }
6156+ Statement :: Lock ( lock) => lock. fmt ( f) ,
61446157 Statement :: LockTables { tables } => {
61456158 write ! ( f, "LOCK TABLES {}" , display_comma_separated( tables) )
61466159 }
@@ -6387,6 +6400,104 @@ impl fmt::Display for TruncateTableTarget {
63876400 }
63886401}
63896402
6403+ /// A `LOCK` statement.
6404+ ///
6405+ /// See <https://www.postgresql.org/docs/current/sql-lock.html>
6406+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
6407+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
6408+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
6409+ pub struct Lock {
6410+ /// List of tables to lock.
6411+ pub tables : Vec < LockTableTarget > ,
6412+ /// Lock mode.
6413+ pub lock_mode : Option < LockTableMode > ,
6414+ /// Whether `NOWAIT` was specified.
6415+ pub nowait : bool ,
6416+ }
6417+
6418+ impl fmt:: Display for Lock {
6419+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
6420+ write ! ( f, "LOCK TABLE {}" , display_comma_separated( & self . tables) ) ?;
6421+ if let Some ( lock_mode) = & self . lock_mode {
6422+ write ! ( f, " IN {lock_mode} MODE" ) ?;
6423+ }
6424+ if self . nowait {
6425+ write ! ( f, " NOWAIT" ) ?;
6426+ }
6427+ Ok ( ( ) )
6428+ }
6429+ }
6430+
6431+ /// Target of a `LOCK TABLE` command
6432+ ///
6433+ /// See <https://www.postgresql.org/docs/current/sql-lock.html>
6434+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
6435+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
6436+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
6437+ pub struct LockTableTarget {
6438+ /// Name of the table being locked.
6439+ #[ cfg_attr( feature = "visitor" , visit( with = "visit_relation" ) ) ]
6440+ pub name : ObjectName ,
6441+ /// Whether `ONLY` was specified to exclude descendant tables.
6442+ pub only : bool ,
6443+ /// Whether `*` was specified to explicitly include descendant tables.
6444+ pub has_asterisk : bool ,
6445+ }
6446+
6447+ impl fmt:: Display for LockTableTarget {
6448+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
6449+ if self . only {
6450+ write ! ( f, "ONLY " ) ?;
6451+ }
6452+ write ! ( f, "{}" , self . name) ?;
6453+ if self . has_asterisk {
6454+ write ! ( f, " *" ) ?;
6455+ }
6456+ Ok ( ( ) )
6457+ }
6458+ }
6459+
6460+ /// PostgreSQL lock modes for `LOCK TABLE`.
6461+ ///
6462+ /// See <https://www.postgresql.org/docs/current/sql-lock.html>
6463+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
6464+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
6465+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
6466+ pub enum LockTableMode {
6467+ /// `ACCESS SHARE`
6468+ AccessShare ,
6469+ /// `ROW SHARE`
6470+ RowShare ,
6471+ /// `ROW EXCLUSIVE`
6472+ RowExclusive ,
6473+ /// `SHARE UPDATE EXCLUSIVE`
6474+ ShareUpdateExclusive ,
6475+ /// `SHARE`
6476+ Share ,
6477+ /// `SHARE ROW EXCLUSIVE`
6478+ ShareRowExclusive ,
6479+ /// `EXCLUSIVE`
6480+ Exclusive ,
6481+ /// `ACCESS EXCLUSIVE`
6482+ AccessExclusive ,
6483+ }
6484+
6485+ impl fmt:: Display for LockTableMode {
6486+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
6487+ let text = match self {
6488+ Self :: AccessShare => "ACCESS SHARE" ,
6489+ Self :: RowShare => "ROW SHARE" ,
6490+ Self :: RowExclusive => "ROW EXCLUSIVE" ,
6491+ Self :: ShareUpdateExclusive => "SHARE UPDATE EXCLUSIVE" ,
6492+ Self :: Share => "SHARE" ,
6493+ Self :: ShareRowExclusive => "SHARE ROW EXCLUSIVE" ,
6494+ Self :: Exclusive => "EXCLUSIVE" ,
6495+ Self :: AccessExclusive => "ACCESS EXCLUSIVE" ,
6496+ } ;
6497+ write ! ( f, "{text}" )
6498+ }
6499+ }
6500+
63906501/// PostgreSQL identity option for TRUNCATE table
63916502/// [ RESTART IDENTITY | CONTINUE IDENTITY ]
63926503#[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
0 commit comments