From c44ddba7fba68d8dbc6b467a27e841ce57d7eb45 Mon Sep 17 00:00:00 2001
From: LucaCappelletti94 <cappelletti.luca94@gmail.com>
Date: Tue, 10 Nov 2026 16:41:26 +0100
Subject: [PATCH v1] Use the multirange schema for its array type name

---
 doc/src/sgml/ref/create_type.sgml             |  4 +--
 src/backend/commands/typecmds.c               |  2 +-
 src/test/regress/expected/multirangetypes.out | 28 +++++++++++++++++++
 src/test/regress/sql/multirangetypes.sql      | 20 +++++++++++++
 4 files changed, 51 insertions(+), 3 deletions(-)

diff --git a/doc/src/sgml/ref/create_type.sgml b/doc/src/sgml/ref/create_type.sgml
index 6aa01eb0daa..2d55c15a37e 100644
--- a/doc/src/sgml/ref/create_type.sgml
+++ b/doc/src/sgml/ref/create_type.sgml
@@ -504,10 +504,10 @@ CREATE TYPE <replaceable class="parameter">name</replaceable>
    <para>
     Whenever a user-defined type is created,
     <productname>PostgreSQL</productname> automatically creates an
-    associated array type, whose name consists of the element type's
+    associated array type in the same schema. Its name consists of the element type's
     name prepended with an underscore, and truncated if necessary to keep
     it less than <symbol>NAMEDATALEN</symbol> bytes long.  (If the name
-    so generated collides with an existing type name, the process is
+    so generated collides with an existing type name in that schema, the process is
     repeated until a non-colliding name is found.)
     This implicitly-created array type is variable length and uses the
     built-in input and output functions <literal>array_in</literal> and
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 9f57728129f..da55f96b7e4 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -1753,7 +1753,7 @@ DefineRange(ParseState *pstate, CreateRangeStmt *stmt)
 
 	/* Create the multirange's array type */
 
-	multirangeArrayName = makeArrayTypeName(multirangeTypeName, typeNamespace);
+	multirangeArrayName = makeArrayTypeName(multirangeTypeName, multirangeNamespace);
 
 	TypeCreate(multirangeArrayOid,	/* force assignment of this type OID */
 			   multirangeArrayName, /* type name */
diff --git a/src/test/regress/expected/multirangetypes.out b/src/test/regress/expected/multirangetypes.out
index d22106e5c1c..dba074808de 100644
--- a/src/test/regress/expected/multirangetypes.out
+++ b/src/test/regress/expected/multirangetypes.out
@@ -3231,6 +3231,34 @@ select _textrange1(textrange2('a','z')) @> 'b'::text;
 
 drop type textrange1;
 drop type textrange2;
+-- Multirange array names must avoid collisions in the multirange's schema.
+create schema mr_sch;
+create type mr_sch._mr_type1 as enum ('a');
+create type _mr_type2 as enum ('b');
+create type myrange1 as range (subtype=int4, multirange_type_name=mr_sch.mr_type1);
+create type myrange2 as range (subtype=int4, multirange_type_name=mr_sch.mr_type2);
+select t.typname, a.typname as array_name,
+       a.typnamespace = t.typnamespace as same_schema
+from pg_type t join pg_type a on a.oid = t.typarray
+where t.oid in ('mr_sch.mr_type1'::regtype, 'mr_sch.mr_type2'::regtype)
+order by t.typname;
+ typname  | array_name  | same_schema 
+----------+-------------+-------------
+ mr_type1 | _mr_type1_1 | t
+ mr_type2 | _mr_type2   | t
+(2 rows)
+
+select enum_range(null::mr_sch._mr_type1), enum_range(null::_mr_type2);
+ enum_range | enum_range 
+------------+------------
+ {a}        | {b}
+(1 row)
+
+drop type myrange1;
+drop type myrange2;
+drop type mr_sch._mr_type1;
+drop type _mr_type2;
+drop schema mr_sch;
 --
 -- Multiranges don't have their own ownership or permissions.
 --
diff --git a/src/test/regress/sql/multirangetypes.sql b/src/test/regress/sql/multirangetypes.sql
index 148876b2759..2d89dca37a7 100644
--- a/src/test/regress/sql/multirangetypes.sql
+++ b/src/test/regress/sql/multirangetypes.sql
@@ -722,6 +722,26 @@ select _textrange1(textrange2('a','z')) @> 'b'::text;
 drop type textrange1;
 drop type textrange2;
 
+-- Multirange array names must avoid collisions in the multirange's schema.
+create schema mr_sch;
+create type mr_sch._mr_type1 as enum ('a');
+create type _mr_type2 as enum ('b');
+create type myrange1 as range (subtype=int4, multirange_type_name=mr_sch.mr_type1);
+create type myrange2 as range (subtype=int4, multirange_type_name=mr_sch.mr_type2);
+
+select t.typname, a.typname as array_name,
+       a.typnamespace = t.typnamespace as same_schema
+from pg_type t join pg_type a on a.oid = t.typarray
+where t.oid in ('mr_sch.mr_type1'::regtype, 'mr_sch.mr_type2'::regtype)
+order by t.typname;
+select enum_range(null::mr_sch._mr_type1), enum_range(null::_mr_type2);
+
+drop type myrange1;
+drop type myrange2;
+drop type mr_sch._mr_type1;
+drop type _mr_type2;
+drop schema mr_sch;
+
 --
 -- Multiranges don't have their own ownership or permissions.
 --
