git_head_lock_schema_ddl.patch

application/octet-stream

Filename: git_head_lock_schema_ddl.patch
Type: application/octet-stream
Part: 0
Message: Re: Concurrent CREATE TABLE/DROP SCHEMA leaves inconsistent leftovers

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: unified
File+
src/backend/commands/tablecmds.c 16 1
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index c4622c0..c3248f8 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -453,6 +453,20 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId)
 				 errmsg("cannot create temporary table within security-restricted operation")));
 
 	/*
+	 * Lock the namespace so as to handle concurrent DROP operations. Kinda
+	 * klugy with the oid to namespace name list stuff, but then we can handily
+	 * call the existing get_object_address function which does most of the
+	 * work.
+	 *
+	 * AccessShareLock is enough, because we do not want to interlock with
+	 * other create objects in the same schema, but with concurrent deletion
+	 * only
+	 */
+	(void) get_object_address(OBJECT_SCHEMA,
+						list_make1(makeString(get_namespace_name(namespaceId))),
+						NIL, &rel, AccessShareLock, false);
+
+	/*
 	 * Select tablespace to use.  If not specified, use default tablespace
 	 * (which may in turn default to database's default).
 	 */
@@ -633,7 +647,8 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId)
 
 	/*
 	 * Clean up.  We keep lock on new relation (although it shouldn't be
-	 * visible to anyone else anyway, until commit).
+	 * visible to anyone else anyway, until commit). We also retain other locks
+	 * obtained above to guard against concurrent activity
 	 */
 	relation_close(rel, NoLock);