Re: general purpose array_sort

jian he <jian.universality@gmail.com>

From: jian he <jian.universality@gmail.com>
To: Dean Rasheed <dean.a.rasheed@gmail.com>
Cc: Junwang Zhao <zhjwpku@gmail.com>, Aleksander Alekseev <aleksander@timescale.com>, PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>, Tom Lane <tgl@sss.pgh.pa.us>, "David G. Johnston" <david.g.johnston@gmail.com>, Amit Langote <amitlangote09@gmail.com>, "andreas@proxel.se" <andreas@proxel.se>, Robert Haas <robertmhaas@gmail.com>
Date: 2024-11-05T07:12:50Z
Lists: pgsql-hackers

Attachments

On Mon, Nov 4, 2024 at 7:34 PM Dean Rasheed <dean.a.rasheed@gmail.com> wrote:
>
> Testing this with an array with non-default lower bounds, it fails to
> preserve the array bounds, which I think it should (note:
> array_reverse() and array_shuffle() do preserve the bounds):
>
> SELECT array_reverse(a), array_shuffle(a), array_sort(a)
>   FROM (VALUES ('[10:12][20:21]={{1,2},{10,20},{3,4}}'::int[])) v(a);
>
> -[ RECORD 1 ]-+-------------------------------------
> array_reverse | [10:12][20:21]={{3,4},{10,20},{1,2}}
> array_shuffle | [10:12][20:21]={{10,20},{3,4},{1,2}}
> array_sort    | [1:3][20:21]={{1,2},{3,4},{10,20}}
>

if i understand it correctly,
array_create_iterator cannot cope with top dimension bound information.
since input array arguments already have dims, lbs information.
so at the end of array_sort directly copy
from the input array argument to astate.

tuplesort_performsort won't need array bounds, we should be safe?



v12-0001 same as v11-0001-general-purpose-array_sort.patch, only
resolve git conflict
v12-0002 preserve array bound information.
v12-0003 cache ArrayMetaState.

after v12-0003 now
typedef struct ArraySortCachedInfo
{
    TypeCacheEntry *typentry;
    TypeCacheEntry *array_typentry;
    ArrayMetaState array_meta;
} ArraySortCachedInfo;

function array_create_iterator, get_typlenbyvalalign
will do cache search, we can cache ArrayMetaState.
so multiple array_create_iterator calls won't need to call get_typlenbyvalalign.
every time.


0002, I also have a 3 dimensional array test.
create table t(a int[]);
insert into t values ('[-1:-0]={7,1}'::int[]),
('[-2:-0][20:21]={{1,2},{10,20},{1,-4}}'),
('[-2:-0][20:22]={{-11,2,-1},{-11,2, 1},{-11,-4, 10}}'),
('[-13:-10][0:1][20:22]={
{{1,2,112},{1,2,-123}},
{{10,-20,1},{11,123,3}},
{{10,-20,1},{11,-123,-9}},
{{1,2,-11},{1,2,211}}}'::int[]);
SELECT array_sort(t.a) from t;
SELECT array_sort((t.a) [-13:-10][0:1][21:22]) from t where array_ndims(a) = 3;
SELECT array_sort((t.a) [-13:-11][0:1][21:22]) from t where array_ndims(a) = 3;
SELECT array_sort((t.a) [-13:-11][0:0][20:21]) from t where array_ndims(a) = 3;

The test output is ok to me.

Commits

  1. Introduce a SQL-callable function array_sort(anyarray).

  2. Fix ARRAY_SUBLINK and ARRAY[] for int2vector and oidvector input.

  3. Re-implement the ereport() macro using __VA_ARGS__.