Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit94aced8

Browse files
committed
Move autogenerated array types out of the way during ALTER ... RENAME.
Commit9aa3c78 added code to allow CREATE TABLE/CREATE TYPE to not failwhen the desired type name conflicts with an autogenerated array type, bydint of renaming the array type out of the way. But I (tgl) overlookedthat the same case arises in ALTER TABLE/TYPE RENAME. Fix that too.Back-patch to all supported branches.Report and patch by Vik Fearing, modified a bit by meDiscussion:https://postgr.es/m/0f4ade49-4f0b-a9a3-c120-7589f01d1eb8@2ndquadrant.com
1 parent0461b66 commit94aced8

File tree

3 files changed

+98
-9
lines changed

3 files changed

+98
-9
lines changed

‎src/backend/catalog/pg_type.c

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,7 @@ RenameTypeInternal(Oid typeOid, const char *newTypeName, Oid typeNamespace)
695695
HeapTupletuple;
696696
Form_pg_typetyp;
697697
OidarrayOid;
698+
OidoldTypeOid;
698699

699700
pg_type_desc=heap_open(TypeRelationId,RowExclusiveLock);
700701

@@ -708,13 +709,28 @@ RenameTypeInternal(Oid typeOid, const char *newTypeName, Oid typeNamespace)
708709

709710
arrayOid=typ->typarray;
710711

711-
/* Just to give a more friendly error than unique-index violation */
712-
if (SearchSysCacheExists2(TYPENAMENSP,
713-
CStringGetDatum(newTypeName),
714-
ObjectIdGetDatum(typeNamespace)))
715-
ereport(ERROR,
716-
(errcode(ERRCODE_DUPLICATE_OBJECT),
717-
errmsg("type \"%s\" already exists",newTypeName)));
712+
/* Check for a conflicting type name. */
713+
oldTypeOid=GetSysCacheOid2(TYPENAMENSP,
714+
CStringGetDatum(newTypeName),
715+
ObjectIdGetDatum(typeNamespace));
716+
717+
/*
718+
* If there is one, see if it's an autogenerated array type, and if so
719+
* rename it out of the way. (But we must skip that for a shell type
720+
* because moveArrayTypeName will do the wrong thing in that case.)
721+
* Otherwise, we can at least give a more friendly error than unique-index
722+
* violation.
723+
*/
724+
if (OidIsValid(oldTypeOid))
725+
{
726+
if (get_typisdefined(oldTypeOid)&&
727+
moveArrayTypeName(oldTypeOid,newTypeName,typeNamespace))
728+
/* successfully dodged the problem */ ;
729+
else
730+
ereport(ERROR,
731+
(errcode(ERRCODE_DUPLICATE_OBJECT),
732+
errmsg("type \"%s\" already exists",newTypeName)));
733+
}
718734

719735
/* OK, do the rename --- tuple is a copy, so OK to scribble on it */
720736
namestrcpy(&(typ->typname),newTypeName);
@@ -726,8 +742,12 @@ RenameTypeInternal(Oid typeOid, const char *newTypeName, Oid typeNamespace)
726742
heap_freetuple(tuple);
727743
heap_close(pg_type_desc,RowExclusiveLock);
728744

729-
/* If the type has an array type, recurse to handle that */
730-
if (OidIsValid(arrayOid))
745+
/*
746+
* If the type has an array type, recurse to handle that. But we don't
747+
* need to do anything more if we already renamed that array type above
748+
* (which would happen when, eg, renaming "foo" to "_foo").
749+
*/
750+
if (OidIsValid(arrayOid)&&arrayOid!=oldTypeOid)
731751
{
732752
char*arrname=makeArrayTypeName(newTypeName,typeNamespace);
733753

‎src/test/regress/expected/alter_table.out

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,55 @@ SELECT * FROM tmp_new2;
128128

129129
DROP TABLE tmp_new;
130130
DROP TABLE tmp_new2;
131+
--
132+
-- check renaming to a table's array type's autogenerated name
133+
-- (the array type's name should get out of the way)
134+
--
135+
CREATE TABLE tmp_array (id int);
136+
CREATE TABLE tmp_array2 (id int);
137+
SELECT typname FROM pg_type WHERE oid = 'tmp_array[]'::regtype;
138+
typname
139+
------------
140+
_tmp_array
141+
(1 row)
142+
143+
SELECT typname FROM pg_type WHERE oid = 'tmp_array2[]'::regtype;
144+
typname
145+
-------------
146+
_tmp_array2
147+
(1 row)
148+
149+
ALTER TABLE tmp_array2 RENAME TO _tmp_array;
150+
SELECT typname FROM pg_type WHERE oid = 'tmp_array[]'::regtype;
151+
typname
152+
-------------
153+
__tmp_array
154+
(1 row)
155+
156+
SELECT typname FROM pg_type WHERE oid = '_tmp_array[]'::regtype;
157+
typname
158+
--------------
159+
___tmp_array
160+
(1 row)
161+
162+
DROP TABLE _tmp_array;
163+
DROP TABLE tmp_array;
164+
-- renaming to table's own array type's name is an interesting corner case
165+
CREATE TABLE tmp_array (id int);
166+
SELECT typname FROM pg_type WHERE oid = 'tmp_array[]'::regtype;
167+
typname
168+
------------
169+
_tmp_array
170+
(1 row)
171+
172+
ALTER TABLE tmp_array RENAME TO _tmp_array;
173+
SELECT typname FROM pg_type WHERE oid = '_tmp_array[]'::regtype;
174+
typname
175+
-------------
176+
__tmp_array
177+
(1 row)
178+
179+
DROP TABLE _tmp_array;
131180
-- ALTER TABLE ... RENAME on non-table relations
132181
-- renaming indexes (FIXME: this should probably test the index's functionality)
133182
ALTER INDEX IF EXISTS __onek_unique1 RENAME TO tmp_onek_unique1;

‎src/test/regress/sql/alter_table.sql

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,26 @@ SELECT * FROM tmp_new2;
165165
DROPTABLE tmp_new;
166166
DROPTABLE tmp_new2;
167167

168+
--
169+
-- check renaming to a table's array type's autogenerated name
170+
-- (the array type's name should get out of the way)
171+
--
172+
CREATETABLEtmp_array (idint);
173+
CREATETABLEtmp_array2 (idint);
174+
SELECT typnameFROM pg_typeWHEREoid='tmp_array[]'::regtype;
175+
SELECT typnameFROM pg_typeWHEREoid='tmp_array2[]'::regtype;
176+
ALTERTABLE tmp_array2 RENAME TO _tmp_array;
177+
SELECT typnameFROM pg_typeWHEREoid='tmp_array[]'::regtype;
178+
SELECT typnameFROM pg_typeWHEREoid='_tmp_array[]'::regtype;
179+
DROPTABLE _tmp_array;
180+
DROPTABLE tmp_array;
181+
182+
-- renaming to table's own array type's name is an interesting corner case
183+
CREATETABLEtmp_array (idint);
184+
SELECT typnameFROM pg_typeWHEREoid='tmp_array[]'::regtype;
185+
ALTERTABLE tmp_array RENAME TO _tmp_array;
186+
SELECT typnameFROM pg_typeWHEREoid='_tmp_array[]'::regtype;
187+
DROPTABLE _tmp_array;
168188

169189
-- ALTER TABLE ... RENAME on non-table relations
170190
-- renaming indexes (FIXME: this should probably test the index's functionality)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp