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

Commit70988b7

Browse files
committed
Improve makeArrayTypeName's algorithm for choosing array type names.
As before, we start by prepending one underscore (truncating thebase name if necessary). But if there is a conflict, then instead ofprepending more and more underscores, append an underscore and somedigits, in much the same way that ChooseRelationName does. Whilethe previous logic could be driven to fail by creating a lot oftypes with long names differing only near the end, this version seemscertain enough to eventually succeed that we can remove the failurecode path that was there before.While at it, undo6df7a96's decision to split this code out ofmakeArrayTypeName. That wasn't actually accomplishing anything,because no other function was using it --- and it would have beenwrong to do so. The convention that a prefix "_" means an array,not something else, is too ancient to mess with.Andrey Lepikhov and Dmitry Koval, reviewed by Masahiko Sawada and myselfDiscussion:https://postgr.es/m/b84cd82c-cc67-198a-8b1c-60f44e1259ad@postgrespro.ru
1 parent8bb3ad4 commit70988b7

File tree

2 files changed

+37
-59
lines changed

2 files changed

+37
-59
lines changed

‎src/backend/catalog/pg_type.c

Lines changed: 34 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include"catalog/pg_namespace.h"
2727
#include"catalog/pg_proc.h"
2828
#include"catalog/pg_type.h"
29+
#include"commands/defrem.h"
2930
#include"commands/typecmds.h"
3031
#include"mb/pg_wchar.h"
3132
#include"miscadmin.h"
@@ -37,9 +38,6 @@
3738
#include"utils/rel.h"
3839
#include"utils/syscache.h"
3940

40-
staticchar*makeUniqueTypeName(constchar*typeName,OidtypeNamespace,
41-
booltryOriginal);
42-
4341
/* Potentially set by pg_upgrade_support functions */
4442
Oidbinary_upgrade_next_pg_type_oid=InvalidOid;
4543

@@ -815,16 +813,41 @@ RenameTypeInternal(Oid typeOid, const char *newTypeName, Oid typeNamespace)
815813
char*
816814
makeArrayTypeName(constchar*typeName,OidtypeNamespace)
817815
{
818-
char*arr;
816+
char*arr_name;
817+
intpass=0;
818+
charsuffix[NAMEDATALEN];
819819

820-
arr=makeUniqueTypeName(typeName,typeNamespace, false);
821-
if (arr==NULL)
822-
ereport(ERROR,
823-
(errcode(ERRCODE_DUPLICATE_OBJECT),
824-
errmsg("could not form array type name for type \"%s\"",
825-
typeName)));
820+
/*
821+
* Per ancient Postgres tradition, array type names are made by prepending
822+
* an underscore to the base type name. Much client code knows that
823+
* convention, so don't muck with it. However, the tradition is less
824+
* clear about what to do in the corner cases where the resulting name is
825+
* too long or conflicts with an existing name. Our current rules are (1)
826+
* truncate the base name on the right as needed, and (2) if there is a
827+
* conflict, append another underscore and some digits chosen to make it
828+
* unique. This is similar to what ChooseRelationName() does.
829+
*
830+
* The actual name generation can be farmed out to makeObjectName() by
831+
* giving it an empty first name component.
832+
*/
833+
834+
/* First, try with no numeric suffix */
835+
arr_name=makeObjectName("",typeName,NULL);
836+
837+
for (;;)
838+
{
839+
if (!SearchSysCacheExists2(TYPENAMENSP,
840+
CStringGetDatum(arr_name),
841+
ObjectIdGetDatum(typeNamespace)))
842+
break;
843+
844+
/* That attempt conflicted. Prepare a new name with some digits. */
845+
pfree(arr_name);
846+
snprintf(suffix,sizeof(suffix),"%d",++pass);
847+
arr_name=makeObjectName("",typeName,suffix);
848+
}
826849

827-
returnarr;
850+
returnarr_name;
828851
}
829852

830853

@@ -931,48 +954,3 @@ makeMultirangeTypeName(const char *rangeTypeName, Oid typeNamespace)
931954

932955
returnpstrdup(buf);
933956
}
934-
935-
/*
936-
* makeUniqueTypeName
937-
*Generate a unique name for a prospective new type
938-
*
939-
* Given a typeName, return a new palloc'ed name by prepending underscores
940-
* until a non-conflicting name results.
941-
*
942-
* If tryOriginal, first try with zero underscores.
943-
*/
944-
staticchar*
945-
makeUniqueTypeName(constchar*typeName,OidtypeNamespace,booltryOriginal)
946-
{
947-
inti;
948-
intnamelen;
949-
chardest[NAMEDATALEN];
950-
951-
Assert(strlen(typeName) <=NAMEDATALEN-1);
952-
953-
if (tryOriginal&&
954-
!SearchSysCacheExists2(TYPENAMENSP,
955-
CStringGetDatum(typeName),
956-
ObjectIdGetDatum(typeNamespace)))
957-
returnpstrdup(typeName);
958-
959-
/*
960-
* The idea is to prepend underscores as needed until we make a name that
961-
* doesn't collide with anything ...
962-
*/
963-
namelen=strlen(typeName);
964-
for (i=1;i<NAMEDATALEN-1;i++)
965-
{
966-
dest[i-1]='_';
967-
strlcpy(dest+i,typeName,NAMEDATALEN-i);
968-
if (namelen+i >=NAMEDATALEN)
969-
truncate_identifier(dest,NAMEDATALEN, false);
970-
971-
if (!SearchSysCacheExists2(TYPENAMENSP,
972-
CStringGetDatum(dest),
973-
ObjectIdGetDatum(typeNamespace)))
974-
returnpstrdup(dest);
975-
}
976-
977-
returnNULL;
978-
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,9 @@ SELECT typname FROM pg_type WHERE oid = 'attmp_array[]'::regtype;
197197
(1 row)
198198

199199
SELECT typname FROM pg_type WHERE oid = '_attmp_array[]'::regtype;
200-
typname
201-
----------------
202-
___attmp_array
200+
typname
201+
-----------------
202+
__attmp_array_1
203203
(1 row)
204204

205205
DROP TABLE _attmp_array;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp