On 2012-12-01 17:36:20 +0100, Andres Freund wrote:
> On 2012-12-01 17:03:03 +0100, Andres Freund wrote:
> > Could we possibly allow adding enum values to a type which was just created 
> > in
> > this transaction? That shouldn't be too hard. At least easier than providing
> > the capability to pre-assign the next N oids...
>
> The attached patch does just that. Its *not* ready yet though, as it
> will be apparent for everyone who reads it ;)
>
> To really make that work in a reliable manner we would probably need
> an rd_createSubid for typcache entries instead of testing xmin as I have
> done here?

And the patch...

Greetings,

Andres Freund

--
 Andres Freund                     http://www.2ndQuadrant.com/
 PostgreSQL Development, 24x7 Support, Training & Services
>From 2839c7037d4ca8903a322aba5c399f2e54f2d63b Mon Sep 17 00:00:00 2001
From: Andres Freund <and...@anarazel.de>
Date: Sat, 1 Dec 2012 17:37:57 +0100
Subject: [PATCH] Allow ALTER TYPE ... ADD VALUE inside transactions if the
 type was created in the same transaction

---
 src/backend/commands/typecmds.c |   16 ++++++++++++++--
 src/backend/tcop/utility.c      |    4 ++--
 src/include/commands/typecmds.h |    2 +-
 3 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 8418096..d419ed0 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -1169,11 +1169,14 @@ DefineEnum(CreateEnumStmt *stmt)
  *		Adds a new label to an existing enum.
  */
 void
-AlterEnum(AlterEnumStmt *stmt)
+AlterEnum(AlterEnumStmt *stmt, bool toplevel)
 {
 	Oid			enum_type_oid;
 	TypeName   *typename;
 	HeapTuple	tup;
+	bool in_transaction;
+
+	in_transaction = IsTransactionBlock() || IsSubTransaction() || !toplevel;
 
 	/* Make a TypeName so we can use standard type lookup machinery */
 	typename = makeTypeNameFromNameList(stmt->typeName);
@@ -1183,12 +1186,21 @@ AlterEnum(AlterEnumStmt *stmt)
 	if (!HeapTupleIsValid(tup))
 		elog(ERROR, "cache lookup failed for type %u", enum_type_oid);
 
+	if (in_transaction)
+	{
+		TransactionId xmin = HeapTupleHeaderGetXmin(tup->t_data);
+		if (!TransactionIdIsCurrentTransactionId(xmin))
+			PreventTransactionChain(toplevel, "ALTER TYPE ... ADD2");
+	}
+	else
+		PreventTransactionChain(toplevel, "ALTER TYPE ... ADD");
+
 	/* Check it's an enum and check user has permission to ALTER the enum */
 	checkEnumOwner(tup);
 
 	/* Add the new label */
 	AddEnumLabel(enum_type_oid, stmt->newVal,
-				 stmt->newValNeighbor, stmt->newValIsAfter, 
+				 stmt->newValNeighbor, stmt->newValIsAfter,
 				 stmt->skipIfExists);
 
 	ReleaseSysCache(tup);
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 491bd29..bf2a0e3 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -977,9 +977,9 @@ standard_ProcessUtility(Node *parsetree,
 			 * We disallow this in transaction blocks, because we can't cope
 			 * with enum OID values getting into indexes and then having their
 			 * defining pg_enum entries go away.
+			 * XXX
 			 */
-			PreventTransactionChain(isTopLevel, "ALTER TYPE ... ADD");
-			AlterEnum((AlterEnumStmt *) parsetree);
+			AlterEnum((AlterEnumStmt *) parsetree, isTopLevel);
 			break;
 
 		case T_ViewStmt:		/* CREATE VIEW */
diff --git a/src/include/commands/typecmds.h b/src/include/commands/typecmds.h
index 2351024..792b146 100644
--- a/src/include/commands/typecmds.h
+++ b/src/include/commands/typecmds.h
@@ -26,7 +26,7 @@ extern void RemoveTypeById(Oid typeOid);
 extern void DefineDomain(CreateDomainStmt *stmt);
 extern void DefineEnum(CreateEnumStmt *stmt);
 extern void DefineRange(CreateRangeStmt *stmt);
-extern void AlterEnum(AlterEnumStmt *stmt);
+extern void AlterEnum(AlterEnumStmt *stmt, bool toplevel);
 extern Oid	DefineCompositeType(RangeVar *typevar, List *coldeflist);
 extern Oid	AssignTypeArrayOid(void);
 
-- 
1.7.10.4

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to