Hi,
Currently, when creating an enum type, duplicate labels are caught by a unique
index on pg_enum, resulting in a generic error message.
postgres=# create type t as enum ('a','b','a');
ERROR: duplicate key value violates unique constraint
"pg_enum_typid_label_index"
DETAIL: Key (enumtypid, enumlabel)=(16418, a) already exists.
I propose adding an explicit check for duplicate labels during enum creation,
so that a more user-friendly and descriptive error message can be produced,
similar to what is already done in ALTER TYPE ... ADD VALUE
or ALTER TYPE ... RENAME VALUE .. TO ....
With the attached patch applied, the error message becomes:
ERROR: label "a" used more than once
Regards,
Yugo Nagata
--
Yugo Nagata <[email protected]>
>From 0b7f148e9ea6d9d6851e71f7ca3dc91b30b377af Mon Sep 17 00:00:00 2001
From: Yugo Nagata <[email protected]>
Date: Thu, 3 Jul 2025 23:45:40 +0900
Subject: [PATCH] Improve error message for duplicate labels in enum types
Previously, duplicate labels in an enum type were caught by a unique
index on pg_enum, resulting in a generic error message. This adds an
explicit check beforehand to produce a more user-friendly and descriptive
error message.
---
src/backend/catalog/pg_enum.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/src/backend/catalog/pg_enum.c b/src/backend/catalog/pg_enum.c
index a1634e58eec..9a4039d4669 100644
--- a/src/backend/catalog/pg_enum.c
+++ b/src/backend/catalog/pg_enum.c
@@ -164,6 +164,25 @@ EnumValuesCreate(Oid enumTypeOid, List *vals)
{
char *lab = strVal(lfirst(lc));
Name enumlabel = palloc0(NAMEDATALEN);
+ ListCell *lc2;
+
+ /*
+ * Check for duplicate labels. The unique index on pg_enum would catch
+ * that anyway, but we prefer a friendlier error message.
+ */
+ foreach(lc2, vals)
+ {
+ char *lab2 = strVal(lfirst(lc2));
+
+ if (lc == lc2)
+ break;
+
+ if (strcmp(lab, lab2) == 0)
+ ereport(ERROR,
+ (errcode(ERRCODE_DUPLICATE_OBJECT),
+ errmsg("label \"%s\" used more than once",
+ lab)));
+ }
/*
* labels are stored in a name field, for easier syscache lookup, so
--
2.43.0