Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit474aee3

Browse files
committed
Fix ARRAY_SUBLINK and ARRAY[] for int2vector and oidvector input.
If the given input_type yields valid results from bothget_element_type and get_array_type, initArrayResultAny believed theformer and treated the input as an array type. However this isinconsistent with what get_promoted_array_type does, leading tosituations where the output of an ARRAY() subquery is labeled withthe wrong type: it's labeled as oidvector[] but is really a 2-Darray of OID. That at least results in strange output, and canresult in crashes if further processing such as unnest() is applied.AFAIK this is only possible with the int2vector and oidvectortypes, which are special-cased to be treated mostly as true arrayseven though they aren't quite.Fix by switching the logic to match get_promoted_array_type bytesting get_array_type not get_element_type, and remove an Assertthereby made pointless. (We need not introduce a symmetricalcheck for get_element_type in the other if-branch, becauseinitArrayResultArr will check it.) This restores the behaviorthat existed beforebac2739 introduced initArrayResultAny:the output really is int2vector[] or oidvector[].Comparable confusion exists when an input of an ARRAY[] constructis int2vector or oidvector: transformArrayExpr decides it's dealingwith a multidimensional array constructor, and we end up withsomething that's a multidimensional OID array but is alleged to beof type oidvector. I have not found a crashing case here, but it'seasy to demonstrate totally-wrong results. Adjust that code sothat what you get is an oidvector[] instead, for consistency withARRAY() subqueries. (This change also makes these types work likedomains-over-arrays in this context, which seems correct.)Bug: #18840Reported-by: yang lei <ylshiyu@126.com>Author: Tom Lane <tgl@sss.pgh.pa.us>Discussion:https://postgr.es/m/18840-fbc9505f066e50d6@postgresql.orgBackpatch-through: 13
1 parentb200180 commit474aee3

File tree

4 files changed

+166
-8
lines changed

4 files changed

+166
-8
lines changed

‎src/backend/parser/parse_expr.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2155,10 +2155,18 @@ transformArrayExpr(ParseState *pstate, A_ArrayExpr *a,
21552155

21562156
/*
21572157
* Check for sub-array expressions, if we haven't already found
2158-
* one.
2158+
* one. Note we don't accept domain-over-array as a sub-array,
2159+
* nor int2vector nor oidvector; those have constraints that don't
2160+
* map well to being treated as a sub-array.
21592161
*/
2160-
if (!newa->multidims&&type_is_array(exprType(newe)))
2161-
newa->multidims= true;
2162+
if (!newa->multidims)
2163+
{
2164+
Oidnewetype=exprType(newe);
2165+
2166+
if (newetype!=INT2VECTOROID&&newetype!=OIDVECTOROID&&
2167+
type_is_array(newetype))
2168+
newa->multidims= true;
2169+
}
21622170
}
21632171

21642172
newelems=lappend(newelems,newe);

