|
26 | 26 | #include "catalog/pg_namespace.h"
|
27 | 27 | #include "catalog/pg_proc.h"
|
28 | 28 | #include "catalog/pg_type.h"
|
| 29 | +#include "commands/defrem.h" |
29 | 30 | #include "commands/typecmds.h"
|
30 | 31 | #include "mb/pg_wchar.h"
|
31 | 32 | #include "miscadmin.h"
|
|
37 | 38 | #include "utils/rel.h"
|
38 | 39 | #include "utils/syscache.h"
|
39 | 40 |
|
40 |
| -static char *makeUniqueTypeName(const char *typeName, Oid typeNamespace, |
41 |
| - bool tryOriginal); |
42 |
| - |
43 | 41 | /* Potentially set by pg_upgrade_support functions */
|
44 | 42 | Oid binary_upgrade_next_pg_type_oid = InvalidOid;
|
45 | 43 |
|
@@ -815,16 +813,41 @@ RenameTypeInternal(Oid typeOid, const char *newTypeName, Oid typeNamespace)
|
815 | 813 | char *
|
816 | 814 | makeArrayTypeName(const char *typeName, Oid typeNamespace)
|
817 | 815 | {
|
818 |
| - char *arr; |
| 816 | + char *arr_name; |
| 817 | + int pass = 0; |
| 818 | + char suffix[NAMEDATALEN]; |
819 | 819 |
|
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 | + } |
826 | 849 |
|
827 |
| - return arr; |
| 850 | + return arr_name; |
828 | 851 | }
|
829 | 852 |
|
830 | 853 |
|
@@ -931,48 +954,3 @@ makeMultirangeTypeName(const char *rangeTypeName, Oid typeNamespace)
|
931 | 954 |
|
932 | 955 | return pstrdup(buf);
|
933 | 956 | }
|
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 |
| -static char * |
945 |
| -makeUniqueTypeName(const char *typeName, Oid typeNamespace, bool tryOriginal) |
946 |
| -{ |
947 |
| - int i; |
948 |
| - int namelen; |
949 |
| - char dest[NAMEDATALEN]; |
950 |
| - |
951 |
| - Assert(strlen(typeName) <= NAMEDATALEN - 1); |
952 |
| - |
953 |
| - if (tryOriginal && |
954 |
| - !SearchSysCacheExists2(TYPENAMENSP, |
955 |
| - CStringGetDatum(typeName), |
956 |
| - ObjectIdGetDatum(typeNamespace))) |
957 |
| - return pstrdup(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 |
| - return pstrdup(dest); |
975 |
| - } |
976 |
| - |
977 |
| - return NULL; |
978 |
| -} |
0 commit comments