1use super::separator_optional;
2use crate::WriteSql;
3
4#[derive(Clone, Copy, PartialEq, Eq)]
9pub enum RowLockStrength {
10 Update,
11 NoKeyUpdate,
12 Share,
13 KeyShare,
14}
15
16impl RowLockStrength {
17 pub const fn as_str(&self) -> &'static str {
18 match *self {
19 Self::Update => "UPDATE",
20 Self::NoKeyUpdate => "NO KEY UPDATE",
21 Self::Share => "SHARE",
22 Self::KeyShare => "KEY SHARE",
23 }
24 }
25}
26
27#[derive(Clone, Copy, PartialEq, Eq)]
28pub enum RowLockConcurrency {
29 NoWait,
30 SkipLocked,
31}
32
33impl RowLockConcurrency {
34 pub const fn as_str(&self) -> &'static str {
35 match *self {
36 Self::NoWait => "NOWAIT",
37 Self::SkipLocked => "SKIP LOCKED",
38 }
39 }
40}
41
42pub fn row_lock<'t, Sql, Arg, I>(
43 sql: &mut Sql,
44 strength: RowLockStrength,
45 tables: I,
46 concurrency: Option<RowLockConcurrency>,
47) where
48 Sql: WriteSql<Arg>,
49 I: IntoIterator<Item = &'t str>,
50{
51 separator_optional(sql);
52 sql.push_cmd("FOR ");
53 sql.push_cmd(strength.as_str());
54
55 let mut tables = tables.into_iter();
56 if let Some(table) = tables.next() {
57 sql.push_cmd(" OF ");
58 sql.push_cmd(table);
59 }
60 for table in tables {
61 sql.push_cmd(", ");
62 sql.push_cmd(table);
63 }
64
65 if let Some(concurr) = concurrency {
66 sql.push_cmd(" ");
67 sql.push_cmd(concurr.as_str());
68 }
69}
70
71#[derive(Clone, Copy, PartialEq, Eq)]
75pub enum TableLockMode {
76 AccessShare,
77 RowShare,
78 RowExclusive,
79 ShareUpdateExclusive,
80 Share,
81 ShareRowExclusive,
82 Exclusive,
83 AccessExclusive,
84}
85
86impl TableLockMode {
87 pub const fn as_str(&self) -> &'static str {
88 match *self {
89 Self::AccessShare => "ACCESS SHARE",
90 Self::RowShare => "ROW SHARE",
91 Self::RowExclusive => "ROW EXCLUSIVE",
92 Self::ShareUpdateExclusive => "SHARE UPDATE EXCLUSIVE",
93 Self::Share => "SHARE",
94 Self::ShareRowExclusive => "SHARE ROW EXCLUSIVE",
95 Self::Exclusive => "EXCLUSIVE",
96 Self::AccessExclusive => "ACCESS EXCLUSIVE",
97 }
98 }
99}
100
101#[derive(Clone, PartialEq, Eq)]
102pub enum TableLock<'t> {
103 Only(&'t str),
104 Tables(&'t [&'t str]),
105}
106
107#[derive(Default, Clone, Copy, PartialEq, Eq)]
108pub enum TableLockWait {
109 NoWait,
110 #[default]
111 None,
112}
113
114impl TableLockWait {
115 pub const fn as_str(&self) -> &'static str {
116 match *self {
117 Self::NoWait => "NOWAIT",
118 Self::None => "",
119 }
120 }
121}
122
123pub fn table_lock<Sql, Arg>(
127 sql: &mut Sql,
128 tables: TableLock<'_>,
129 lock_mode: Option<TableLockMode>,
130 nowait: TableLockWait,
131) where
132 Sql: WriteSql<Arg>,
133{
134 separator_optional(sql);
135 sql.push_cmd("LOCK TABLE ");
136
137 match tables {
138 TableLock::Only(table) => {
139 sql.push_cmd("ONLY ");
140 sql.push_cmd(table);
141 }
142 TableLock::Tables(tbls) => {
143 if let Some(tbl) = tbls.first() {
144 sql.push_cmd(tbl);
145 }
146 for tbl in &tbls[1..] {
147 sql.push_cmd(", ");
148 sql.push_cmd(tbl);
149 }
150 }
151 }
152
153 if let Some(mode) = lock_mode {
154 sql.push_cmd(" ");
155 sql.push_cmd(mode.as_str());
156 }
157
158 if nowait == TableLockWait::NoWait {
159 sql.push_cmd(" NOWAIT");
160 }
161}
162
163#[allow(unused_macros)]
164macro_rules! lock_strength {
165 (UPDATE) => {
166 "UPDATE"
167 };
168 (NO_KEY_UPDATE) => {
169 "NO KEY UPDATE"
170 };
171 (SHARE) => {
172 "SHARE"
173 };
174 (KEY_SHARE) => {
175 "KEY SHARE"
176 };
177}
178
179#[allow(unused)]
180pub(super) use lock_strength;
181
182#[macro_export]
186macro_rules! static_row_lock {
187 (FOR $s1:tt) => {
188 concat!("FOR ", $crate::expr::lock_strength!($s1))
189 };
190 (FOR $s1:tt NOWAIT) => {
191 concat!("FOR ", $crate::expr::lock_strength!($s1), " NOWAIT")
192 };
193 (FOR $s1:tt SKIP LOCKED) => {
194 concat!("FOR ", $crate::expr::lock_strength!($s1), " SKIP LOCKED")
195 };
196
197 (FOR $s1:tt OF $ftbl:literal$(,)? $($tbl:literal),*) => {
198 concat!(
199 "FOR ",
200 $crate::expr::lock_strength!($s1),
201 " OF ",
202 $ftbl,
203 $(", ", $tbl),*
204 )
205 };
206 (FOR $s1:tt OF $ftbl:literal$(,)? $($tbl:literal),* NOWAIT) => {
207 concat!(
208 "FOR ",
209 $crate::expr::lock_strength!($s1),
210 " OF ",
211 $ftbl,
212 $(", ", $tbl,)*
213 " NOWAIT"
214 )
215 };
216 (FOR $s1:tt OF $ftbl:literal$(,)? $($tbl:literal),* SKIP LOCKED) => {
217 concat!(
218 "FOR ",
219 $crate::expr::lock_strength!($s1),
220 " OF ",
221 $ftbl,
222 $(", ", $tbl,)*
223 " SKIP LOCKED"
224 )
225 };
226}
227
228pub use static_row_lock;
229
230#[allow(unused_macros)]
231macro_rules! lockmode {
232 (ACCESS_SHARE) => {
233 "ACCESS SHARE"
234 };
235 (ROW_SHARE) => {
236 "ROW SHARE"
237 };
238 (ROW_EXCLUSIVE) => {
239 "ROW EXCLUSIVE"
240 };
241 (SHARE_UPDATE_EXCLUSIVE) => {
242 "SHARE UPDATE EXCLUSIVE"
243 };
244 (SHARE) => {
245 "SHARE"
246 };
247 (SHARE_ROW_EXCLUSIVE) => {
248 "SHARE ROW EXCLUSIVE"
249 };
250 (EXCLUSIVE) => {
251 "EXCLUSIVE"
252 };
253 (ACCESS_EXCLUSIVE) => {
254 "ACCESS EXCLUSIVE"
255 };
256}
257
258#[allow(unused)]
259pub(super) use lockmode;
260
261#[macro_export]
265macro_rules! static_table_lock {
266 (LOCK TABLE $table:literal$(,)? $($tables:literal),*) => {
267 concat!("LOCK TABLE ", $table, $(", ", $tables,)*)
268 };
269 (LOCK TABLE ONLY $table:literal) => {
270 concat!("LOCK TABLE ONLY ", $table)
271 };
272 (LOCK TABLE $table:literal$(,)? $($tables:literal),* NOWAIT) => {
273 concat!("LOCK TABLE ", $table, $(", ", $tables,)* " NOWAIT")
274 };
275 (LOCK TABLE ONLY $table:literal NOWAIT) => {
276 concat!("LOCK TABLE ONLY ", $table, " NOWAIT")
277 };
278
279 (LOCK TABLE $table:literal$(,)? $($tables:literal),* IN $mode:tt MODE) => {
280 concat!("LOCK TABLE ", $table, $(", ", $tables,)* " IN ", $crate::expr::lockmode!($mode), " MODE")
281 };
282 (LOCK TABLE ONLY $table:literal IN $mode:tt MODE) => {
283 concat!("LOCK TABLE ONLY ", $table, " IN ", $crate::expr::lockmode!($mode), " MODE")
284 };
285 (LOCK TABLE $table:literal$(,)? $($tables:literal),* IN $mode:tt MODE NOWAIT) => {
286 concat!("LOCK TABLE ", $table, $(", ", $tables,)* " IN ", $crate::expr::lockmode!($mode), " MODE NOWAIT")
287 };
288 (LOCK TABLE ONLY $table:literal IN $mode:tt MODE NOWAIT) => {
289 concat!("LOCK TABLE ONLY ", $table, " IN ", $crate::expr::lockmode!($mode), " MODE NOWAIT")
290 };
291}
292
293pub use static_table_lock;
294
295#[cfg(test)]
296mod row_lock_test {
297 use super::{row_lock, RowLockStrength};
298 use crate::{expr::RowLockConcurrency, SqlCommand, Void};
299
300 #[test]
301 fn row_locking_strength() {
302 let mut sql: SqlCommand<Void> = SqlCommand::default();
303
304 row_lock(&mut sql, RowLockStrength::NoKeyUpdate, [], None);
305
306 assert_eq!(sql.as_command(), "FOR NO KEY UPDATE");
307 }
308
309 #[test]
310 fn row_locking_strength_with_concurrency() {
311 let mut sql: SqlCommand<Void> = SqlCommand::default();
312
313 row_lock(
314 &mut sql,
315 RowLockStrength::Share,
316 [],
317 Some(RowLockConcurrency::NoWait),
318 );
319
320 assert_eq!(sql.as_command(), "FOR SHARE NOWAIT");
321 }
322
323 #[test]
324 fn row_locking_with_tables() {
325 let mut sql: SqlCommand<Void> = SqlCommand::default();
326
327 row_lock(
328 &mut sql,
329 RowLockStrength::Update,
330 ["user", "access_history"],
331 None,
332 );
333
334 assert_eq!(sql.as_command(), "FOR UPDATE OF user, access_history");
335 }
336
337 #[test]
338 fn row_locking_with_tables_and_concurrency() {
339 let mut sql: SqlCommand<Void> = SqlCommand::default();
340
341 row_lock(
342 &mut sql,
343 RowLockStrength::KeyShare,
344 ["customer"],
345 Some(RowLockConcurrency::SkipLocked),
346 );
347
348 assert_eq!(sql.as_command(), "FOR KEY SHARE OF customer SKIP LOCKED");
349 }
350}
351
352#[cfg(test)]
353mod table_lock_test {
354 use crate::{
355 expr::{table_lock, TableLock, TableLockMode, TableLockWait},
356 SqlCommand, Void,
357 };
358
359 #[test]
360 fn lock_table_only() {
361 let mut sql: SqlCommand<Void> = SqlCommand::default();
362
363 table_lock(&mut sql, TableLock::Only("user"), None, TableLockWait::None);
364
365 assert_eq!(sql.as_command(), "LOCK TABLE ONLY user");
366 }
367
368 #[test]
369 fn lock_table_only_with_lockmode() {
370 let mut sql: SqlCommand<Void> = SqlCommand::default();
371
372 table_lock(
373 &mut sql,
374 TableLock::Only("user"),
375 Some(TableLockMode::AccessExclusive),
376 TableLockWait::None,
377 );
378
379 assert_eq!(sql.as_command(), "LOCK TABLE ONLY user ACCESS EXCLUSIVE");
380 }
381
382 #[test]
383 fn lock_table_only_with_lockmode_and_wait() {
384 let mut sql: SqlCommand<Void> = SqlCommand::default();
385
386 table_lock(
387 &mut sql,
388 TableLock::Only("user"),
389 Some(TableLockMode::AccessExclusive),
390 TableLockWait::NoWait,
391 );
392
393 assert_eq!(
394 sql.as_command(),
395 "LOCK TABLE ONLY user ACCESS EXCLUSIVE NOWAIT"
396 );
397 }
398
399 #[test]
400 fn lock_table_only_with_onwait() {
401 let mut sql: SqlCommand<Void> = SqlCommand::default();
402
403 table_lock(
404 &mut sql,
405 TableLock::Only("user"),
406 None,
407 TableLockWait::NoWait,
408 );
409
410 assert_eq!(sql.as_command(), "LOCK TABLE ONLY user NOWAIT");
411 }
412
413 #[test]
414 fn lock_tables() {
415 let mut sql: SqlCommand<Void> = SqlCommand::default();
416
417 table_lock(
418 &mut sql,
419 TableLock::Tables(&["user", "customer"]),
420 None,
421 TableLockWait::None,
422 );
423
424 assert_eq!(sql.as_command(), "LOCK TABLE user, customer");
425 }
426
427 #[test]
428 fn lock_tables_with_lockmode() {
429 let mut sql: SqlCommand<Void> = SqlCommand::default();
430
431 table_lock(
432 &mut sql,
433 TableLock::Tables(&["user", "customer"]),
434 Some(TableLockMode::Share),
435 TableLockWait::None,
436 );
437
438 assert_eq!(sql.as_command(), "LOCK TABLE user, customer SHARE");
439 }
440
441 #[test]
442 fn lock_tables_with_lockmode_and_nowait() {
443 let mut sql: SqlCommand<Void> = SqlCommand::default();
444
445 table_lock(
446 &mut sql,
447 TableLock::Tables(&["user", "customer"]),
448 Some(TableLockMode::RowExclusive),
449 TableLockWait::NoWait,
450 );
451
452 assert_eq!(
453 sql.as_command(),
454 "LOCK TABLE user, customer ROW EXCLUSIVE NOWAIT"
455 );
456 }
457
458 #[test]
459 fn lock_tables_with_nowait() {
460 let mut sql: SqlCommand<Void> = SqlCommand::default();
461
462 table_lock(
463 &mut sql,
464 TableLock::Tables(&["user", "customer"]),
465 None,
466 TableLockWait::NoWait,
467 );
468
469 assert_eq!(sql.as_command(), "LOCK TABLE user, customer NOWAIT");
470 }
471}
472
473#[cfg(test)]
474mod static_row_lock_test {
475 #[test]
476 fn static_row_lock_macro() {
477 assert_eq!(static_row_lock!(FOR UPDATE), "FOR UPDATE");
478 assert_eq!(static_row_lock!(FOR NO_KEY_UPDATE), "FOR NO KEY UPDATE");
479 assert_eq!(static_row_lock!(FOR SHARE), "FOR SHARE");
480 assert_eq!(static_row_lock!(FOR KEY_SHARE), "FOR KEY SHARE");
481
482 assert_eq!(static_row_lock!(FOR UPDATE NOWAIT), "FOR UPDATE NOWAIT");
483 assert_eq!(
484 static_row_lock!(FOR NO_KEY_UPDATE NOWAIT),
485 "FOR NO KEY UPDATE NOWAIT"
486 );
487 assert_eq!(static_row_lock!(FOR SHARE NOWAIT), "FOR SHARE NOWAIT");
488 assert_eq!(
489 static_row_lock!(FOR KEY_SHARE NOWAIT),
490 "FOR KEY SHARE NOWAIT"
491 );
492
493 assert_eq!(
494 static_row_lock!(FOR UPDATE SKIP LOCKED),
495 "FOR UPDATE SKIP LOCKED"
496 );
497 assert_eq!(
498 static_row_lock!(FOR NO_KEY_UPDATE SKIP LOCKED),
499 "FOR NO KEY UPDATE SKIP LOCKED"
500 );
501 assert_eq!(
502 static_row_lock!(FOR SHARE SKIP LOCKED),
503 "FOR SHARE SKIP LOCKED"
504 );
505 assert_eq!(
506 static_row_lock!(FOR KEY_SHARE SKIP LOCKED),
507 "FOR KEY SHARE SKIP LOCKED"
508 );
509
510 assert_eq!(static_row_lock!(FOR UPDATE OF "user"), "FOR UPDATE OF user");
511 assert_eq!(
512 static_row_lock!(FOR NO_KEY_UPDATE OF "user"),
513 "FOR NO KEY UPDATE OF user"
514 );
515 assert_eq!(static_row_lock!(FOR SHARE OF "user"), "FOR SHARE OF user");
516 assert_eq!(
517 static_row_lock!(FOR KEY_SHARE OF "user"),
518 "FOR KEY SHARE OF user"
519 );
520
521 assert_eq!(
522 static_row_lock!(FOR UPDATE OF "user" NOWAIT),
523 "FOR UPDATE OF user NOWAIT"
524 );
525 assert_eq!(
526 static_row_lock!(FOR NO_KEY_UPDATE OF "user" NOWAIT),
527 "FOR NO KEY UPDATE OF user NOWAIT"
528 );
529 assert_eq!(
530 static_row_lock!(FOR SHARE OF "user" NOWAIT),
531 "FOR SHARE OF user NOWAIT"
532 );
533 assert_eq!(
534 static_row_lock!(FOR KEY_SHARE OF "user" NOWAIT),
535 "FOR KEY SHARE OF user NOWAIT"
536 );
537
538 assert_eq!(
539 static_row_lock!(FOR UPDATE OF "user" SKIP LOCKED),
540 "FOR UPDATE OF user SKIP LOCKED"
541 );
542 assert_eq!(
543 static_row_lock!(FOR NO_KEY_UPDATE OF "user" SKIP LOCKED),
544 "FOR NO KEY UPDATE OF user SKIP LOCKED"
545 );
546 assert_eq!(
547 static_row_lock!(FOR SHARE OF "user" SKIP LOCKED),
548 "FOR SHARE OF user SKIP LOCKED"
549 );
550 assert_eq!(
551 static_row_lock!(FOR KEY_SHARE OF "user" SKIP LOCKED),
552 "FOR KEY SHARE OF user SKIP LOCKED"
553 );
554
555 assert_eq!(
556 static_row_lock!(FOR UPDATE OF "user", "access", "customer"),
557 "FOR UPDATE OF user, access, customer"
558 );
559 assert_eq!(
560 static_row_lock!(FOR NO_KEY_UPDATE OF "user", "access", "customer"),
561 "FOR NO KEY UPDATE OF user, access, customer"
562 );
563 assert_eq!(
564 static_row_lock!(FOR SHARE OF "user", "access", "customer"),
565 "FOR SHARE OF user, access, customer"
566 );
567 assert_eq!(
568 static_row_lock!(FOR KEY_SHARE OF "user", "access", "customer"),
569 "FOR KEY SHARE OF user, access, customer"
570 );
571
572 assert_eq!(
573 static_row_lock!(FOR UPDATE OF "user", "access", "customer" NOWAIT),
574 "FOR UPDATE OF user, access, customer NOWAIT"
575 );
576 assert_eq!(
577 static_row_lock!(FOR NO_KEY_UPDATE OF "user", "access", "customer" NOWAIT),
578 "FOR NO KEY UPDATE OF user, access, customer NOWAIT"
579 );
580 assert_eq!(
581 static_row_lock!(FOR SHARE OF "user", "access", "customer" NOWAIT),
582 "FOR SHARE OF user, access, customer NOWAIT"
583 );
584 assert_eq!(
585 static_row_lock!(FOR KEY_SHARE OF "user", "access", "customer" NOWAIT),
586 "FOR KEY SHARE OF user, access, customer NOWAIT"
587 );
588
589 assert_eq!(
590 static_row_lock!(FOR UPDATE OF "user", "access", "customer" SKIP LOCKED),
591 "FOR UPDATE OF user, access, customer SKIP LOCKED"
592 );
593 assert_eq!(
594 static_row_lock!(FOR NO_KEY_UPDATE OF "user", "access", "customer" SKIP LOCKED),
595 "FOR NO KEY UPDATE OF user, access, customer SKIP LOCKED"
596 );
597 assert_eq!(
598 static_row_lock!(FOR SHARE OF "user", "access", "customer" SKIP LOCKED),
599 "FOR SHARE OF user, access, customer SKIP LOCKED"
600 );
601 assert_eq!(
602 static_row_lock!(FOR KEY_SHARE OF "user", "access", "customer" SKIP LOCKED),
603 "FOR KEY SHARE OF user, access, customer SKIP LOCKED"
604 );
605 }
606
607 #[test]
608 fn static_table_lock_macro() {
609 assert_eq!(static_table_lock!(LOCK TABLE "user"), "LOCK TABLE user");
610 assert_eq!(
611 static_table_lock!(LOCK TABLE "user", "customer", "access_record"),
612 "LOCK TABLE user, customer, access_record"
613 );
614 assert_eq!(
615 static_table_lock!(LOCK TABLE "user" IN ROW_EXCLUSIVE MODE),
616 "LOCK TABLE user IN ROW EXCLUSIVE MODE"
617 );
618
619 assert_eq!(
620 static_table_lock!(LOCK TABLE "user", "customer", "access_record" IN ACCESS_SHARE MODE),
621 "LOCK TABLE user, customer, access_record IN ACCESS SHARE MODE"
622 );
623 assert_eq!(
624 static_table_lock!(LOCK TABLE "user", "customer", "access_record" IN ROW_SHARE MODE),
625 "LOCK TABLE user, customer, access_record IN ROW SHARE MODE"
626 );
627 assert_eq!(
628 static_table_lock!(LOCK TABLE "user", "customer", "access_record" IN ROW_EXCLUSIVE MODE),
629 "LOCK TABLE user, customer, access_record IN ROW EXCLUSIVE MODE"
630 );
631 assert_eq!(
632 static_table_lock!(LOCK TABLE "user", "customer", "access_record" IN SHARE_UPDATE_EXCLUSIVE MODE),
633 "LOCK TABLE user, customer, access_record IN SHARE UPDATE EXCLUSIVE MODE"
634 );
635 assert_eq!(
636 static_table_lock!(LOCK TABLE "user", "customer", "access_record" IN SHARE MODE),
637 "LOCK TABLE user, customer, access_record IN SHARE MODE"
638 );
639 assert_eq!(
640 static_table_lock!(LOCK TABLE "user", "customer", "access_record" IN SHARE_ROW_EXCLUSIVE MODE),
641 "LOCK TABLE user, customer, access_record IN SHARE ROW EXCLUSIVE MODE"
642 );
643 assert_eq!(
644 static_table_lock!(LOCK TABLE "user", "customer", "access_record" IN EXCLUSIVE MODE),
645 "LOCK TABLE user, customer, access_record IN EXCLUSIVE MODE"
646 );
647 assert_eq!(
648 static_table_lock!(LOCK TABLE "user", "customer", "access_record" IN ACCESS_EXCLUSIVE MODE),
649 "LOCK TABLE user, customer, access_record IN ACCESS EXCLUSIVE MODE"
650 );
651
652 assert_eq!(
653 static_table_lock!(LOCK TABLE "user" NOWAIT),
654 "LOCK TABLE user NOWAIT"
655 );
656 assert_eq!(
657 static_table_lock!(LOCK TABLE "user", "customer", "access_record" NOWAIT),
658 "LOCK TABLE user, customer, access_record NOWAIT"
659 );
660 assert_eq!(
661 static_table_lock!(LOCK TABLE "user" IN ROW_EXCLUSIVE MODE NOWAIT),
662 "LOCK TABLE user IN ROW EXCLUSIVE MODE NOWAIT"
663 );
664
665 assert_eq!(
666 static_table_lock!(LOCK TABLE "user", "access_record" IN ACCESS_SHARE MODE NOWAIT),
667 "LOCK TABLE user, access_record IN ACCESS SHARE MODE NOWAIT"
668 );
669 assert_eq!(
670 static_table_lock!(LOCK TABLE "customer", "access_record" IN ROW_SHARE MODE NOWAIT),
671 "LOCK TABLE customer, access_record IN ROW SHARE MODE NOWAIT"
672 );
673 assert_eq!(
674 static_table_lock!(LOCK TABLE "user", "customer" IN ROW_EXCLUSIVE MODE NOWAIT),
675 "LOCK TABLE user, customer IN ROW EXCLUSIVE MODE NOWAIT"
676 );
677 assert_eq!(
678 static_table_lock!(LOCK TABLE "user", "customer", "access_record" IN SHARE_UPDATE_EXCLUSIVE MODE NOWAIT),
679 "LOCK TABLE user, customer, access_record IN SHARE UPDATE EXCLUSIVE MODE NOWAIT"
680 );
681 assert_eq!(
682 static_table_lock!(LOCK TABLE "user", "customer" IN SHARE MODE NOWAIT),
683 "LOCK TABLE user, customer IN SHARE MODE NOWAIT"
684 );
685 assert_eq!(
686 static_table_lock!(LOCK TABLE "access_record" IN SHARE_ROW_EXCLUSIVE MODE NOWAIT),
687 "LOCK TABLE access_record IN SHARE ROW EXCLUSIVE MODE NOWAIT"
688 );
689 assert_eq!(
690 static_table_lock!(LOCK TABLE "user", "customer", "access_record" IN EXCLUSIVE MODE NOWAIT),
691 "LOCK TABLE user, customer, access_record IN EXCLUSIVE MODE NOWAIT"
692 );
693 assert_eq!(
694 static_table_lock!(LOCK TABLE "user", "customer", "access_record" IN ACCESS_EXCLUSIVE MODE NOWAIT),
695 "LOCK TABLE user, customer, access_record IN ACCESS EXCLUSIVE MODE NOWAIT"
696 );
697 }
698}