mirror of
https://github.com/postgres/postgres.git
synced 2025-04-29 13:56:47 +03:00
Minor corrections for ALTER TYPE ADD VALUE IF NOT EXISTS patch.
Produce a NOTICE when the label already exists, for consistency with other CREATE IF NOT EXISTS commands. Also, fix the code so it produces something more user-friendly than an index violation when the label already exists. This not incidentally enables making a regression test that the previous patch didn't make for fear of exposing an unpredictable OID in the results. Also some wordsmithing on the documentation.
This commit is contained in:
parent
fcc1576687
commit
31510194cc
@ -109,15 +109,16 @@ ALTER TYPE <replaceable class="PARAMETER">name</replaceable> ADD VALUE [ IF NOT
|
|||||||
<term><literal>ADD VALUE [ IF NOT EXISTS ] [ BEFORE | AFTER ]</literal></term>
|
<term><literal>ADD VALUE [ IF NOT EXISTS ] [ BEFORE | AFTER ]</literal></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
This form adds a new value to an enum type. If the new value's place in
|
This form adds a new value to an enum type. The new value's place in
|
||||||
the enum's ordering is not specified using <literal>BEFORE</literal> or
|
the enum's ordering can be specified as being <literal>BEFORE</literal>
|
||||||
<literal>AFTER</literal>, then the new item is placed at the end of the
|
or <literal>AFTER</literal> one of the existing values. Otherwise,
|
||||||
list of values.
|
the new item is added at the end of the list of values.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
If <literal>IF NOT EXISTS</literal> is used, it is not an error if the
|
If <literal>IF NOT EXISTS</literal> is specified, it is not an error if
|
||||||
type already contains the new value, and no action is taken. Otherwise,
|
the type already contains the new value: a notice is issued but no other
|
||||||
an error will occur if the new value is already present.
|
action is taken. Otherwise, an error will occur if the new value is
|
||||||
|
already present.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -212,19 +212,30 @@ AddEnumLabel(Oid enumTypeOid,
|
|||||||
*/
|
*/
|
||||||
LockDatabaseObject(TypeRelationId, enumTypeOid, 0, ExclusiveLock);
|
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;
|
ReleaseSysCache(enum_tup);
|
||||||
|
if (skipIfExists)
|
||||||
tup = SearchSysCache2(ENUMTYPOIDNAME,
|
|
||||||
ObjectIdGetDatum(enumTypeOid),
|
|
||||||
CStringGetDatum(newVal));
|
|
||||||
if (HeapTupleIsValid(tup))
|
|
||||||
{
|
{
|
||||||
ReleaseSysCache(tup);
|
ereport(NOTICE,
|
||||||
|
(errcode(ERRCODE_DUPLICATE_OBJECT),
|
||||||
|
errmsg("enum label \"%s\" already exists, skipping",
|
||||||
|
newVal)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_DUPLICATE_OBJECT),
|
||||||
|
errmsg("enum label \"%s\" already exists",
|
||||||
|
newVal)));
|
||||||
}
|
}
|
||||||
|
|
||||||
pg_enum = heap_open(EnumRelationId, RowExclusiveLock);
|
pg_enum = heap_open(EnumRelationId, RowExclusiveLock);
|
||||||
|
@ -2306,7 +2306,7 @@ typedef struct AlterEnumStmt
|
|||||||
char *newVal; /* new enum value's name */
|
char *newVal; /* new enum value's name */
|
||||||
char *newValNeighbor; /* neighboring enum value, if specified */
|
char *newValNeighbor; /* neighboring enum value, if specified */
|
||||||
bool newValIsAfter; /* place new enum value after neighbor? */
|
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;
|
} AlterEnumStmt;
|
||||||
|
|
||||||
/* ----------------------
|
/* ----------------------
|
||||||
|
@ -97,11 +97,11 @@ ALTER TYPE planets ADD VALUE 'pluto' AFTER 'zeus';
|
|||||||
ERROR: "zeus" is not an existing enum label
|
ERROR: "zeus" is not an existing enum label
|
||||||
-- if not exists tests
|
-- if not exists tests
|
||||||
-- existing value gives error
|
-- existing value gives error
|
||||||
-- We can't do this test because the error contains the
|
ALTER TYPE planets ADD VALUE 'mercury';
|
||||||
-- offending Oid value, which is unpredictable.
|
ERROR: enum label "mercury" already exists
|
||||||
-- ALTER TYPE planets ADD VALUE 'mercury';
|
|
||||||
-- unless IF NOT EXISTS is specified
|
-- unless IF NOT EXISTS is specified
|
||||||
ALTER TYPE planets ADD VALUE IF NOT EXISTS 'mercury';
|
ALTER TYPE planets ADD VALUE IF NOT EXISTS 'mercury';
|
||||||
|
NOTICE: enum label "mercury" already exists, skipping
|
||||||
-- should be neptune, not mercury
|
-- should be neptune, not mercury
|
||||||
SELECT enum_last(NULL::planets);
|
SELECT enum_last(NULL::planets);
|
||||||
enum_last
|
enum_last
|
||||||
|
@ -57,10 +57,7 @@ ALTER TYPE planets ADD VALUE 'pluto' AFTER 'zeus';
|
|||||||
-- if not exists tests
|
-- if not exists tests
|
||||||
|
|
||||||
-- existing value gives error
|
-- existing value gives error
|
||||||
|
ALTER TYPE planets ADD VALUE 'mercury';
|
||||||
-- We can't do this test because the error contains the
|
|
||||||
-- offending Oid value, which is unpredictable.
|
|
||||||
-- ALTER TYPE planets ADD VALUE 'mercury';
|
|
||||||
|
|
||||||
-- unless IF NOT EXISTS is specified
|
-- unless IF NOT EXISTS is specified
|
||||||
ALTER TYPE planets ADD VALUE IF NOT EXISTS 'mercury';
|
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
|
-- should be pluto, i.e. the new value
|
||||||
SELECT enum_last(NULL::planets);
|
SELECT enum_last(NULL::planets);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Test inserting so many values that we have to renumber
|
-- Test inserting so many values that we have to renumber
|
||||||
--
|
--
|
||||||
|
Loading…
x
Reference in New Issue
Block a user