On Wed, Dec 27, 2017 at 04:53:42PM +0900, Michael Paquier wrote:
> Indeed, this bit is important, and RangeVarGet does so. Looking at
> get_object_address(), it also handles locking of the object. Using that
> as interface to address all the concurrency problems could be appealing,
> and less invasive for a final result as many DDLs are visibly
> impacted (still need to make a list here). What do you think?

So, I have looked at all the object types to spot concurrency problems,
and I have found some more. And the winners are:
- database
- role
- domain
- event trigger
- FDW
- server
- user mapping
- type
- tablespace

Most of the failures show "tuple concurrently updated" using a given set
of ALTER commands running concurrently, but I have been able to trigger
as well one "cache lookup failure" for domains, and a duplicate key value
violation for databases.

I have done some extra checks with parallel ALTER commands for the
following objects as well, without spotting issues:
- access method
- cast
- attribute
- extension
- view
- policy
- publication
- subscription
- rule
- transform
- text search stuff
- statistics
- operator [family], etc.

As looking for those failures manually is no fun, I am attaching a patch
which includes a set of isolation regression tests able to trigger
them. You just need to look for unwelcome ERROR messages and you are
good to go. The goal to move forward will be to take care of all those
failures. Please note that isolation tests don't allow dynamic input, so
those have no tests but you can reproduce an error easily with ALTER
TABLESPACE SET SCHEMA between two sessions. Note as well that the domain
test will fail because the cache lookup error on domains exposes the
domain OID, but that's nothing to care about.

