summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/catalog/pg_enum.c25
-rw-r--r--src/test/regress/expected/enum.out3
-rw-r--r--src/test/regress/sql/enum.sql3
3 files changed, 25 insertions, 6 deletions
diff --git a/src/backend/catalog/pg_enum.c b/src/backend/catalog/pg_enum.c
index a1634e58eec..da9c2a46cfa 100644
--- a/src/backend/catalog/pg_enum.c
+++ b/src/backend/catalog/pg_enum.c
@@ -110,12 +110,6 @@ EnumValuesCreate(Oid enumTypeOid, List *vals)
num_elems = list_length(vals);
- /*
- * We do not bother to check the list of values for duplicates --- if you
- * have any, you'll get a less-than-friendly unique-index violation. It is
- * probably not worth trying harder.
- */
-
pg_enum = table_open(EnumRelationId, RowExclusiveLock);
/*
@@ -164,6 +158,7 @@ EnumValuesCreate(Oid enumTypeOid, List *vals)
{
char *lab = strVal(lfirst(lc));
Name enumlabel = palloc0(NAMEDATALEN);
+ ListCell *lc2;
/*
* labels are stored in a name field, for easier syscache lookup, so
@@ -176,6 +171,24 @@ EnumValuesCreate(Oid enumTypeOid, List *vals)
errdetail("Labels must be %d bytes or less.",
NAMEDATALEN - 1)));
+ /*
+ * Check for duplicate labels. The unique index on pg_enum would catch
+ * that anyway, but we prefer a friendlier error message.
+ */
+ foreach(lc2, vals)
+ {
+ /* Only need to compare lc to earlier entries */
+ if (lc2 == lc)
+ break;
+
+ if (strcmp(lab, strVal(lfirst(lc2))) == 0)
+ ereport(ERROR,
+ (errcode(ERRCODE_DUPLICATE_OBJECT),
+ errmsg("enum label \"%s\" used more than once",
+ lab)));
+ }
+
+ /* OK, construct a tuple for this label */
ExecClearTuple(slot[slotCount]);
memset(slot[slotCount]->tts_isnull, false,
diff --git a/src/test/regress/expected/enum.out b/src/test/regress/expected/enum.out
index 4d9f36d0d36..990ce66c7bb 100644
--- a/src/test/regress/expected/enum.out
+++ b/src/test/regress/expected/enum.out
@@ -52,6 +52,9 @@ hint |
sql_error_code | 22P02
\x
+-- check for duplicate enum entries
+CREATE TYPE dup_enum AS ENUM ('foo','bar','foo');
+ERROR: enum label "foo" used more than once
--
-- adding new values
--
diff --git a/src/test/regress/sql/enum.sql b/src/test/regress/sql/enum.sql
index ecc4878a678..803ccad6a6b 100644
--- a/src/test/regress/sql/enum.sql
+++ b/src/test/regress/sql/enum.sql
@@ -23,6 +23,9 @@ SELECT * FROM pg_input_error_info('mauve', 'rainbow');
SELECT * FROM pg_input_error_info(repeat('too_long', 32), 'rainbow');
\x
+-- check for duplicate enum entries
+CREATE TYPE dup_enum AS ENUM ('foo','bar','foo');
+
--
-- adding new values
--