diff options
-rw-r--r-- | src/backend/catalog/pg_enum.c | 25 | ||||
-rw-r--r-- | src/test/regress/expected/enum.out | 3 | ||||
-rw-r--r-- | src/test/regress/sql/enum.sql | 3 |
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 -- |