new-lock-table maxlocks=10000
----

new-txn txn=txn1 ts=10,1 epoch=0
----

new-txn txn=txn2 ts=11,1 epoch=0
----

# req1 will acquire locks for txn1

new-request r=req1 txn=txn1 ts=10,1 spans=exclusive@c,h
----

scan r=req1
----
start-waiting: false

should-wait r=req1
----
false

acquire r=req1 k=c durability=u strength=exclusive
----
num=1
 lock: "c"
  holder: txn: 00000000-0000-0000-0000-000000000001 epoch: 0, iso: Serializable, ts: 10.000000000,1, info: unrepl [(str: Exclusive seq: 0)]

acquire r=req1 k=g durability=u strength=exclusive
----
num=2
 lock: "c"
  holder: txn: 00000000-0000-0000-0000-000000000001 epoch: 0, iso: Serializable, ts: 10.000000000,1, info: unrepl [(str: Exclusive seq: 0)]
 lock: "g"
  holder: txn: 00000000-0000-0000-0000-000000000001 epoch: 0, iso: Serializable, ts: 10.000000000,1, info: unrepl [(str: Exclusive seq: 0)]

dequeue r=req1
----
num=2
 lock: "c"
  holder: txn: 00000000-0000-0000-0000-000000000001 epoch: 0, iso: Serializable, ts: 10.000000000,1, info: unrepl [(str: Exclusive seq: 0)]
 lock: "g"
  holder: txn: 00000000-0000-0000-0000-000000000001 epoch: 0, iso: Serializable, ts: 10.000000000,1, info: unrepl [(str: Exclusive seq: 0)]

new-request r=req2 txn=txn2 ts=11,1 spans=none@a,d
----

scan r=req2
----
start-waiting: true

should-wait r=req2
----
true

dequeue r=req2
----
num=2
 lock: "c"
  holder: txn: 00000000-0000-0000-0000-000000000001 epoch: 0, iso: Serializable, ts: 10.000000000,1, info: unrepl [(str: Exclusive seq: 0)]
 lock: "g"
  holder: txn: 00000000-0000-0000-0000-000000000001 epoch: 0, iso: Serializable, ts: 10.000000000,1, info: unrepl [(str: Exclusive seq: 0)]

new-request r=req3 txn=txn2 ts=11,1 spans=none@a,d+none@f,i
----

scan-opt r=req3
----
start-waiting: false

should-wait r=req3
----
false

print
----
num=2
 lock: "c"
  holder: txn: 00000000-0000-0000-0000-000000000001 epoch: 0, iso: Serializable, ts: 10.000000000,1, info: unrepl [(str: Exclusive seq: 0)]
 lock: "g"
  holder: txn: 00000000-0000-0000-0000-000000000001 epoch: 0, iso: Serializable, ts: 10.000000000,1, info: unrepl [(str: Exclusive seq: 0)]

check-opt-no-conflicts r=req3 spans=none@a,c
----
no-conflicts: true

check-opt-no-conflicts r=req3 spans=none@a,d
----
no-conflicts: false

check-opt-no-conflicts r=req3 spans=none@a,c+none@f,g
----
no-conflicts: true

check-opt-no-conflicts r=req3 spans=none@a,c+none@f,h
----
no-conflicts: false

dequeue r=req3
----
num=2
 lock: "c"
  holder: txn: 00000000-0000-0000-0000-000000000001 epoch: 0, iso: Serializable, ts: 10.000000000,1, info: unrepl [(str: Exclusive seq: 0)]
 lock: "g"
  holder: txn: 00000000-0000-0000-0000-000000000001 epoch: 0, iso: Serializable, ts: 10.000000000,1, info: unrepl [(str: Exclusive seq: 0)]

# ---------------------------------------------------------------------------------
# Test with a Skip wait policy. Even though the lock table has a conflicting lock,
# it assumes that the request saw and handled this lock during evaluation, so it
# does not trigger a conflict.
# ---------------------------------------------------------------------------------

new-request r=req4 txn=txn2 ts=11,1 spans=none@a,i skip-locked
----

scan-opt r=req4
----
start-waiting: false

should-wait r=req4
----
false

check-opt-no-conflicts r=req4 spans=none@a,i
----
no-conflicts: true

dequeue r=req4
----
num=2
 lock: "c"
  holder: txn: 00000000-0000-0000-0000-000000000001 epoch: 0, iso: Serializable, ts: 10.000000000,1, info: unrepl [(str: Exclusive seq: 0)]
 lock: "g"
  holder: txn: 00000000-0000-0000-0000-000000000001 epoch: 0, iso: Serializable, ts: 10.000000000,1, info: unrepl [(str: Exclusive seq: 0)]


# ------------------------------------------------------------------------------
# Test that optimistic evaluation succeeds if the lock is held by our own
# transaction, regardless of lock strengths.
# ------------------------------------------------------------------------------

clear
----
num=0

new-request r=req5 txn=txn1 ts=10,1 spans=shared@a
----

scan r=req5
----
start-waiting: false

should-wait r=req5
----
false

acquire r=req5 k=a durability=u strength=shared
----
num=1
 lock: "a"
  holder: txn: 00000000-0000-0000-0000-000000000001 epoch: 0, iso: Serializable, info: unrepl [(str: Shared seq: 0)]

# Ensure a optimistic evaluation attempt from the same transaction that covers
# key "a" succeeds -- both with lower and higher lock strengths than the
# strength of the lock already held (shared).

new-request r=req6 txn=txn1 ts=10,1 spans=exclusive@a,c
----

scan-opt r=req6
----
start-waiting: false

should-wait r=req6
----
false

check-opt-no-conflicts r=req6 spans=exclusive@a,c
----
no-conflicts: true

dequeue r=req6
----
num=1
 lock: "a"
  holder: txn: 00000000-0000-0000-0000-000000000001 epoch: 0, iso: Serializable, info: unrepl [(str: Shared seq: 0)]

new-request r=req7 txn=txn1 ts=10,1 spans=none@a,c
----

scan-opt r=req7
----
start-waiting: false

should-wait r=req7
----
false

check-opt-no-conflicts r=req7 spans=none@a,c
----
no-conflicts: true

dequeue r=req7
----
num=1
 lock: "a"
  holder: txn: 00000000-0000-0000-0000-000000000001 epoch: 0, iso: Serializable, info: unrepl [(str: Shared seq: 0)]

# ------------------------------------------------------------------------------
# Test that optimistic evaluation works with SHARED locking strength -- if a
# shared lock is held, another transaction should be able to perform optimistic
# evaluation with shared locking strength and not conflict; optimistic evaluation
# should conflict if run with exclusive lock strength.
# ------------------------------------------------------------------------------

new-request r=req8 txn=txn2 ts=10,1 spans=none@a,c
----

scan-opt r=req8
----
start-waiting: false

should-wait r=req8
----
false

check-opt-no-conflicts r=req8 spans=shared@a,c
----
no-conflicts: true

dequeue r=req8
----
num=1
 lock: "a"
  holder: txn: 00000000-0000-0000-0000-000000000001 epoch: 0, iso: Serializable, info: unrepl [(str: Shared seq: 0)]

new-request r=req9 txn=txn2 ts=10,1 spans=exclusive@a,c
----

scan-opt r=req9
----
start-waiting: false

should-wait r=req9
----
false

check-opt-no-conflicts r=req9 spans=exclusive@a,c
----
no-conflicts: false

dequeue r=req9
----
num=1
 lock: "a"
  holder: txn: 00000000-0000-0000-0000-000000000001 epoch: 0, iso: Serializable, info: unrepl [(str: Shared seq: 0)]
