# SELECT ... FOR UPDATE SKIP LOCKED
#
# Sanity checks for SELECT ... FOR UPDATE SKIP LOCKED.

setup
{

  DROP TABLE IF EXISTS skip_locked;
  CREATE TABLE skip_locked (
	id integer PRIMARY KEY,
	value integer not null
  );

  INSERT INTO skip_locked
  SELECT x,x FROM generate_series(1,10) x;
}

teardown
{
  DROP TABLE skip_locked;
}

# The session that does the SKIP LOCKED queries
session "sl1"
step 	"sl1_begin" {
	BEGIN ISOLATION LEVEL READ COMMITTED;
}
step	"sl1_selectblocking" {
	SELECT xmin, xmax, ctid, * FROM skip_locked WHERE pg_advisory_lock(0) is not null FOR SHARE NOWAIT;
}
teardown                    { COMMIT; }

# A session that's used for an UPDATE of the rows to be locked, for when we're testing ctid
# chain following.
session "upd"
step	"upd_getlock" {
	SELECT pg_advisory_lock(0);
}
step    "upd_doupdate" {
	BEGIN ISOLATION LEVEL READ COMMITTED;
	UPDATE skip_locked SET value = value WHERE id % 2 = 0;
	COMMIT;
}
step 	"upd_releaselock" {
	SELECT pg_advisory_unlock(0);
}

# A session that acquires locks that sl1 is supposed to skip
session "lk1"
step    "lk1_doforshare" {
	BEGIN ISOLATION LEVEL READ COMMITTED;
	SELECT id FROM skip_locked WHERE id % 2 = 0 FOR SHARE;
}
teardown {
	COMMIT;
}

permutation "upd_getlock" "sl1_begin" "sl1_selectblocking" "upd_doupdate" "lk1_doforshare" "upd_releaselock"