Opinions or thoughts?
--
Michael
diff --git a/src/test/isolation/expected/concurrent-database.out 
b/src/test/isolation/expected/concurrent-database.out
new file mode 100644
index 0000000000..59da795117
--- /dev/null
+++ b/src/test/isolation/expected/concurrent-database.out
@@ -0,0 +1,105 @@
+Parsed test spec with 2 sessions
+
+starting permutation: s1_begin s1_alterdb_with s2_begin s2_alterdb_with 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_alterdb_with: 
+       ALTER DATABASE regress_database WITH ALLOW_CONNECTIONS true;
+step s2_begin: BEGIN;
+step s2_alterdb_with: 
+       ALTER DATABASE regress_database WITH ALLOW_CONNECTIONS true; <waiting 
...>
+step s1_commit: COMMIT;
+step s2_alterdb_with: <... completed>
+error in steps s1_commit s2_alterdb_with: ERROR:  tuple concurrently updated
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_alterdb_with s2_begin s2_alterdb_set 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_alterdb_with: 
+       ALTER DATABASE regress_database WITH ALLOW_CONNECTIONS true;
+step s2_begin: BEGIN;
+step s2_alterdb_set: 
+       ALTER DATABASE regress_database SET commit_delay = '10';
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_alterdb_with s2_begin s2_alterdb_owner 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_alterdb_with: 
+       ALTER DATABASE regress_database WITH ALLOW_CONNECTIONS true;
+step s2_begin: BEGIN;
+step s2_alterdb_owner: 
+       ALTER DATABASE regress_database OWNER TO CURRENT_USER;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_alterdb_with s2_begin s2_alterdb_tbc 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_alterdb_with: 
+       ALTER DATABASE regress_database WITH ALLOW_CONNECTIONS true;
+step s2_begin: BEGIN;
+step s2_alterdb_tbc: 
+       ALTER DATABASE regress_database SET TABLESPACE TO DEFAULT;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_alterdb_set s2_begin s2_alterdb_set 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_alterdb_set: 
+       ALTER DATABASE regress_database SET commit_delay = '10';
+step s2_begin: BEGIN;
+step s2_alterdb_set: 
+       ALTER DATABASE regress_database SET commit_delay = '10'; <waiting ...>
+step s1_commit: COMMIT;
+step s2_alterdb_set: <... completed>
+error in steps s1_commit s2_alterdb_set: ERROR:  duplicate key value violates 
unique constraint "pg_db_role_setting_databaseid_rol_index"
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_alterdb_set s2_begin s2_alterdb_owner 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_alterdb_set: 
+       ALTER DATABASE regress_database SET commit_delay = '10';
+step s2_begin: BEGIN;
+step s2_alterdb_owner: 
+       ALTER DATABASE regress_database OWNER TO CURRENT_USER;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_alterdb_set s2_begin s2_alterdb_tbc 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_alterdb_set: 
+       ALTER DATABASE regress_database SET commit_delay = '10';
+step s2_begin: BEGIN;
+step s2_alterdb_tbc: 
+       ALTER DATABASE regress_database SET TABLESPACE TO DEFAULT;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_alterdb_owner s2_begin s2_alterdb_owner 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_alterdb_owner: 
+       ALTER DATABASE regress_database OWNER TO CURRENT_USER;
+step s2_begin: BEGIN;
+step s2_alterdb_owner: 
+       ALTER DATABASE regress_database OWNER TO CURRENT_USER;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_alterdb_owner s2_begin s2_alterdb_tbc 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_alterdb_owner: 
+       ALTER DATABASE regress_database OWNER TO CURRENT_USER;
+step s2_begin: BEGIN;
+step s2_alterdb_tbc: 
+       ALTER DATABASE regress_database SET TABLESPACE TO DEFAULT;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_alterdb_tbc s2_begin s2_alterdb_tbc 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_alterdb_tbc: 
+       ALTER DATABASE regress_database SET TABLESPACE TO DEFAULT;
+step s2_begin: BEGIN;
+step s2_alterdb_tbc: 
+       ALTER DATABASE regress_database SET TABLESPACE TO DEFAULT;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
diff --git a/src/test/isolation/expected/concurrent-domain.out 
b/src/test/isolation/expected/concurrent-domain.out
new file mode 100644
index 0000000000..caf7902d45
--- /dev/null
+++ b/src/test/isolation/expected/concurrent-domain.out
@@ -0,0 +1,519 @@
+Parsed test spec with 2 sessions
+
+starting permutation: s1_begin s1_dom_set_notnull s2_begin s2_dom_set_notnull 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_set_notnull: 
+       ALTER DOMAIN regress_domain_conc SET NOT NULL;
+step s2_begin: BEGIN;
+step s2_dom_set_notnull: 
+       ALTER DOMAIN regress_domain_conc SET NOT NULL; <waiting ...>
+step s1_commit: COMMIT;
+step s2_dom_set_notnull: <... completed>
+error in steps s1_commit s2_dom_set_notnull: ERROR:  tuple concurrently updated
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_set_notnull s2_begin s2_dom_drop_notnull 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_set_notnull: 
+       ALTER DOMAIN regress_domain_conc SET NOT NULL;
+step s2_begin: BEGIN;
+step s2_dom_drop_notnull: 
+       ALTER DOMAIN regress_domain_conc DROP NOT NULL;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_set_notnull s2_begin s2_dom_set_default 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_set_notnull: 
+       ALTER DOMAIN regress_domain_conc SET NOT NULL;
+step s2_begin: BEGIN;
+step s2_dom_set_default: 
+       ALTER DOMAIN regress_domain_conc SET DEFAULT 1; <waiting ...>
+step s1_commit: COMMIT;
+step s2_dom_set_default: <... completed>
+error in steps s1_commit s2_dom_set_default: ERROR:  tuple concurrently updated
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_set_notnull s2_begin s2_dom_drop_default 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_set_notnull: 
+       ALTER DOMAIN regress_domain_conc SET NOT NULL;
+step s2_begin: BEGIN;
+step s2_dom_drop_default: 
+       ALTER DOMAIN regress_domain_conc DROP DEFAULT; <waiting ...>
+step s1_commit: COMMIT;
+step s2_dom_drop_default: <... completed>
+error in steps s1_commit s2_dom_drop_default: ERROR:  tuple concurrently 
updated
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_set_notnull s2_begin s2_dom_add_con 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_set_notnull: 
+       ALTER DOMAIN regress_domain_conc SET NOT NULL;
+step s2_begin: BEGIN;
+step s2_dom_add_con: 
+       ALTER DOMAIN regress_domain_conc ADD CONSTRAINT dom_con CHECK (VALUE > 
0);
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_set_notnull s2_begin s2_dom_owner 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_set_notnull: 
+       ALTER DOMAIN regress_domain_conc SET NOT NULL;
+step s2_begin: BEGIN;
+step s2_dom_owner: 
+       ALTER DOMAIN regress_domain_conc OWNER TO CURRENT_USER;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_set_notnull s2_begin s2_dom_schema_priv 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_set_notnull: 
+       ALTER DOMAIN regress_domain_conc SET NOT NULL;
+step s2_begin: BEGIN;
+step s2_dom_schema_priv: 
+       ALTER DOMAIN regress_domain_conc SET SCHEMA regress_domain_schema; 
<waiting ...>
+step s1_commit: COMMIT;
+step s2_dom_schema_priv: <... completed>
+error in steps s1_commit s2_dom_schema_priv: ERROR:  tuple concurrently updated
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_set_notnull s2_begin s2_dom_schema_publ 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_set_notnull: 
+       ALTER DOMAIN regress_domain_conc SET NOT NULL;
+step s2_begin: BEGIN;
+step s2_dom_schema_publ: 
+       ALTER DOMAIN regress_domain_conc SET SCHEMA public;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_drop_notnull s2_begin 
s2_dom_drop_notnull s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_drop_notnull: 
+       ALTER DOMAIN regress_domain_conc DROP NOT NULL;
+step s2_begin: BEGIN;
+step s2_dom_drop_notnull: 
+       ALTER DOMAIN regress_domain_conc DROP NOT NULL;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_drop_notnull s2_begin s2_dom_set_default 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_drop_notnull: 
+       ALTER DOMAIN regress_domain_conc DROP NOT NULL;
+step s2_begin: BEGIN;
+step s2_dom_set_default: 
+       ALTER DOMAIN regress_domain_conc SET DEFAULT 1;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_drop_notnull s2_begin 
s2_dom_drop_default s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_drop_notnull: 
+       ALTER DOMAIN regress_domain_conc DROP NOT NULL;
+step s2_begin: BEGIN;
+step s2_dom_drop_default: 
+       ALTER DOMAIN regress_domain_conc DROP DEFAULT;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_drop_notnull s2_begin s2_dom_add_con 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_drop_notnull: 
+       ALTER DOMAIN regress_domain_conc DROP NOT NULL;
+step s2_begin: BEGIN;
+step s2_dom_add_con: 
+       ALTER DOMAIN regress_domain_conc ADD CONSTRAINT dom_con CHECK (VALUE > 
0);
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_drop_notnull s2_begin s2_dom_owner 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_drop_notnull: 
+       ALTER DOMAIN regress_domain_conc DROP NOT NULL;
+step s2_begin: BEGIN;
+step s2_dom_owner: 
+       ALTER DOMAIN regress_domain_conc OWNER TO CURRENT_USER;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_drop_notnull s2_begin s2_dom_schema_priv 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_drop_notnull: 
+       ALTER DOMAIN regress_domain_conc DROP NOT NULL;
+step s2_begin: BEGIN;
+step s2_dom_schema_priv: 
+       ALTER DOMAIN regress_domain_conc SET SCHEMA regress_domain_schema;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_drop_notnull s2_begin s2_dom_schema_publ 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_drop_notnull: 
+       ALTER DOMAIN regress_domain_conc DROP NOT NULL;
+step s2_begin: BEGIN;
+step s2_dom_schema_publ: 
+       ALTER DOMAIN regress_domain_conc SET SCHEMA public;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_set_default s2_begin s2_dom_set_default 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_set_default: 
+       ALTER DOMAIN regress_domain_conc SET DEFAULT 1;
+step s2_begin: BEGIN;
+step s2_dom_set_default: 
+       ALTER DOMAIN regress_domain_conc SET DEFAULT 1; <waiting ...>
+step s1_commit: COMMIT;
+step s2_dom_set_default: <... completed>
+error in steps s1_commit s2_dom_set_default: ERROR:  tuple concurrently updated
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_set_default s2_begin s2_dom_drop_default 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_set_default: 
+       ALTER DOMAIN regress_domain_conc SET DEFAULT 1;
+step s2_begin: BEGIN;
+step s2_dom_drop_default: 
+       ALTER DOMAIN regress_domain_conc DROP DEFAULT; <waiting ...>
+step s1_commit: COMMIT;
+step s2_dom_drop_default: <... completed>
+error in steps s1_commit s2_dom_drop_default: ERROR:  tuple concurrently 
updated
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_set_default s2_begin s2_dom_add_con 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_set_default: 
+       ALTER DOMAIN regress_domain_conc SET DEFAULT 1;
+step s2_begin: BEGIN;
+step s2_dom_add_con: 
+       ALTER DOMAIN regress_domain_conc ADD CONSTRAINT dom_con CHECK (VALUE > 
0);
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_set_default s2_begin s2_dom_owner 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_set_default: 
+       ALTER DOMAIN regress_domain_conc SET DEFAULT 1;
+step s2_begin: BEGIN;
+step s2_dom_owner: 
+       ALTER DOMAIN regress_domain_conc OWNER TO CURRENT_USER;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_set_default s2_begin s2_dom_schema_priv 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_set_default: 
+       ALTER DOMAIN regress_domain_conc SET DEFAULT 1;
+step s2_begin: BEGIN;
+step s2_dom_schema_priv: 
+       ALTER DOMAIN regress_domain_conc SET SCHEMA regress_domain_schema; 
<waiting ...>
+step s1_commit: COMMIT;
+step s2_dom_schema_priv: <... completed>
+error in steps s1_commit s2_dom_schema_priv: ERROR:  tuple concurrently updated
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_set_default s2_begin s2_dom_schema_publ 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_set_default: 
+       ALTER DOMAIN regress_domain_conc SET DEFAULT 1;
+step s2_begin: BEGIN;
+step s2_dom_schema_publ: 
+       ALTER DOMAIN regress_domain_conc SET SCHEMA public;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_drop_default s2_begin 
s2_dom_drop_default s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_drop_default: 
+       ALTER DOMAIN regress_domain_conc DROP DEFAULT;
+step s2_begin: BEGIN;
+step s2_dom_drop_default: 
+       ALTER DOMAIN regress_domain_conc DROP DEFAULT; <waiting ...>
+step s1_commit: COMMIT;
+step s2_dom_drop_default: <... completed>
+error in steps s1_commit s2_dom_drop_default: ERROR:  tuple concurrently 
updated
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_drop_default s2_begin s2_dom_add_con 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_drop_default: 
+       ALTER DOMAIN regress_domain_conc DROP DEFAULT;
+step s2_begin: BEGIN;
+step s2_dom_add_con: 
+       ALTER DOMAIN regress_domain_conc ADD CONSTRAINT dom_con CHECK (VALUE > 
0);
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_drop_default s2_begin s2_dom_owner 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_drop_default: 
+       ALTER DOMAIN regress_domain_conc DROP DEFAULT;
+step s2_begin: BEGIN;
+step s2_dom_owner: 
+       ALTER DOMAIN regress_domain_conc OWNER TO CURRENT_USER;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_drop_default s2_begin s2_dom_schema_priv 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_drop_default: 
+       ALTER DOMAIN regress_domain_conc DROP DEFAULT;
+step s2_begin: BEGIN;
+step s2_dom_schema_priv: 
+       ALTER DOMAIN regress_domain_conc SET SCHEMA regress_domain_schema; 
<waiting ...>
+step s1_commit: COMMIT;
+step s2_dom_schema_priv: <... completed>
+error in steps s1_commit s2_dom_schema_priv: ERROR:  tuple concurrently updated
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_drop_default s2_begin s2_dom_schema_publ 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_drop_default: 
+       ALTER DOMAIN regress_domain_conc DROP DEFAULT;
+step s2_begin: BEGIN;
+step s2_dom_schema_publ: 
+       ALTER DOMAIN regress_domain_conc SET SCHEMA public;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_add_con s2_begin s2_dom_add_con2 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_add_con: 
+       ALTER DOMAIN regress_domain_conc ADD CONSTRAINT dom_con CHECK (VALUE > 
0);
+step s2_begin: BEGIN;
+step s2_dom_add_con2: 
+       ALTER DOMAIN regress_domain_conc ADD CONSTRAINT dom_con2 CHECK (VALUE > 
0);
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_add_con s2_begin s2_dom_drop_con 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_add_con: 
+       ALTER DOMAIN regress_domain_conc ADD CONSTRAINT dom_con CHECK (VALUE > 
0);
+step s2_begin: BEGIN;
+step s2_dom_drop_con: 
+       ALTER DOMAIN regress_domain_conc DROP CONSTRAINT dom_con;
+ERROR:  constraint "dom_con" of domain "regress_domain_conc" does not exist
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_add_con s2_begin s2_dom_validate_con 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_add_con: 
+       ALTER DOMAIN regress_domain_conc ADD CONSTRAINT dom_con CHECK (VALUE > 
0);
+step s2_begin: BEGIN;
+step s2_dom_validate_con: 
+       ALTER DOMAIN regress_domain_conc VALIDATE CONSTRAINT dom_con;
+ERROR:  constraint "dom_con" of domain "regress_domain_conc" does not exist
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_add_con s2_begin s2_dom_owner s1_commit 
s2_commit
+step s1_begin: BEGIN;
+step s1_dom_add_con: 
+       ALTER DOMAIN regress_domain_conc ADD CONSTRAINT dom_con CHECK (VALUE > 
0);
+step s2_begin: BEGIN;
+step s2_dom_owner: 
+       ALTER DOMAIN regress_domain_conc OWNER TO CURRENT_USER;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_add_con s2_begin s2_dom_schema_priv 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_add_con: 
+       ALTER DOMAIN regress_domain_conc ADD CONSTRAINT dom_con CHECK (VALUE > 
0);
+step s2_begin: BEGIN;
+step s2_dom_schema_priv: 
+       ALTER DOMAIN regress_domain_conc SET SCHEMA regress_domain_schema;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_add_con s2_begin s2_dom_schema_publ 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_add_con: 
+       ALTER DOMAIN regress_domain_conc ADD CONSTRAINT dom_con CHECK (VALUE > 
0);
+step s2_begin: BEGIN;
+step s2_dom_schema_publ: 
+       ALTER DOMAIN regress_domain_conc SET SCHEMA public;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_dom_add_con s1_begin s1_dom_drop_con s2_begin 
s2_dom_drop_con s1_commit s2_commit
+step s1_dom_add_con: 
+       ALTER DOMAIN regress_domain_conc ADD CONSTRAINT dom_con CHECK (VALUE > 
0);
+step s1_begin: BEGIN;
+step s1_dom_drop_con: 
+       ALTER DOMAIN regress_domain_conc DROP CONSTRAINT dom_con;
+step s2_begin: BEGIN;
+step s2_dom_drop_con: 
+       ALTER DOMAIN regress_domain_conc DROP CONSTRAINT dom_con; <waiting ...>
+step s1_commit: COMMIT;
+step s2_dom_drop_con: <... completed>
+error in steps s1_commit s2_dom_drop_con: ERROR:  cache lookup failed for 
constraint 16509
+step s2_commit: COMMIT;
+
+starting permutation: s1_dom_add_con s1_begin s1_dom_drop_con s2_begin 
s2_dom_validate_con s1_commit s2_commit
+step s1_dom_add_con: 
+       ALTER DOMAIN regress_domain_conc ADD CONSTRAINT dom_con CHECK (VALUE > 
0);
+step s1_begin: BEGIN;
+step s1_dom_drop_con: 
+       ALTER DOMAIN regress_domain_conc DROP CONSTRAINT dom_con;
+step s2_begin: BEGIN;
+step s2_dom_validate_con: 
+       ALTER DOMAIN regress_domain_conc VALIDATE CONSTRAINT dom_con; <waiting 
...>
+step s1_commit: COMMIT;
+step s2_dom_validate_con: <... completed>
+error in steps s1_commit s2_dom_validate_con: ERROR:  tuple concurrently 
updated
+step s2_commit: COMMIT;
+
+starting permutation: s1_dom_add_con s1_begin s1_dom_drop_con s2_begin 
s2_dom_owner s1_commit s2_commit
+step s1_dom_add_con: 
+       ALTER DOMAIN regress_domain_conc ADD CONSTRAINT dom_con CHECK (VALUE > 
0);
+step s1_begin: BEGIN;
+step s1_dom_drop_con: 
+       ALTER DOMAIN regress_domain_conc DROP CONSTRAINT dom_con;
+step s2_begin: BEGIN;
+step s2_dom_owner: 
+       ALTER DOMAIN regress_domain_conc OWNER TO CURRENT_USER;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_dom_add_con s1_begin s1_dom_drop_con s2_begin 
s2_dom_schema_publ s1_commit s2_commit
+step s1_dom_add_con: 
+       ALTER DOMAIN regress_domain_conc ADD CONSTRAINT dom_con CHECK (VALUE > 
0);
+step s1_begin: BEGIN;
+step s1_dom_drop_con: 
+       ALTER DOMAIN regress_domain_conc DROP CONSTRAINT dom_con;
+step s2_begin: BEGIN;
+step s2_dom_schema_publ: 
+       ALTER DOMAIN regress_domain_conc SET SCHEMA public;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_dom_add_con s1_begin s1_dom_drop_con s2_begin 
s2_dom_schema_priv s1_commit s2_commit
+step s1_dom_add_con: 
+       ALTER DOMAIN regress_domain_conc ADD CONSTRAINT dom_con CHECK (VALUE > 
0);
+step s1_begin: BEGIN;
+step s1_dom_drop_con: 
+       ALTER DOMAIN regress_domain_conc DROP CONSTRAINT dom_con;
+step s2_begin: BEGIN;
+step s2_dom_schema_priv: 
+       ALTER DOMAIN regress_domain_conc SET SCHEMA regress_domain_schema; 
<waiting ...>
+step s1_commit: COMMIT;
+step s2_dom_schema_priv: <... completed>
+error in steps s1_commit s2_dom_schema_priv: ERROR:  tuple concurrently updated
+step s2_commit: COMMIT;
+
+starting permutation: s1_dom_add_con s1_begin s1_dom_validate_con s2_begin 
s2_dom_validate_con s1_commit s2_commit
+step s1_dom_add_con: 
+       ALTER DOMAIN regress_domain_conc ADD CONSTRAINT dom_con CHECK (VALUE > 
0);
+step s1_begin: BEGIN;
+step s1_dom_validate_con: 
+       ALTER DOMAIN regress_domain_conc VALIDATE CONSTRAINT dom_con;
+step s2_begin: BEGIN;
+step s2_dom_validate_con: 
+       ALTER DOMAIN regress_domain_conc VALIDATE CONSTRAINT dom_con; <waiting 
...>
+step s1_commit: COMMIT;
+step s2_dom_validate_con: <... completed>
+error in steps s1_commit s2_dom_validate_con: ERROR:  tuple concurrently 
updated
+step s2_commit: COMMIT;
+
+starting permutation: s1_dom_add_con s1_begin s1_dom_validate_con s2_begin 
s2_dom_owner s1_commit s2_commit
+step s1_dom_add_con: 
+       ALTER DOMAIN regress_domain_conc ADD CONSTRAINT dom_con CHECK (VALUE > 
0);
+step s1_begin: BEGIN;
+step s1_dom_validate_con: 
+       ALTER DOMAIN regress_domain_conc VALIDATE CONSTRAINT dom_con;
+step s2_begin: BEGIN;
+step s2_dom_owner: 
+       ALTER DOMAIN regress_domain_conc OWNER TO CURRENT_USER;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_dom_add_con s1_begin s1_dom_validate_con s2_begin 
s2_dom_schema_priv s1_commit s2_commit
+step s1_dom_add_con: 
+       ALTER DOMAIN regress_domain_conc ADD CONSTRAINT dom_con CHECK (VALUE > 
0);
+step s1_begin: BEGIN;
+step s1_dom_validate_con: 
+       ALTER DOMAIN regress_domain_conc VALIDATE CONSTRAINT dom_con;
+step s2_begin: BEGIN;
+step s2_dom_schema_priv: 
+       ALTER DOMAIN regress_domain_conc SET SCHEMA regress_domain_schema; 
<waiting ...>
+step s1_commit: COMMIT;
+step s2_dom_schema_priv: <... completed>
+error in steps s1_commit s2_dom_schema_priv: ERROR:  tuple concurrently updated
+step s2_commit: COMMIT;
+
+starting permutation: s1_dom_add_con s1_begin s1_dom_validate_con s2_begin 
s2_dom_schema_publ s1_commit s2_commit
+step s1_dom_add_con: 
+       ALTER DOMAIN regress_domain_conc ADD CONSTRAINT dom_con CHECK (VALUE > 
0);
+step s1_begin: BEGIN;
+step s1_dom_validate_con: 
+       ALTER DOMAIN regress_domain_conc VALIDATE CONSTRAINT dom_con;
+step s2_begin: BEGIN;
+step s2_dom_schema_publ: 
+       ALTER DOMAIN regress_domain_conc SET SCHEMA public;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_owner s2_begin s2_dom_owner s1_commit 
s2_commit
+step s1_begin: BEGIN;
+step s1_dom_owner: 
+       ALTER DOMAIN regress_domain_conc OWNER TO CURRENT_USER;
+step s2_begin: BEGIN;
+step s2_dom_owner: 
+       ALTER DOMAIN regress_domain_conc OWNER TO CURRENT_USER;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_owner s2_begin s2_dom_schema_priv 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_owner: 
+       ALTER DOMAIN regress_domain_conc OWNER TO CURRENT_USER;
+step s2_begin: BEGIN;
+step s2_dom_schema_priv: 
+       ALTER DOMAIN regress_domain_conc SET SCHEMA regress_domain_schema;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_owner s2_begin s2_dom_schema_publ 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_owner: 
+       ALTER DOMAIN regress_domain_conc OWNER TO CURRENT_USER;
+step s2_begin: BEGIN;
+step s2_dom_schema_publ: 
+       ALTER DOMAIN regress_domain_conc SET SCHEMA public;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_schema_priv s2_begin s2_dom_schema_publ 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_schema_priv: 
+       ALTER DOMAIN regress_domain_conc SET SCHEMA regress_domain_schema;
+step s2_begin: BEGIN;
+step s2_dom_schema_publ: 
+       ALTER DOMAIN regress_domain_conc SET SCHEMA public;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_schema_publ s2_begin s2_dom_schema_priv 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_schema_publ: 
+       ALTER DOMAIN regress_domain_conc SET SCHEMA public;
+step s2_begin: BEGIN;
+step s2_dom_schema_priv: 
+       ALTER DOMAIN regress_domain_conc SET SCHEMA regress_domain_schema;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_dom_schema_publ s2_begin s2_dom_schema_publ 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_dom_schema_publ: 
+       ALTER DOMAIN regress_domain_conc SET SCHEMA public;
+step s2_begin: BEGIN;
+step s2_dom_schema_publ: 
+       ALTER DOMAIN regress_domain_conc SET SCHEMA public;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
diff --git a/src/test/isolation/expected/concurrent-event-trigger.out 
b/src/test/isolation/expected/concurrent-event-trigger.out
new file mode 100644
index 0000000000..43dca2d8af
--- /dev/null
+++ b/src/test/isolation/expected/concurrent-event-trigger.out
@@ -0,0 +1,55 @@
+Parsed test spec with 2 sessions
+
+starting permutation: s1_begin s1_disable s2_begin s2_disable s1_commit 
s2_commit
+step s1_begin: BEGIN;
+step s1_disable: ALTER EVENT TRIGGER notice_ddl DISABLE;
+step s2_begin: BEGIN;
+step s2_disable: ALTER EVENT TRIGGER notice_ddl DISABLE; <waiting ...>
+step s1_commit: COMMIT;
+step s2_disable: <... completed>
+error in steps s1_commit s2_disable: ERROR:  tuple concurrently updated
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_disable s2_begin s2_enable s1_commit 
s2_commit
+step s1_begin: BEGIN;
+step s1_disable: ALTER EVENT TRIGGER notice_ddl DISABLE;
+step s2_begin: BEGIN;
+step s2_enable: ALTER EVENT TRIGGER notice_ddl ENABLE REPLICA; <waiting ...>
+step s1_commit: COMMIT;
+step s2_enable: <... completed>
+error in steps s1_commit s2_enable: ERROR:  tuple concurrently updated
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_disable s2_begin s2_owner s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_disable: ALTER EVENT TRIGGER notice_ddl DISABLE;
+step s2_begin: BEGIN;
+step s2_owner: ALTER EVENT TRIGGER notice_ddl OWNER TO CURRENT_USER;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_enable s2_begin s2_enable s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_enable: ALTER EVENT TRIGGER notice_ddl ENABLE REPLICA;
+step s2_begin: BEGIN;
+step s2_enable: ALTER EVENT TRIGGER notice_ddl ENABLE REPLICA; <waiting ...>
+step s1_commit: COMMIT;
+step s2_enable: <... completed>
+error in steps s1_commit s2_enable: ERROR:  tuple concurrently updated
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_enable s2_begin s2_owner s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_enable: ALTER EVENT TRIGGER notice_ddl ENABLE REPLICA;
+step s2_begin: BEGIN;
+step s2_owner: ALTER EVENT TRIGGER notice_ddl OWNER TO CURRENT_USER;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_owner s2_begin s2_owner s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_owner: ALTER EVENT TRIGGER notice_ddl OWNER TO CURRENT_USER;
+step s2_begin: BEGIN;
+step s2_owner: ALTER EVENT TRIGGER notice_ddl OWNER TO CURRENT_USER;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
diff --git a/src/test/isolation/expected/concurrent-fdw.out 
b/src/test/isolation/expected/concurrent-fdw.out
new file mode 100644
index 0000000000..9c3724df34
--- /dev/null
+++ b/src/test/isolation/expected/concurrent-fdw.out
@@ -0,0 +1,118 @@
+Parsed test spec with 2 sessions
+
+starting permutation: s1_begin s1_options s2_begin s2_options s1_commit 
s2_commit
+step s1_begin: BEGIN;
+step s1_options: 
+       ALTER FOREIGN DATA WRAPPER regress_fdw OPTIONS (a '1');
+step s2_begin: BEGIN;
+step s2_options: 
+       ALTER FOREIGN DATA WRAPPER regress_fdw OPTIONS (a '1'); <waiting ...>
+step s1_commit: COMMIT;
+step s2_options: <... completed>
+error in steps s1_commit s2_options: ERROR:  tuple concurrently updated
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_options s2_begin s2_validator s1_commit 
s2_commit
+step s1_begin: BEGIN;
+step s1_options: 
+       ALTER FOREIGN DATA WRAPPER regress_fdw OPTIONS (a '1');
+step s2_begin: BEGIN;
+step s2_validator: 
+       ALTER FOREIGN DATA WRAPPER regress_fdw NO VALIDATOR; <waiting ...>
+step s1_commit: COMMIT;
+step s2_validator: <... completed>
+error in steps s1_commit s2_validator: ERROR:  tuple concurrently updated
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_options s2_begin s2_handler s1_commit 
s2_commit
+step s1_begin: BEGIN;
+step s1_options: 
+       ALTER FOREIGN DATA WRAPPER regress_fdw OPTIONS (a '1');
+step s2_begin: BEGIN;
+WARNING:  changing the foreign-data wrapper handler can change behavior of 
existing foreign tables
+step s2_handler: 
+       ALTER FOREIGN DATA WRAPPER regress_fdw NO HANDLER; <waiting ...>
+step s1_commit: COMMIT;
+step s2_handler: <... completed>
+error in steps s1_commit s2_handler: ERROR:  tuple concurrently updated
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_options s2_begin s2_owner s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_options: 
+       ALTER FOREIGN DATA WRAPPER regress_fdw OPTIONS (a '1');
+step s2_begin: BEGIN;
+step s2_owner: 
+       ALTER FOREIGN DATA WRAPPER regress_fdw OWNER TO CURRENT_USER;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_validator s2_begin s2_validator s1_commit 
s2_commit
+step s1_begin: BEGIN;
+step s1_validator: 
+       ALTER FOREIGN DATA WRAPPER regress_fdw NO VALIDATOR;
+step s2_begin: BEGIN;
+step s2_validator: 
+       ALTER FOREIGN DATA WRAPPER regress_fdw NO VALIDATOR; <waiting ...>
+step s1_commit: COMMIT;
+step s2_validator: <... completed>
+error in steps s1_commit s2_validator: ERROR:  tuple concurrently updated
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_validator s2_begin s2_handler s1_commit 
s2_commit
+step s1_begin: BEGIN;
+step s1_validator: 
+       ALTER FOREIGN DATA WRAPPER regress_fdw NO VALIDATOR;
+step s2_begin: BEGIN;
+WARNING:  changing the foreign-data wrapper handler can change behavior of 
existing foreign tables
+step s2_handler: 
+       ALTER FOREIGN DATA WRAPPER regress_fdw NO HANDLER; <waiting ...>
+step s1_commit: COMMIT;
+step s2_handler: <... completed>
+error in steps s1_commit s2_handler: ERROR:  tuple concurrently updated
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_validator s2_begin s2_owner s1_commit 
s2_commit
+step s1_begin: BEGIN;
+step s1_validator: 
+       ALTER FOREIGN DATA WRAPPER regress_fdw NO VALIDATOR;
+step s2_begin: BEGIN;
+step s2_owner: 
+       ALTER FOREIGN DATA WRAPPER regress_fdw OWNER TO CURRENT_USER;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_handler s2_begin s2_handler s1_commit 
s2_commit
+step s1_begin: BEGIN;
+WARNING:  changing the foreign-data wrapper handler can change behavior of 
existing foreign tables
+step s1_handler: 
+       ALTER FOREIGN DATA WRAPPER regress_fdw NO HANDLER;
+step s2_begin: BEGIN;
+WARNING:  changing the foreign-data wrapper handler can change behavior of 
existing foreign tables
+step s2_handler: 
+       ALTER FOREIGN DATA WRAPPER regress_fdw NO HANDLER; <waiting ...>
+step s1_commit: COMMIT;
+step s2_handler: <... completed>
+error in steps s1_commit s2_handler: ERROR:  tuple concurrently updated
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_handler s2_begin s2_owner s1_commit s2_commit
+step s1_begin: BEGIN;
+WARNING:  changing the foreign-data wrapper handler can change behavior of 
existing foreign tables
+step s1_handler: 
+       ALTER FOREIGN DATA WRAPPER regress_fdw NO HANDLER;
+step s2_begin: BEGIN;
+step s2_owner: 
+       ALTER FOREIGN DATA WRAPPER regress_fdw OWNER TO CURRENT_USER;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_owner s2_begin s2_owner s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_owner: 
+       ALTER FOREIGN DATA WRAPPER regress_fdw OWNER TO CURRENT_USER;
+step s2_begin: BEGIN;
+step s2_owner: 
+       ALTER FOREIGN DATA WRAPPER regress_fdw OWNER TO CURRENT_USER;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
diff --git a/src/test/isolation/expected/concurrent-role.out 
b/src/test/isolation/expected/concurrent-role.out
new file mode 100644
index 0000000000..86bf17365d
--- /dev/null
+++ b/src/test/isolation/expected/concurrent-role.out
@@ -0,0 +1,45 @@
+Parsed test spec with 2 sessions
+
+starting permutation: s1_begin s1_alterrole_set s2_begin s2_alterrole_set 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_alterrole_set: 
+       ALTER ROLE regress_role_conc SET commit_delay = '10';
+step s2_begin: BEGIN;
+step s2_alterrole_set: 
+       ALTER ROLE regress_role_conc SET commit_delay = '10'; <waiting ...>
+step s1_commit: COMMIT;
+step s2_alterrole_set: <... completed>
+error in steps s1_commit s2_alterrole_set: ERROR:  duplicate key value 
violates unique constraint "pg_db_role_setting_databaseid_rol_index"
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_alterrole_set s2_begin s2_alterrole_opt 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_alterrole_set: 
+       ALTER ROLE regress_role_conc SET commit_delay = '10';
+step s2_begin: BEGIN;
+step s2_alterrole_opt: 
+       ALTER ROLE regress_role_conc PASSWORD 'foo';
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_alterrole_opt s2_begin s2_alterrole_set 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_alterrole_opt: 
+       ALTER ROLE regress_role_conc PASSWORD 'foo';
+step s2_begin: BEGIN;
+step s2_alterrole_set: 
+       ALTER ROLE regress_role_conc SET commit_delay = '10';
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_alterrole_opt s2_begin s2_alterrole_opt 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_alterrole_opt: 
+       ALTER ROLE regress_role_conc PASSWORD 'foo';
+step s2_begin: BEGIN;
+step s2_alterrole_opt: 
+       ALTER ROLE regress_role_conc PASSWORD 'foo'; <waiting ...>
+step s1_commit: COMMIT;
+step s2_alterrole_opt: <... completed>
+error in steps s1_commit s2_alterrole_opt: ERROR:  tuple concurrently updated
+step s2_commit: COMMIT;
diff --git a/src/test/isolation/expected/concurrent-server.out 
b/src/test/isolation/expected/concurrent-server.out
new file mode 100644
index 0000000000..303569f6ce
--- /dev/null
+++ b/src/test/isolation/expected/concurrent-server.out
@@ -0,0 +1,33 @@
+Parsed test spec with 2 sessions
+
+starting permutation: s1_begin s1_options s2_begin s2_options s1_commit 
s2_commit
+step s1_begin: BEGIN;
+step s1_options: 
+       ALTER SERVER regress_server OPTIONS (a '1');
+step s2_begin: BEGIN;
+step s2_options: 
+       ALTER SERVER regress_server OPTIONS (a '1'); <waiting ...>
+step s1_commit: COMMIT;
+step s2_options: <... completed>
+error in steps s1_commit s2_options: ERROR:  tuple concurrently updated
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_options s2_begin s2_owner s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_options: 
+       ALTER SERVER regress_server OPTIONS (a '1');
+step s2_begin: BEGIN;
+step s2_owner: 
+       ALTER SERVER regress_server OWNER TO CURRENT_USER;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_owner s2_begin s2_owner s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_owner: 
+       ALTER SERVER regress_server OWNER TO CURRENT_USER;
+step s2_begin: BEGIN;
+step s2_owner: 
+       ALTER SERVER regress_server OWNER TO CURRENT_USER;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
diff --git a/src/test/isolation/expected/concurrent-type.out 
b/src/test/isolation/expected/concurrent-type.out
new file mode 100644
index 0000000000..45dbbcd130
--- /dev/null
+++ b/src/test/isolation/expected/concurrent-type.out
@@ -0,0 +1,229 @@
+Parsed test spec with 2 sessions
+
+starting permutation: s1_begin s1_add_attr s2_begin s2_add_attr s1_commit 
s2_commit
+step s1_begin: BEGIN;
+step s1_add_attr: 
+       ALTER TYPE regress_type ADD ATTRIBUTE b1 int;
+step s2_begin: BEGIN;
+step s2_add_attr: 
+       ALTER TYPE regress_type ADD ATTRIBUTE b2 int; <waiting ...>
+step s1_commit: COMMIT;
+step s2_add_attr: <... completed>
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_add_attr s2_begin s2_drop_attr s1_commit 
s2_commit
+step s1_begin: BEGIN;
+step s1_add_attr: 
+       ALTER TYPE regress_type ADD ATTRIBUTE b1 int;
+step s2_begin: BEGIN;
+step s2_drop_attr: 
+       ALTER TYPE regress_type DROP ATTRIBUTE a; <waiting ...>
+step s1_commit: COMMIT;
+step s2_drop_attr: <... completed>
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_add_attr s2_begin s2_alter_attr s1_commit 
s2_commit
+step s1_begin: BEGIN;
+step s1_add_attr: 
+       ALTER TYPE regress_type ADD ATTRIBUTE b1 int;
+step s2_begin: BEGIN;
+step s2_alter_attr: 
+       ALTER TYPE regress_type ALTER ATTRIBUTE a TYPE int8; <waiting ...>
+step s1_commit: COMMIT;
+step s2_alter_attr: <... completed>
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_add_attr s2_begin s2_rename_attr s1_commit 
s2_commit
+step s1_begin: BEGIN;
+step s1_add_attr: 
+       ALTER TYPE regress_type ADD ATTRIBUTE b1 int;
+step s2_begin: BEGIN;
+step s2_rename_attr: 
+       ALTER TYPE regress_type RENAME ATTRIBUTE a TO b; <waiting ...>
+step s1_commit: COMMIT;
+step s2_rename_attr: <... completed>
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_add_attr s2_begin s2_owner s1_commit 
s2_commit
+step s1_begin: BEGIN;
+step s1_add_attr: 
+       ALTER TYPE regress_type ADD ATTRIBUTE b1 int;
+step s2_begin: BEGIN;
+step s2_owner: 
+       ALTER TYPE regress_type OWNER TO CURRENT_USER;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_add_attr s2_begin s2_schema s1_commit 
s2_commit
+step s1_begin: BEGIN;
+step s1_add_attr: 
+       ALTER TYPE regress_type ADD ATTRIBUTE b1 int;
+step s2_begin: BEGIN;
+step s2_schema: 
+       ALTER TYPE regress_type SET SCHEMA regress_type_schema; <waiting ...>
+step s1_commit: COMMIT;
+step s2_schema: <... completed>
+error in steps s1_commit s2_schema: ERROR:  tuple concurrently updated
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_drop_attr s2_begin s2_drop_attr s1_commit 
s2_commit
+step s1_begin: BEGIN;
+step s1_drop_attr: 
+       ALTER TYPE regress_type DROP ATTRIBUTE a;
+step s2_begin: BEGIN;
+step s2_drop_attr: 
+       ALTER TYPE regress_type DROP ATTRIBUTE a; <waiting ...>
+step s1_commit: COMMIT;
+step s2_drop_attr: <... completed>
+error in steps s1_commit s2_drop_attr: ERROR:  column "a" of relation 
"regress_type" does not exist
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_drop_attr s2_begin s2_alter_attr s1_commit 
s2_commit
+step s1_begin: BEGIN;
+step s1_drop_attr: 
+       ALTER TYPE regress_type DROP ATTRIBUTE a;
+step s2_begin: BEGIN;
+step s2_alter_attr: 
+       ALTER TYPE regress_type ALTER ATTRIBUTE a TYPE int8; <waiting ...>
+step s1_commit: COMMIT;
+step s2_alter_attr: <... completed>
+error in steps s1_commit s2_alter_attr: ERROR:  column "a" of relation 
"regress_type" does not exist
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_drop_attr s2_begin s2_rename_attr s1_commit 
s2_commit
+step s1_begin: BEGIN;
+step s1_drop_attr: 
+       ALTER TYPE regress_type DROP ATTRIBUTE a;
+step s2_begin: BEGIN;
+step s2_rename_attr: 
+       ALTER TYPE regress_type RENAME ATTRIBUTE a TO b; <waiting ...>
+step s1_commit: COMMIT;
+step s2_rename_attr: <... completed>
+error in steps s1_commit s2_rename_attr: ERROR:  column "a" does not exist
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_drop_attr s2_begin s2_owner s1_commit 
s2_commit
+step s1_begin: BEGIN;
+step s1_drop_attr: 
+       ALTER TYPE regress_type DROP ATTRIBUTE a;
+step s2_begin: BEGIN;
+step s2_owner: 
+       ALTER TYPE regress_type OWNER TO CURRENT_USER;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_drop_attr s2_begin s2_schema s1_commit 
s2_commit
+step s1_begin: BEGIN;
+step s1_drop_attr: 
+       ALTER TYPE regress_type DROP ATTRIBUTE a;
+step s2_begin: BEGIN;
+step s2_schema: 
+       ALTER TYPE regress_type SET SCHEMA regress_type_schema;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_alter_attr s2_begin s2_alter_attr s1_commit 
s2_commit
+step s1_begin: BEGIN;
+step s1_alter_attr: 
+       ALTER TYPE regress_type ALTER ATTRIBUTE a TYPE int8;
+step s2_begin: BEGIN;
+step s2_alter_attr: 
+       ALTER TYPE regress_type ALTER ATTRIBUTE a TYPE int8; <waiting ...>
+step s1_commit: COMMIT;
+step s2_alter_attr: <... completed>
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_alter_attr s2_begin s2_rename_attr s1_commit 
s2_commit
+step s1_begin: BEGIN;
+step s1_alter_attr: 
+       ALTER TYPE regress_type ALTER ATTRIBUTE a TYPE int8;
+step s2_begin: BEGIN;
+step s2_rename_attr: 
+       ALTER TYPE regress_type RENAME ATTRIBUTE a TO b; <waiting ...>
+step s1_commit: COMMIT;
+step s2_rename_attr: <... completed>
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_alter_attr s2_begin s2_owner s1_commit 
s2_commit
+step s1_begin: BEGIN;
+step s1_alter_attr: 
+       ALTER TYPE regress_type ALTER ATTRIBUTE a TYPE int8;
+step s2_begin: BEGIN;
+step s2_owner: 
+       ALTER TYPE regress_type OWNER TO CURRENT_USER;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_alter_attr s2_begin s2_schema s1_commit 
s2_commit
+step s1_begin: BEGIN;
+step s1_alter_attr: 
+       ALTER TYPE regress_type ALTER ATTRIBUTE a TYPE int8;
+step s2_begin: BEGIN;
+step s2_schema: 
+       ALTER TYPE regress_type SET SCHEMA regress_type_schema;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_rename_attr s2_begin s2_rename_attr 
s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_rename_attr: 
+       ALTER TYPE regress_type RENAME ATTRIBUTE a TO b;
+step s2_begin: BEGIN;
+step s2_rename_attr: 
+       ALTER TYPE regress_type RENAME ATTRIBUTE a TO b; <waiting ...>
+step s1_commit: COMMIT;
+step s2_rename_attr: <... completed>
+error in steps s1_commit s2_rename_attr: ERROR:  column "a" does not exist
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_rename_attr s2_begin s2_owner s1_commit 
s2_commit
+step s1_begin: BEGIN;
+step s1_rename_attr: 
+       ALTER TYPE regress_type RENAME ATTRIBUTE a TO b;
+step s2_begin: BEGIN;
+step s2_owner: 
+       ALTER TYPE regress_type OWNER TO CURRENT_USER;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_rename_attr s2_begin s2_schema s1_commit 
s2_commit
+step s1_begin: BEGIN;
+step s1_rename_attr: 
+       ALTER TYPE regress_type RENAME ATTRIBUTE a TO b;
+step s2_begin: BEGIN;
+step s2_schema: 
+       ALTER TYPE regress_type SET SCHEMA regress_type_schema;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_owner s2_begin s2_owner s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_owner: 
+       ALTER TYPE regress_type OWNER TO CURRENT_USER;
+step s2_begin: BEGIN;
+step s2_owner: 
+       ALTER TYPE regress_type OWNER TO CURRENT_USER;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_owner s2_begin s2_schema s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_owner: 
+       ALTER TYPE regress_type OWNER TO CURRENT_USER;
+step s2_begin: BEGIN;
+step s2_schema: 
+       ALTER TYPE regress_type SET SCHEMA regress_type_schema;
+step s1_commit: COMMIT;
+step s2_commit: COMMIT;
+
+starting permutation: s1_begin s1_schema s2_begin s2_schema s1_commit s2_commit
+step s1_begin: BEGIN;
+step s1_schema: 
+       ALTER TYPE regress_type SET SCHEMA regress_type_schema;
+step s2_begin: BEGIN;
+step s2_schema: 
+       ALTER TYPE regress_type SET SCHEMA regress_type_schema; <waiting ...>
+step s1_commit: COMMIT;
+step s2_schema: <... completed>
+error in steps s1_commit s2_schema: ERROR:  tuple concurrently updated
+step s2_commit: COMMIT;
diff --git a/src/test/isolation/expected/concurrent-user-mapping.out 
b/src/test/isolation/expected/concurrent-user-mapping.out
new file mode 100644
index 0000000000..63a89e2e88
--- /dev/null
+++ b/src/test/isolation/expected/concurrent-user-mapping.out
@@ -0,0 +1,15 @@
+Parsed test spec with 2 sessions
+
+starting permutation: s1_begin s1_options s2_begin s2_options s1_commit 
s2_commit
+step s1_begin: BEGIN;
+step s1_options: 
+       ALTER USER MAPPING FOR CURRENT_USER server regress_server
+         OPTIONS (SET USER 'popo1');
+step s2_begin: BEGIN;
+step s2_options: 
+       ALTER USER MAPPING FOR CURRENT_USER server regress_server
+         OPTIONS (SET USER 'popo1'); <waiting ...>
+step s1_commit: COMMIT;
+step s2_options: <... completed>
+error in steps s1_commit s2_options: ERROR:  tuple concurrently updated
+step s2_commit: COMMIT;
diff --git a/src/test/isolation/isolation_schedule 
b/src/test/isolation/isolation_schedule
index eb566ebb6c..f02a196dcc 100644
--- a/src/test/isolation/isolation_schedule
+++ b/src/test/isolation/isolation_schedule
@@ -64,3 +64,11 @@ test: async-notify
 test: vacuum-reltuples
 test: timeouts
 test: vacuum-concurrent-drop
