diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/catalog/pg_enum.c | 29 | ||||
-rw-r--r-- | src/include/nodes/parsenodes.h | 2 | ||||
-rw-r--r-- | src/test/regress/expected/enum.out | 6 | ||||
-rw-r--r-- | src/test/regress/sql/enum.sql | 6 |
4 files changed, 25 insertions, 18 deletions
diff --git a/src/backend/catalog/pg_enum.c b/src/backend/catalog/pg_enum.c index f3161efb20b..bed0f357bb6 100644 --- a/src/backend/catalog/pg_enum.c +++ b/src/backend/catalog/pg_enum.c @@ -212,19 +212,30 @@ AddEnumLabel(Oid enumTypeOid, */ LockDatabaseObject(TypeRelationId, enumTypeOid, 0, ExclusiveLock); - /* Do the "IF NOT EXISTS" test if specified */ - if (skipIfExists) + /* + * Check if label is already in use. The unique index on pg_enum would + * catch this anyway, but we prefer a friendlier error message, and + * besides we need a check to support IF NOT EXISTS. + */ + enum_tup = SearchSysCache2(ENUMTYPOIDNAME, + ObjectIdGetDatum(enumTypeOid), + CStringGetDatum(newVal)); + if (HeapTupleIsValid(enum_tup)) { - HeapTuple tup; - - tup = SearchSysCache2(ENUMTYPOIDNAME, - ObjectIdGetDatum(enumTypeOid), - CStringGetDatum(newVal)); - if (HeapTupleIsValid(tup)) + ReleaseSysCache(enum_tup); + if (skipIfExists) { - ReleaseSysCache(tup); + ereport(NOTICE, + (errcode(ERRCODE_DUPLICATE_OBJECT), + errmsg("enum label \"%s\" already exists, skipping", + newVal))); return; } + else + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_OBJECT), + errmsg("enum label \"%s\" already exists", + newVal))); } pg_enum = heap_open(EnumRelationId, RowExclusiveLock); diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 98fe850c927..214d4f60e32 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -2306,7 +2306,7 @@ typedef struct AlterEnumStmt char *newVal; /* new enum value's name */ char *newValNeighbor; /* neighboring enum value, if specified */ bool newValIsAfter; /* place new enum value after neighbor? */ - bool skipIfExists; /* ignore statement if label already exists */ + bool skipIfExists; /* no error if label already exists */ } AlterEnumStmt; /* ---------------------- diff --git a/src/test/regress/expected/enum.out b/src/test/regress/expected/enum.out index a14097297a1..ed729dddc3f 100644 --- a/src/test/regress/expected/enum.out +++ b/src/test/regress/expected/enum.out @@ -97,11 +97,11 @@ ALTER TYPE planets ADD VALUE 'pluto' AFTER 'zeus'; ERROR: "zeus" is not an existing enum label -- if not exists tests -- existing value gives error --- We can't do this test because the error contains the --- offending Oid value, which is unpredictable. --- ALTER TYPE planets ADD VALUE 'mercury'; +ALTER TYPE planets ADD VALUE 'mercury'; +ERROR: enum label "mercury" already exists -- unless IF NOT EXISTS is specified ALTER TYPE planets ADD VALUE IF NOT EXISTS 'mercury'; +NOTICE: enum label "mercury" already exists, skipping -- should be neptune, not mercury SELECT enum_last(NULL::planets); enum_last diff --git a/src/test/regress/sql/enum.sql b/src/test/regress/sql/enum.sql index db7bf44b408..130a723f698 100644 --- a/src/test/regress/sql/enum.sql +++ b/src/test/regress/sql/enum.sql @@ -57,10 +57,7 @@ ALTER TYPE planets ADD VALUE 'pluto' AFTER 'zeus'; -- if not exists tests -- existing value gives error - --- We can't do this test because the error contains the --- offending Oid value, which is unpredictable. --- ALTER TYPE planets ADD VALUE 'mercury'; +ALTER TYPE planets ADD VALUE 'mercury'; -- unless IF NOT EXISTS is specified ALTER TYPE planets ADD VALUE IF NOT EXISTS 'mercury'; @@ -73,7 +70,6 @@ ALTER TYPE planets ADD VALUE IF NOT EXISTS 'pluto'; -- should be pluto, i.e. the new value SELECT enum_last(NULL::planets); - -- -- Test inserting so many values that we have to renumber -- |