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