From: Andrey Lepikhov <a.lepikhov@postgrespro.ru>
To: PostgreSQL mailing lists <pgsql-bugs@lists.postgresql.org>
Cc: d.koval@postgrespro.ru
Subject: Postgres do not allow to create many tables with more than 63-symbols prefix
Date: Fri, 3 Jun 2022 22:02:56 +0300
Message-ID: <121e286f-3796-c9d7-9eab-6fb8e0b9c701@postgrespro.ru> (raw)
According to subj you can try to create many tables (induced by the case
of partitioned table) with long prefix - see 6727v.sql for reproduction.
But now it's impossible because of logic of the makeUniqueTypeName()
routine.
You get the error:
ERROR: could not form array type name for type ...
It is very corner case, of course. But solution is easy and short. So,
why not to fix? - See the patch in attachment.
--
regards,
Andrey Lepikhov
Postgres Professional
Attachments:
6727v.sql (application/sql, 397B) download0001-Allow-postgresql-to-generate-more-relations-with-the.patch (text/plain, 3.6K) download
From e28e0b88ce7bfe79ebd3fa82a3124bf924a9fb53 Mon Sep 17 00:00:00 2001
From: "Andrey V. Lepikhov" <a.lepikhov@postgrespro.ru>
Date: Fri, 3 Jun 2022 21:40:01 +0300
Subject: [PATCH] Allow postgresql to generate more relations with the same 63
symbols long prefix. Rewrite the makeUniqueTypeName routine - generator of
unique name is based on the same idea as the ChooseRelationName() routine.
Authors: Dmitry Koval <d.koval@postgrespro.ru>, Andrey Lepikhov <a.lepikhov@postgrespro.ru>
---
src/backend/catalog/pg_type.c | 41 +++++++++++++----------
src/test/regress/expected/alter_table.out | 6 ++--
2 files changed, 27 insertions(+), 20 deletions(-)
diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.cindex 03788cb975..6977377f40 100644--- a/src/backend/catalog/pg_type.c+++ b/src/backend/catalog/pg_type.c@@ -26,6 +26,7 @@
#include "catalog/pg_namespace.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
+#include "commands/defrem.h"
#include "commands/typecmds.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
@@ -936,17 +937,17 @@ makeMultirangeTypeName(const char *rangeTypeName, Oid typeNamespace)
* makeUniqueTypeName
* Generate a unique name for a prospective new type
*
- * Given a typeName, return a new palloc'ed name by prepending underscores- * until a non-conflicting name results.+ * Given a typeName, return a new palloc'ed name by prepending underscore+ * and (if needed) adding a suffix to the end of the type name.
*
* If tryOriginal, first try with zero underscores.
*/
static char *
makeUniqueTypeName(const char *typeName, Oid typeNamespace, bool tryOriginal)
{
- int i;- int namelen;- char dest[NAMEDATALEN];+ int pass = 0;+ char suffix[NAMEDATALEN];+ char *type_name;
Assert(strlen(typeName) <= NAMEDATALEN - 1);
@@ -956,23 +957,29 @@ makeUniqueTypeName(const char *typeName, Oid typeNamespace, bool tryOriginal)
ObjectIdGetDatum(typeNamespace)))
return pstrdup(typeName);
+ /* Prepare initial object name. Just for compatibility. */+ type_name = makeObjectName("", typeName, NULL);+
/*
- * The idea is to prepend underscores as needed until we make a name that- * doesn't collide with anything ...+ * The idea of unique name generation is similar to ChooseRelationName()+ * implementation logic.
*/
- namelen = strlen(typeName);- for (i = 1; i < NAMEDATALEN - 1; i++)+ do
{
- dest[i - 1] = '_';- strlcpy(dest + i, typeName, NAMEDATALEN - i);- if (namelen + i >= NAMEDATALEN)- truncate_identifier(dest, NAMEDATALEN, false);-
if (!SearchSysCacheExists2(TYPENAMENSP,
- CStringGetDatum(dest),+ CStringGetDatum(type_name),
ObjectIdGetDatum(typeNamespace)))
- return pstrdup(dest);- }+ return type_name;+ /* Previous attempt was failed. Prepare a new one. */+ pfree(type_name);+ snprintf(suffix, sizeof(suffix), "%d", pass++);+ type_name = makeObjectName("", typeName, suffix);+ } while (pass >= 0);++ /*+ * Return NULL only after integer overflow. It seems impossible because+ * of OID limits.+ */
return NULL;
}
diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.outindex 5ede56d9b5..41a019eab7 100644--- a/src/test/regress/expected/alter_table.out+++ b/src/test/regress/expected/alter_table.out@@ -197,9 +197,9 @@ SELECT typname FROM pg_type WHERE oid = 'attmp_array[]'::regtype;
(1 row)
SELECT typname FROM pg_type WHERE oid = '_attmp_array[]'::regtype;
- typname ------------------ ___attmp_array+ typname +-----------------+ __attmp_array_0
(1 row)
DROP TABLE _attmp_array;
--
2.36.1
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-bugs@postgresql.org
Cc: a.lepikhov@postgrespro.ru, pgsql-bugs@lists.postgresql.org, d.koval@postgrespro.ru
Subject: Re: Postgres do not allow to create many tables with more than 63-symbols prefix
In-Reply-To: <121e286f-3796-c9d7-9eab-6fb8e0b9c701@postgrespro.ru>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox