pg.ddx.io  pgsql-bugs@postgresql.org mailing list archive  
help / color / mirror / Atom feed
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) download

0001-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.c index 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.out index 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

view thread (2+ messages)  latest in thread

Message-ID: <121e286f-3796-c9d7-9eab-6fb8e0b9c701@postgrespro.ru>
Permalink:  ../121e286f-3796-c9d7-9eab-6fb8e0b9c701@postgrespro.ru/
Also on:    postgresql.org/message-id/121e286f-3796-c9d7-9eab-6fb8e0b9c701@postgrespro.ru

 ·  · 

reply

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