0001-Allow-ALTER-TYPE-.-ADD-VALUE-inside-transactions-if-.patch
text/x-patch
Filename: 0001-Allow-ALTER-TYPE-.-ADD-VALUE-inside-transactions-if-.patch
Type: text/x-patch
Part: 0
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
Series: patch 0001
| File | + | − |
|---|---|---|
| src/backend/commands/typecmds.c | 14 | 2 |
| src/backend/tcop/utility.c | 2 | 2 |
| src/include/commands/typecmds.h | 1 | 1 |
>From 2839c7037d4ca8903a322aba5c399f2e54f2d63b Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@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