+test: concurrent-database
+test: concurrent-role
+test: concurrent-domain
+test: concurrent-event-trigger
+test: concurrent-fdw
+test: concurrent-server
+test: concurrent-user-mapping
+test: concurrent-type
diff --git a/src/test/isolation/specs/concurrent-database.spec 
b/src/test/isolation/specs/concurrent-database.spec
new file mode 100644
index 0000000000..a3812abcdc
--- /dev/null
+++ b/src/test/isolation/specs/concurrent-database.spec
@@ -0,0 +1,64 @@
+# Test for interactions with DDL commands manipulating database
+# objects.
+# XXX: This cannot be included in the final patch as installcheck would
+# create a database on existing instances!
+# The following set of commands can interact in concurrency:
+# - ALTER DATABASE SET
+# - ALTER DATABASE OWNER TO
+# - ALTER DATABASE SET TABLESPACE
+# - ALTER DATABASE WITH
+
+setup
+{
+  CREATE DATABASE regress_database TEMPLATE template0;
+}
+
+teardown
+{
+  DROP DATABASE regress_database;
+}
+
+session "s1"
+step "s1_begin"                        { BEGIN; }
+step "s1_alterdb_with" {
+       ALTER DATABASE regress_database WITH ALLOW_CONNECTIONS true; }
+step "s1_alterdb_set"  {
+       ALTER DATABASE regress_database SET commit_delay = '10'; }
+step "s1_alterdb_owner"        {
+       ALTER DATABASE regress_database OWNER TO CURRENT_USER; }
+step "s1_alterdb_tbc"  {
+       ALTER DATABASE regress_database SET TABLESPACE TO DEFAULT; }
+step "s1_commit"       { COMMIT; }
+
+session "s2"
+step "s2_begin"                        { BEGIN; }
+step "s2_alterdb_with" {
+       ALTER DATABASE regress_database WITH ALLOW_CONNECTIONS true; }
+step "s2_alterdb_set"  {
+       ALTER DATABASE regress_database SET commit_delay = '10'; }
+step "s2_alterdb_owner"        {
+       ALTER DATABASE regress_database OWNER TO CURRENT_USER; }
+step "s2_alterdb_tbc"  {
+       ALTER DATABASE regress_database SET TABLESPACE TO DEFAULT; }
+step "s2_commit"       { COMMIT; }
+
+permutation "s1_begin" "s1_alterdb_with" "s2_begin" "s2_alterdb_with"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_alterdb_with" "s2_begin" "s2_alterdb_set"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_alterdb_with" "s2_begin" "s2_alterdb_owner"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_alterdb_with" "s2_begin" "s2_alterdb_tbc"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_alterdb_set" "s2_begin" "s2_alterdb_set"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_alterdb_set" "s2_begin" "s2_alterdb_owner"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_alterdb_set" "s2_begin" "s2_alterdb_tbc"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_alterdb_owner" "s2_begin" "s2_alterdb_owner"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_alterdb_owner" "s2_begin" "s2_alterdb_tbc"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_alterdb_tbc" "s2_begin" "s2_alterdb_tbc"
+       "s1_commit" "s2_commit"
diff --git a/src/test/isolation/specs/concurrent-domain.spec 
b/src/test/isolation/specs/concurrent-domain.spec
new file mode 100644
index 0000000000..1525a53c42
--- /dev/null
+++ b/src/test/isolation/specs/concurrent-domain.spec
@@ -0,0 +1,191 @@
+# Test for interactions with DDL commands manipulating domain
+# objects.
+# The following set of commands can interact in concurrency:
+# - ALTER DOMAIN SET NOT NULL
+# - ALTER DOMAIN DROP NOT NULL
+# - ALTER DOMAIN SET DEFAULT
+# - ALTER DOMAIN DROP DEFAULT
+# - ALTER DOMAIN ADD CONSTRAINT
+# - ALTER DOMAIN DROP CONSTRAINT
+# - ALTER DOMAIN VALIDATE CONSTRAINT
+# - ALTER DOMAIN OWNER TO
+# - ALTER DOMAIN SET SCHEMA
+
+setup
+{
+  CREATE SCHEMA regress_domain_schema;
+  CREATE DOMAIN regress_domain_conc AS int;
+}
+
+teardown
+{
+  DROP DOMAIN IF EXISTS regress_domain_conc;
+  DROP SCHEMA regress_domain_schema CASCADE;
+
+}
+
+session "s1"
+step "s1_begin"                                { BEGIN; }
+step "s1_dom_set_notnull"      {
+       ALTER DOMAIN regress_domain_conc SET NOT NULL; }
+step "s1_dom_drop_notnull"     {
+       ALTER DOMAIN regress_domain_conc DROP NOT NULL; }
+step "s1_dom_set_default"      {
+       ALTER DOMAIN regress_domain_conc SET DEFAULT 1; }
+step "s1_dom_drop_default"     {
+       ALTER DOMAIN regress_domain_conc DROP DEFAULT; }
+step "s1_dom_add_con"          {
+       ALTER DOMAIN regress_domain_conc ADD CONSTRAINT dom_con CHECK (VALUE > 
0); }
+step "s1_dom_drop_con"         {
+       ALTER DOMAIN regress_domain_conc DROP CONSTRAINT dom_con; }
+step "s1_dom_validate_con"     {
+       ALTER DOMAIN regress_domain_conc VALIDATE CONSTRAINT dom_con; }
+step "s1_dom_owner"                    {
+       ALTER DOMAIN regress_domain_conc OWNER TO CURRENT_USER; }
+step "s1_dom_schema_priv"      {
+       ALTER DOMAIN regress_domain_conc SET SCHEMA regress_domain_schema; }
+step "s1_dom_schema_publ"      {
+       ALTER DOMAIN regress_domain_conc SET SCHEMA public; }
+step "s1_commit"                       { COMMIT; }
+
+session "s2"
+step "s2_begin"                        { BEGIN; }
+step "s2_dom_set_notnull"      {
+       ALTER DOMAIN regress_domain_conc SET NOT NULL; }
+step "s2_dom_drop_notnull"     {
+       ALTER DOMAIN regress_domain_conc DROP NOT NULL; }
+step "s2_dom_set_default"      {
+       ALTER DOMAIN regress_domain_conc SET DEFAULT 1; }
+step "s2_dom_drop_default"     {
+       ALTER DOMAIN regress_domain_conc DROP DEFAULT; }
+step "s2_dom_add_con"          {
+       ALTER DOMAIN regress_domain_conc ADD CONSTRAINT dom_con CHECK (VALUE > 
0); }
+step "s2_dom_add_con2"         {
+       ALTER DOMAIN regress_domain_conc ADD CONSTRAINT dom_con2 CHECK (VALUE > 
0); }
+step "s2_dom_drop_con"         {
+       ALTER DOMAIN regress_domain_conc DROP CONSTRAINT dom_con; }
+step "s2_dom_validate_con"     {
+       ALTER DOMAIN regress_domain_conc VALIDATE CONSTRAINT dom_con; }
+step "s2_dom_owner"                    {
+       ALTER DOMAIN regress_domain_conc OWNER TO CURRENT_USER; }
+step "s2_dom_schema_priv"      {
+       ALTER DOMAIN regress_domain_conc SET SCHEMA regress_domain_schema; }
+step "s2_dom_schema_publ"      {
+       ALTER DOMAIN regress_domain_conc SET SCHEMA public; }
+step "s2_commit"       { COMMIT; }
+
+# Round 1 of all permutations using SET NOT NULL as base
+permutation "s1_begin" "s1_dom_set_notnull" "s2_begin" "s2_dom_set_notnull"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_dom_set_notnull" "s2_begin" "s2_dom_drop_notnull"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_dom_set_notnull" "s2_begin" "s2_dom_set_default"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_dom_set_notnull" "s2_begin" "s2_dom_drop_default"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_dom_set_notnull" "s2_begin" "s2_dom_add_con"
+       "s1_commit" "s2_commit"
+# No DROP/VALIDATE CONSTRAINT needed as nothing is defined.
+permutation "s1_begin" "s1_dom_set_notnull" "s2_begin" "s2_dom_owner"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_dom_set_notnull" "s2_begin" "s2_dom_schema_priv"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_dom_set_notnull" "s2_begin" "s2_dom_schema_publ"
+       "s1_commit" "s2_commit"
+
+# Round 2 of all permutations using DROP NOT NULL as base
+permutation "s1_begin" "s1_dom_drop_notnull" "s2_begin" "s2_dom_drop_notnull"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_dom_drop_notnull" "s2_begin" "s2_dom_set_default"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_dom_drop_notnull" "s2_begin" "s2_dom_drop_default"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_dom_drop_notnull" "s2_begin" "s2_dom_add_con"
+       "s1_commit" "s2_commit"
+# No DROP/VALIDATE CONSTRAINT needed as nothing is defined.
+permutation "s1_begin" "s1_dom_drop_notnull" "s2_begin" "s2_dom_owner"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_dom_drop_notnull" "s2_begin" "s2_dom_schema_priv"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_dom_drop_notnull" "s2_begin" "s2_dom_schema_publ"
+       "s1_commit" "s2_commit"
+
+# Round 3 of all permutations using SET DEFAULT as base
+permutation "s1_begin" "s1_dom_set_default" "s2_begin" "s2_dom_set_default"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_dom_set_default" "s2_begin" "s2_dom_drop_default"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_dom_set_default" "s2_begin" "s2_dom_add_con"
+       "s1_commit" "s2_commit"
+# No DROP/VALIDATE CONSTRAINT needed as nothing is defined.
+permutation "s1_begin" "s1_dom_set_default" "s2_begin" "s2_dom_owner"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_dom_set_default" "s2_begin" "s2_dom_schema_priv"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_dom_set_default" "s2_begin" "s2_dom_schema_publ"
+       "s1_commit" "s2_commit"
+
+# Round 4 of all permutations using DROP DEFAULT as base
+permutation "s1_begin" "s1_dom_drop_default" "s2_begin" "s2_dom_drop_default"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_dom_drop_default" "s2_begin" "s2_dom_add_con"
+       "s1_commit" "s2_commit"
+# No DROP/VALIDATE CONSTRAINT needed as nothing is defined.
+permutation "s1_begin" "s1_dom_drop_default" "s2_begin" "s2_dom_owner"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_dom_drop_default" "s2_begin" "s2_dom_schema_priv"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_dom_drop_default" "s2_begin" "s2_dom_schema_publ"
+       "s1_commit" "s2_commit"
+
+# Round 5 of all permutations using ADD CONSTRAINT as a base
+permutation "s1_begin" "s1_dom_add_con" "s2_begin" "s2_dom_add_con2"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_dom_add_con" "s2_begin" "s2_dom_drop_con"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_dom_add_con" "s2_begin" "s2_dom_validate_con"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_dom_add_con" "s2_begin" "s2_dom_owner"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_dom_add_con" "s2_begin" "s2_dom_schema_priv"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_dom_add_con" "s2_begin" "s2_dom_schema_publ"
+       "s1_commit" "s2_commit"
+
+# Round 6 with DROP CONSTRAINT
+permutation "s1_dom_add_con" "s1_begin" "s1_dom_drop_con" "s2_begin"
+       "s2_dom_drop_con" "s1_commit" "s2_commit"
+permutation "s1_dom_add_con" "s1_begin" "s1_dom_drop_con" "s2_begin"
+       "s2_dom_validate_con" "s1_commit" "s2_commit"
+permutation "s1_dom_add_con" "s1_begin" "s1_dom_drop_con" "s2_begin"
+       "s2_dom_owner" "s1_commit" "s2_commit"
+permutation "s1_dom_add_con" "s1_begin" "s1_dom_drop_con" "s2_begin"
+       "s2_dom_schema_publ" "s1_commit" "s2_commit"
+permutation "s1_dom_add_con" "s1_begin" "s1_dom_drop_con" "s2_begin"
+       "s2_dom_schema_priv" "s1_commit" "s2_commit"
+
+# Round 7 of all permutations using VALIDATE CONSTRAINT
+permutation "s1_dom_add_con" "s1_begin" "s1_dom_validate_con" "s2_begin"
+       "s2_dom_validate_con" "s1_commit" "s2_commit"
+permutation "s1_dom_add_con" "s1_begin" "s1_dom_validate_con" "s2_begin"
+       "s2_dom_owner" "s1_commit" "s2_commit"
+permutation "s1_dom_add_con" "s1_begin" "s1_dom_validate_con" "s2_begin"
+       "s2_dom_schema_priv" "s1_commit" "s2_commit"
+permutation "s1_dom_add_con" "s1_begin" "s1_dom_validate_con" "s2_begin"
+       "s2_dom_schema_publ" "s1_commit" "s2_commit"
+
+# Round 8 of all permutations using OWNER TO as base
+permutation "s1_begin" "s1_dom_owner" "s2_begin" "s2_dom_owner"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_dom_owner" "s2_begin" "s2_dom_schema_priv"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_dom_owner" "s2_begin" "s2_dom_schema_publ"
+       "s1_commit" "s2_commit"
+
+# Round 9 with schemas
+permutation "s1_begin" "s1_dom_schema_priv" "s2_begin" "s2_dom_schema_publ"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_dom_schema_publ" "s2_begin" "s2_dom_schema_priv"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_dom_schema_publ" "s2_begin" "s2_dom_schema_publ"
+       "s1_commit" "s2_commit"
diff --git a/src/test/isolation/specs/concurrent-event-trigger.spec 
b/src/test/isolation/specs/concurrent-event-trigger.spec
new file mode 100644
index 0000000000..f896f0754c
--- /dev/null
+++ b/src/test/isolation/specs/concurrent-event-trigger.spec
@@ -0,0 +1,53 @@
+# Test for interactions with DDL commands manipulating event trigger
+# objects.
+# The following set of commands can interact in concurrency:
+# - ALTER EVENT TRIGGER ENABLE
+# - ALTER EVENT TRIGGER DISABLE
+# - ALTER EVENT TRIGGER OWNER TO
+
+setup
+{
+  CREATE OR REPLACE FUNCTION notice_any_command()
+    RETURNS event_trigger
+    LANGUAGE plpgsql
+    AS $$
+      BEGIN
+      RAISE NOTICE 'command % is run', tg_tag;
+      END;
+    $$;
+  CREATE EVENT TRIGGER notice_ddl ON ddl_command_start
+     EXECUTE PROCEDURE notice_any_command();
+}
+
+teardown
+{
+  DROP EVENT TRIGGER notice_ddl;
+  DROP FUNCTION notice_any_command();
+}
+
+session "s1"
+step "s1_begin"                { BEGIN; }
+step "s1_disable"      { ALTER EVENT TRIGGER notice_ddl DISABLE; }
+step "s1_enable"       { ALTER EVENT TRIGGER notice_ddl ENABLE REPLICA; }
+step "s1_owner"                { ALTER EVENT TRIGGER notice_ddl OWNER TO 
CURRENT_USER; }
+step "s1_commit"       { COMMIT; }
+
+session "s2"
+step "s2_begin"                { BEGIN; }
+step "s2_disable"      { ALTER EVENT TRIGGER notice_ddl DISABLE; }
+step "s2_enable"       { ALTER EVENT TRIGGER notice_ddl ENABLE REPLICA; }
+step "s2_owner"                { ALTER EVENT TRIGGER notice_ddl OWNER TO 
CURRENT_USER; }
+step "s2_commit"       { COMMIT; }
+
+permutation "s1_begin" "s1_disable" "s2_begin" "s2_disable"
+  "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_disable" "s2_begin" "s2_enable"
+  "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_disable" "s2_begin" "s2_owner"
+  "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_enable" "s2_begin" "s2_enable"
+  "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_enable" "s2_begin" "s2_owner"
+  "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_owner" "s2_begin" "s2_owner"
+  "s1_commit" "s2_commit"
diff --git a/src/test/isolation/specs/concurrent-fdw.spec 
b/src/test/isolation/specs/concurrent-fdw.spec
new file mode 100644
index 0000000000..1e8ce38dad
--- /dev/null
+++ b/src/test/isolation/specs/concurrent-fdw.spec
@@ -0,0 +1,62 @@
+# Test for interactions with DDL commands manipulating fdw
+# objects.
+# The following set of commands can interact in concurrency:
+# - ALTER FDW OPTIONS
+# - ALTER FDW VALIDATOR
+# - ALTER FDW HANDLER
+# - ALTER FDW OWNER TO
+
+setup
+{
+  CREATE FOREIGN DATA WRAPPER regress_fdw;
+}
+
+teardown
+{
+  DROP FOREIGN DATA WRAPPER regress_fdw;
+}
+
+session "s1"
+step "s1_begin"                        { BEGIN; }
+step "s1_options"      {
+       ALTER FOREIGN DATA WRAPPER regress_fdw OPTIONS (a '1'); }
+step "s1_validator"    {
+       ALTER FOREIGN DATA WRAPPER regress_fdw NO VALIDATOR; }
+step "s1_handler"      {
+       ALTER FOREIGN DATA WRAPPER regress_fdw NO HANDLER; }
+step "s1_owner"        {
+       ALTER FOREIGN DATA WRAPPER regress_fdw OWNER TO CURRENT_USER; }
+step "s1_commit"       { COMMIT; }
+
+session "s2"
+step "s2_begin"                        { BEGIN; }
+step "s2_options"      {
+       ALTER FOREIGN DATA WRAPPER regress_fdw OPTIONS (a '1'); }
+step "s2_validator"    {
+       ALTER FOREIGN DATA WRAPPER regress_fdw NO VALIDATOR; }
+step "s2_handler"      {
+       ALTER FOREIGN DATA WRAPPER regress_fdw NO HANDLER; }
+step "s2_owner"        {
+       ALTER FOREIGN DATA WRAPPER regress_fdw OWNER TO CURRENT_USER; }
+step "s2_commit"       { COMMIT; }
+
+permutation "s1_begin" "s1_options" "s2_begin" "s2_options"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_options" "s2_begin" "s2_validator"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_options" "s2_begin" "s2_handler"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_options" "s2_begin" "s2_owner"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_validator" "s2_begin" "s2_validator"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_validator" "s2_begin" "s2_handler"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_validator" "s2_begin" "s2_owner"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_handler" "s2_begin" "s2_handler"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_handler" "s2_begin" "s2_owner"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_owner" "s2_begin" "s2_owner"
+       "s1_commit" "s2_commit"
diff --git a/src/test/isolation/specs/concurrent-role.spec 
b/src/test/isolation/specs/concurrent-role.spec
new file mode 100644
index 0000000000..24b96da41a
--- /dev/null
+++ b/src/test/isolation/specs/concurrent-role.spec
@@ -0,0 +1,40 @@
+# Test for interactions with DDL commands manipulating role
+# objects.
+# The following set of commands can interact in concurrency:
+# - ALTER ROLE SET
+# - ALTER ROLE option
+
+setup
+{
+  CREATE ROLE regress_role_conc;
+}
+
+teardown
+{
+  DROP ROLE regress_role_conc;
+}
+
+session "s1"
+step "s1_begin"                        { BEGIN; }
+step "s1_alterrole_set"        {
+       ALTER ROLE regress_role_conc SET commit_delay = '10'; }
+step "s1_alterrole_opt"        {
+       ALTER ROLE regress_role_conc PASSWORD 'foo'; }
+step "s1_commit"       { COMMIT; }
+
+session "s2"
+step "s2_begin"                        { BEGIN; }
+step "s2_alterrole_set"        {
+       ALTER ROLE regress_role_conc SET commit_delay = '10'; }
+step "s2_alterrole_opt"        {
+       ALTER ROLE regress_role_conc PASSWORD 'foo'; }
+step "s2_commit"       { COMMIT; }
+
+permutation "s1_begin" "s1_alterrole_set" "s2_begin" "s2_alterrole_set"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_alterrole_set" "s2_begin" "s2_alterrole_opt"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_alterrole_opt" "s2_begin" "s2_alterrole_set"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_alterrole_opt" "s2_begin" "s2_alterrole_opt"
+       "s1_commit" "s2_commit"
diff --git a/src/test/isolation/specs/concurrent-server.spec 
b/src/test/isolation/specs/concurrent-server.spec
new file mode 100644
index 0000000000..2a41d09397
--- /dev/null
+++ b/src/test/isolation/specs/concurrent-server.spec
@@ -0,0 +1,39 @@
+# Test for interactions with DDL commands manipulating server
+# objects.
+# The following set of commands can interact in concurrency:
+# - ALTER SERVER OPTIONS
+# - ALTER SERVER OWNER TO
+
+setup
+{
+  CREATE FOREIGN DATA WRAPPER regress_fdw;
+  CREATE SERVER regress_server FOREIGN DATA WRAPPER regress_fdw;
+}
+
+teardown
+{
+  DROP FOREIGN DATA WRAPPER regress_fdw CASCADE;
+}
+
+session "s1"
+step "s1_begin"                { BEGIN; }
+step "s1_options"      {
+       ALTER SERVER regress_server OPTIONS (a '1'); }
+step "s1_owner"                {
+       ALTER SERVER regress_server OWNER TO CURRENT_USER; }
+step "s1_commit"       { COMMIT; }
+
+session "s2"
+step "s2_begin"                        { BEGIN; }
+step "s2_options"      {
+       ALTER SERVER regress_server OPTIONS (a '1'); }
+step "s2_owner"                {
+       ALTER SERVER regress_server OWNER TO CURRENT_USER; }
+step "s2_commit"       { COMMIT; }
+
+permutation "s1_begin" "s1_options" "s2_begin" "s2_options"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_options" "s2_begin" "s2_owner"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_owner" "s2_begin" "s2_owner"
+       "s1_commit" "s2_commit"
diff --git a/src/test/isolation/specs/concurrent-type.spec 
b/src/test/isolation/specs/concurrent-type.spec
new file mode 100644
index 0000000000..3fe8f2338b
--- /dev/null
+++ b/src/test/isolation/specs/concurrent-type.spec
@@ -0,0 +1,107 @@
+# Test for interactions with DDL commands manipulating type
+# objects.
+# The following set of commands can interact in concurrency:
+# - ALTER TYPE ADD ATTRIBUTE
+# - ALTER TYPE DROP ATTRIBUTE
+# - ALTER TYPE ALTER ATTRIBUTE
+# - ALTER TYPE RENAME ATTRIBUTE
+# - ALTER TYPE OWNER TO
+# - ALTER TYPE SET SCHEMA
+
+setup
+{
+  CREATE SCHEMA regress_type_schema;
+  CREATE TYPE regress_type AS (a int);
+}
+
+teardown
+{
+  DROP TYPE IF EXISTS regress_type;
+  DROP SCHEMA regress_type_schema CASCADE;
+}
+
+session "s1"
+step "s1_begin"                        { BEGIN; }
+step "s1_add_attr"             {
+       ALTER TYPE regress_type ADD ATTRIBUTE b1 int; }
+step "s1_drop_attr"            {
+       ALTER TYPE regress_type DROP ATTRIBUTE a; }
+step "s1_alter_attr"   {
+       ALTER TYPE regress_type ALTER ATTRIBUTE a TYPE int8; }
+step "s1_rename_attr"  {
+       ALTER TYPE regress_type RENAME ATTRIBUTE a TO b; }
+step "s1_owner"                        {
+       ALTER TYPE regress_type OWNER TO CURRENT_USER; }
+step "s1_schema"               {
+       ALTER TYPE regress_type SET SCHEMA regress_type_schema; }
+step "s1_commit"       { COMMIT; }
+
+session "s2"
+step "s2_begin"                { BEGIN; }
+step "s2_add_attr"             {
+       ALTER TYPE regress_type ADD ATTRIBUTE b2 int; }
+step "s2_drop_attr"            {
+       ALTER TYPE regress_type DROP ATTRIBUTE a; }
+step "s2_alter_attr"   {
+       ALTER TYPE regress_type ALTER ATTRIBUTE a TYPE int8; }
+step "s2_rename_attr"  {
+       ALTER TYPE regress_type RENAME ATTRIBUTE a TO b; }
+step "s2_owner"                        {
+       ALTER TYPE regress_type OWNER TO CURRENT_USER; }
+step "s2_schema"               {
+       ALTER TYPE regress_type SET SCHEMA regress_type_schema; }
+step "s2_commit"       { COMMIT; }
+
+# Round 1 of permutations based on ADD ATTRIBUTE
+permutation "s1_begin" "s1_add_attr" "s2_begin" "s2_add_attr"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_add_attr" "s2_begin" "s2_drop_attr"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_add_attr" "s2_begin" "s2_alter_attr"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_add_attr" "s2_begin" "s2_rename_attr"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_add_attr" "s2_begin" "s2_owner"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_add_attr" "s2_begin" "s2_schema"
+       "s1_commit" "s2_commit"
+
+# Round 2 of permutations based on DROP ATTRIBUTE
+permutation "s1_begin" "s1_drop_attr" "s2_begin" "s2_drop_attr"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_drop_attr" "s2_begin" "s2_alter_attr"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_drop_attr" "s2_begin" "s2_rename_attr"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_drop_attr" "s2_begin" "s2_owner"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_drop_attr" "s2_begin" "s2_schema"
+       "s1_commit" "s2_commit"
+
+# Round 3 of permutations based on ALTER ATTRIBUTE
+permutation "s1_begin" "s1_alter_attr" "s2_begin" "s2_alter_attr"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_alter_attr" "s2_begin" "s2_rename_attr"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_alter_attr" "s2_begin" "s2_owner"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_alter_attr" "s2_begin" "s2_schema"
+       "s1_commit" "s2_commit"
+
+# Round 4 of permutations based on RENAME ATTRIBUTE
+permutation "s1_begin" "s1_rename_attr" "s2_begin" "s2_rename_attr"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_rename_attr" "s2_begin" "s2_owner"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_rename_attr" "s2_begin" "s2_schema"
+       "s1_commit" "s2_commit"
+
+# Round 5 of permutations based on OWNER TO
+permutation "s1_begin" "s1_owner" "s2_begin" "s2_owner"
+       "s1_commit" "s2_commit"
+permutation "s1_begin" "s1_owner" "s2_begin" "s2_schema"
+       "s1_commit" "s2_commit"
+
+# Round 6 of permutations based on SET SCHEMA
+permutation "s1_begin" "s1_schema" "s2_begin" "s2_schema"
+       "s1_commit" "s2_commit"
diff --git a/src/test/isolation/specs/concurrent-user-mapping.spec 
b/src/test/isolation/specs/concurrent-user-mapping.spec
new file mode 100644
index 0000000000..d8a8669c4f
--- /dev/null
+++ b/src/test/isolation/specs/concurrent-user-mapping.spec
@@ -0,0 +1,34 @@
+# Test for interactions with DDL commands manipulating user
+# mappings
+# The following set of commands can interact in concurrency:
+# - ALTER USER MAPPING OPTIONS
+
+setup
+{
+  CREATE FOREIGN DATA WRAPPER regress_fdw;
+  CREATE SERVER regress_server FOREIGN DATA WRAPPER regress_fdw;
+  CREATE USER MAPPING FOR CURRENT_USER SERVER regress_server
+    OPTIONS (user 'CURRENT_USER');
+}
+
+teardown
+{
+  DROP FOREIGN DATA WRAPPER regress_fdw CASCADE;
+}
+
+session "s1"
+step "s1_begin"                { BEGIN; }
+step "s1_options"      {
+       ALTER USER MAPPING FOR CURRENT_USER server regress_server
+         OPTIONS (SET USER 'popo1'); }
+step "s1_commit"       { COMMIT; }
+
+session "s2"
+step "s2_begin"                { BEGIN; }
+step "s2_options"      {
+       ALTER USER MAPPING FOR CURRENT_USER server regress_server
+         OPTIONS (SET USER 'popo1'); }
+step "s2_commit"       { COMMIT; }
+
+permutation "s1_begin" "s1_options" "s2_begin" "s2_options"
+       "s1_commit" "s2_commit"

Attachment: signature.asc
Description: PGP signature

Reply via email to