From 126a317976b95ccf4f76c6bbd9e70708282df95a Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Wed, 12 Mar 2025 19:18:39 -0400
Subject: [PATCH v1 2/2] Make ARRAY[] treat int2vector and oidvector like
 ARRAY_SUBLINK does.

Historically ARRAY[oidvector] has decided that the result type
is also oidvector, which it is not really.  This causes visibly
bogus answers in some cases but gives seemingly-sane results
in others; I have not found a case where it'd crash.  Nonetheless,
it's surely very bogus that ARRAY[] and ARRAY_SUBLINK come to
different conclusions.  Make ARRAY[] act like ARRAY_SUBLINK, that
is decide that the result type is oidvector[].  The test cases
created by the previous patch show the change in behavior;
but we have no pre-existing tests that notice, suggesting
strongly that nobody thought about this case.

I looked at other callers of type_is_array and didn't find any
that I wanted to change, so I just hacked up this one test
rather than trying to invent some nicer solution.

This should be applied to master, but I'm unsure whether to
back-patch.

Bug: #18840
Reported-by: yang lei <ylshiyu@126.com>
Author: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/18840-fbc9505f066e50d6@postgresql.org
---
 src/backend/parser/parse_expr.c      | 14 +++++--
 src/test/regress/expected/arrays.out | 62 ++++++++++++----------------
 src/test/regress/sql/arrays.sql      |  2 +-
 3 files changed, 39 insertions(+), 39 deletions(-)

diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index bad1df732ea..9caf1e481a2 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -2053,10 +2053,18 @@ transformArrayExpr(ParseState *pstate, A_ArrayExpr *a,
 
 			/*
 			 * Check for sub-array expressions, if we haven't already found
-			 * one.
+			 * one.  Note we don't accept domain-over-array as a sub-array,
+			 * nor int2vector nor oidvector; those have constraints that don't
+			 * map well to being treated as a sub-array.
 			 */
-			if (!newa->multidims && type_is_array(exprType(newe)))
-				newa->multidims = true;
+			if (!newa->multidims)
+			{
+				Oid			newetype = exprType(newe);
+
+				if (newetype != INT2VECTOROID && newetype != OIDVECTOROID &&
+					type_is_array(newetype))
+					newa->multidims = true;
+			}
 		}
 
 		newelems = lappend(newelems, newe);
diff --git a/src/test/regress/expected/arrays.out b/src/test/regress/expected/arrays.out
index 5b8889cd013..7afd7356bbe 100644
--- a/src/test/regress/expected/arrays.out
+++ b/src/test/regress/expected/arrays.out
@@ -2502,34 +2502,30 @@ select unnest(array(select '11 22 33'::oidvector from generate_series(1,5)));
  11 22 33
 (5 rows)
 
--- array[] really ought to do the same, but historically hasn't
+-- array[] should do the same
 select pg_typeof(array['11 22 33'::int2vector]);
- pg_typeof  
-------------
- int2vector
+  pg_typeof   
+--------------
+ int2vector[]
 (1 row)
 
 select array['11 22 33'::int2vector];
- array 
--------
- 1
+    array     
+--------------
+ {"11 22 33"}
 (1 row)
 
 select pg_typeof(unnest(array['11 22 33'::int2vector]));
- pg_typeof 
------------
- smallint
- smallint
- smallint
-(3 rows)
+ pg_typeof  
+------------
+ int2vector
+(1 row)
 
 select unnest(array['11 22 33'::int2vector]);
- unnest 
---------
-     11
-     22
-     33
-(3 rows)
+  unnest  
+----------
+ 11 22 33
+(1 row)
 
 select pg_typeof(unnest('11 22 33'::int2vector));
  pg_typeof 
@@ -2548,32 +2544,28 @@ select unnest('11 22 33'::int2vector);
 (3 rows)
 
 select pg_typeof(array['11 22 33'::oidvector]);
- pg_typeof 
------------
- oidvector
+  pg_typeof  
+-------------
+ oidvector[]
 (1 row)
 
 select array['11 22 33'::oidvector];
- array 
--------
- 1
+    array     
+--------------
+ {"11 22 33"}
 (1 row)
 
 select pg_typeof(unnest(array['11 22 33'::oidvector]));
  pg_typeof 
 -----------
- oid
- oid
- oid
-(3 rows)
+ oidvector
+(1 row)
 
 select unnest(array['11 22 33'::oidvector]);
- unnest 
---------
-     11
-     22
-     33
-(3 rows)
+  unnest  
+----------
+ 11 22 33
+(1 row)
 
 select pg_typeof(unnest('11 22 33'::oidvector));
  pg_typeof 
diff --git a/src/test/regress/sql/arrays.sql b/src/test/regress/sql/arrays.sql
index 41a360dc18f..399a0797f3b 100644
--- a/src/test/regress/sql/arrays.sql
+++ b/src/test/regress/sql/arrays.sql
@@ -721,7 +721,7 @@ select pg_typeof(array(select '11 22 33'::oidvector from generate_series(1,5)));
 select array(select '11 22 33'::oidvector from generate_series(1,5));
 select unnest(array(select '11 22 33'::oidvector from generate_series(1,5)));
 
--- array[] really ought to do the same, but historically hasn't
+-- array[] should do the same
 select pg_typeof(array['11 22 33'::int2vector]);
 select array['11 22 33'::int2vector];
 select pg_typeof(unnest(array['11 22 33'::int2vector]));
-- 
2.43.5