‎src/backend/utils/adt/arrayfuncs.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5541,9 +5541,14 @@ ArrayBuildStateAny *
55415541
initArrayResultAny(Oidinput_type,MemoryContextrcontext,boolsubcontext)
55425542
{
55435543
ArrayBuildStateAny*astate;
5544-
Oidelement_type=get_element_type(input_type);
55455544

5546-
if (OidIsValid(element_type))
5545+
/*
5546+
* int2vector and oidvector will satisfy both get_element_type and
5547+
* get_array_type. We prefer to treat them as scalars, to be consistent
5548+
* with get_promoted_array_type. Hence, check get_array_type not
5549+
* get_element_type.
5550+
*/
5551+
if (!OidIsValid(get_array_type(input_type)))
55475552
{
55485553
/* Array case */
55495554
ArrayBuildStateArr*arraystate;
@@ -5560,9 +5565,6 @@ initArrayResultAny(Oid input_type, MemoryContext rcontext, bool subcontext)
55605565
/* Scalar case */
55615566
ArrayBuildState*scalarstate;
55625567

5563-
/* Let's just check that we have a type that can be put into arrays */
5564-
Assert(OidIsValid(get_array_type(input_type)));
5565-
55665568
scalarstate=initArrayResult(input_type,rcontext,subcontext);
55675569
astate= (ArrayBuildStateAny*)
55685570
MemoryContextAlloc(scalarstate->mcontext,

‎src/test/regress/expected/arrays.out

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2128,6 +2128,132 @@ select array(select array['Hello', i::text] from generate_series(9,11) i);
21282128
{{Hello,9},{Hello,10},{Hello,11}}
21292129
(1 row)
21302130

2131+
-- int2vector and oidvector should be treated as scalar types for this purpose
2132+
select pg_typeof(array(select '11 22 33'::int2vector from generate_series(1,5)));
2133+
pg_typeof
2134+
--------------
2135+
int2vector[]
2136+
(1 row)
2137+
2138+
select array(select '11 22 33'::int2vector from generate_series(1,5));
2139+
array
2140+
----------------------------------------------------------
2141+
{"11 22 33","11 22 33","11 22 33","11 22 33","11 22 33"}
2142+
(1 row)
2143+
2144+
select unnest(array(select '11 22 33'::int2vector from generate_series(1,5)));
2145+
unnest
2146+
----------
2147+
11 22 33
2148+
11 22 33
2149+
11 22 33
2150+
11 22 33
2151+
11 22 33
2152+
(5 rows)
2153+
2154+
select pg_typeof(array(select '11 22 33'::oidvector from generate_series(1,5)));
2155+
pg_typeof
2156+
-------------
2157+
oidvector[]
2158+
(1 row)
2159+
2160+
select array(select '11 22 33'::oidvector from generate_series(1,5));
2161+
array
2162+
----------------------------------------------------------
2163+
{"11 22 33","11 22 33","11 22 33","11 22 33","11 22 33"}
2164+
(1 row)
2165+
2166+
select unnest(array(select '11 22 33'::oidvector from generate_series(1,5)));
2167+
unnest
2168+
----------
2169+
11 22 33
2170+
11 22 33
2171+
11 22 33
2172+
11 22 33
2173+
11 22 33
2174+
(5 rows)
2175+
2176+
-- array[] should do the same
2177+
select pg_typeof(array['11 22 33'::int2vector]);
2178+
pg_typeof
2179+
--------------
2180+
int2vector[]
2181+
(1 row)
2182+
2183+
select array['11 22 33'::int2vector];
2184+
array
2185+
--------------
2186+
{"11 22 33"}
2187+
(1 row)
2188+
2189+
select pg_typeof(unnest(array['11 22 33'::int2vector]));
2190+
pg_typeof
2191+
------------
2192+
int2vector
2193+
(1 row)
2194+
2195+
select unnest(array['11 22 33'::int2vector]);
2196+
unnest
2197+
----------
2198+
11 22 33
2199+
(1 row)
2200+
2201+
select pg_typeof(unnest('11 22 33'::int2vector));
2202+
pg_typeof
2203+
-----------
2204+
smallint
2205+
smallint
2206+
smallint
2207+
(3 rows)
2208+
2209+
select unnest('11 22 33'::int2vector);
2210+
unnest
2211+
--------
2212+
11
2213+
22
2214+
33
2215+
(3 rows)
2216+
2217+
select pg_typeof(array['11 22 33'::oidvector]);
2218+
pg_typeof
2219+
-------------
2220+
oidvector[]
2221+
(1 row)
2222+
2223+
select array['11 22 33'::oidvector];
2224+
array
2225+
--------------
2226+
{"11 22 33"}
2227+
(1 row)
2228+
2229+
select pg_typeof(unnest(array['11 22 33'::oidvector]));
2230+
pg_typeof
2231+
-----------
2232+
oidvector
2233+
(1 row)
2234+
2235+
select unnest(array['11 22 33'::oidvector]);
2236+
unnest
2237+
----------
2238+
11 22 33
2239+
(1 row)
2240+
2241+
select pg_typeof(unnest('11 22 33'::oidvector));
2242+
pg_typeof
2243+
-----------
2244+
oid
2245+
oid
2246+
oid
2247+
(3 rows)
2248+
2249+
select unnest('11 22 33'::oidvector);
2250+
unnest
2251+
--------
2252+
11
2253+
22
2254+
33
2255+
(3 rows)
2256+
21312257
-- Insert/update on a column that is array of composite
21322258
create temp table t1 (f1 int8_tbl[]);
21332259
insert into t1 (f1[5].q1) values(42);

‎src/test/regress/sql/arrays.sql

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,28 @@ select array_replace(array['AB',NULL,'CDE'],NULL,'12');
637637
select array(select array[i,i/2]from generate_series(1,5) i);
638638
select array(select array['Hello', i::text]from generate_series(9,11) i);
639639

640+
-- int2vector and oidvector should be treated as scalar types for this purpose
641+
select pg_typeof(array(select'11 22 33'::int2vectorfrom generate_series(1,5)));
642+
select array(select'11 22 33'::int2vectorfrom generate_series(1,5));
643+
select unnest(array(select'11 22 33'::int2vectorfrom generate_series(1,5)));
644+
select pg_typeof(array(select'11 22 33'::oidvectorfrom generate_series(1,5)));
645+
select array(select'11 22 33'::oidvectorfrom generate_series(1,5));
646+
select unnest(array(select'11 22 33'::oidvectorfrom generate_series(1,5)));
647+
648+
-- array[] should do the same
649+
select pg_typeof(array['11 22 33'::int2vector]);
650+
select array['11 22 33'::int2vector];
651+
select pg_typeof(unnest(array['11 22 33'::int2vector]));
652+
select unnest(array['11 22 33'::int2vector]);
653+
select pg_typeof(unnest('11 22 33'::int2vector));
654+
select unnest('11 22 33'::int2vector);
655+
select pg_typeof(array['11 22 33'::oidvector]);
656+
select array['11 22 33'::oidvector];
657+
select pg_typeof(unnest(array['11 22 33'::oidvector]));
658+
select unnest(array['11 22 33'::oidvector]);
659+
select pg_typeof(unnest('11 22 33'::oidvector));
660+
select unnest('11 22 33'::oidvector);
661+
640662
-- Insert/update on a column that is array of composite
641663

642664
create temp table t1 (f1 int8_tbl[]);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp