1
0
mirror of https://github.com/postgres/postgres.git synced 2025-12-19 17:02:53 +03:00

Introduce a SQL-callable function array_sort(anyarray).

Create a function that will sort the elements of an array
according to the element type's sort order.  If the array
has more than one dimension, the sub-arrays of the first
dimension are sorted per normal array-comparison rules,
leaving their contents alone.

In support of this, add pg_type.typarray to the set of fields
cached by the typcache.

Author: Junwang Zhao <zhjwpku@gmail.com>
Co-authored-by: Jian He <jian.universality@gmail.com>
Reviewed-by: Aleksander Alekseev <aleksander@timescale.com>
Discussion: https://postgr.es/m/CAEG8a3J41a4dpw_-F94fF-JPRXYxw-GfsgoGotKcjs9LVfEEvw@mail.gmail.com
This commit is contained in:
Tom Lane
2025-04-01 18:03:55 -04:00
parent 6da2ba1d8a
commit 6c12ae09f5
11 changed files with 426 additions and 1 deletions

View File

@@ -2860,3 +2860,145 @@ SELECT array_reverse('{{1,2},{3,4},{5,6},{7,8}}'::int[]);
{{7,8},{5,6},{3,4},{1,2}}
(1 row)
-- array_sort
SELECT array_sort('{}'::int[]);
array_sort
------------
{}
(1 row)
SELECT array_sort('{1}'::int[]);
array_sort
------------
{1}
(1 row)
SELECT array_sort('{1,3,5,2,4,6}'::int[]);
array_sort
---------------
{1,2,3,4,5,6}
(1 row)
SELECT array_sort('{1.1,3.3,5.5,2.2,4.4,6.6}'::numeric[]);
array_sort
---------------------------
{1.1,2.2,3.3,4.4,5.5,6.6}
(1 row)
SELECT array_sort('{foo,bar,CCC,Abc,bbc}'::text[] COLLATE "C");
array_sort
-----------------------
{Abc,CCC,bar,bbc,foo}
(1 row)
SELECT array_sort('{foo,bar,null,CCC,Abc,bbc}'::text[] COLLATE "C");
array_sort
----------------------------
{Abc,CCC,bar,bbc,foo,NULL}
(1 row)
SELECT array_sort(ARRAY(SELECT '1 4'::int2vector UNION ALL SELECT '1 2'::int2vector));
array_sort
---------------
{"1 2","1 4"}
(1 row)
-- array_sort with order specified
SELECT array_sort('{1.1,3.3,5.5,2.2,null,4.4,6.6}'::float8[], true);
array_sort
--------------------------------
{NULL,6.6,5.5,4.4,3.3,2.2,1.1}
(1 row)
SELECT array_sort('{1.1,3.3,5.5,2.2,null,4.4,6.6}'::float8[], false);
array_sort
--------------------------------
{1.1,2.2,3.3,4.4,5.5,6.6,NULL}
(1 row)
-- array_sort with order and nullsfirst flag specified
SELECT array_sort('{1.1,3.3,5.5,2.2,null,4.4,6.6}'::float8[], true, true);
array_sort
--------------------------------
{NULL,6.6,5.5,4.4,3.3,2.2,1.1}
(1 row)
SELECT array_sort('{1.1,3.3,5.5,2.2,null,4.4,6.6}'::float8[], true, false);
array_sort
--------------------------------
{6.6,5.5,4.4,3.3,2.2,1.1,NULL}
(1 row)
SELECT array_sort('{1.1,3.3,5.5,2.2,null,4.4,6.6}'::float8[], false, true);
array_sort
--------------------------------
{NULL,1.1,2.2,3.3,4.4,5.5,6.6}
(1 row)
SELECT array_sort('{1.1,3.3,5.5,2.2,null,4.4,6.6}'::float8[], false, false);
array_sort
--------------------------------
{1.1,2.2,3.3,4.4,5.5,6.6,NULL}
(1 row)
-- multidimensional array tests
SELECT array_sort('{{1}}'::int[]);
array_sort
------------
{{1}}
(1 row)
SELECT array_sort(ARRAY[[2,4],[2,1],[6,5]]);
array_sort
---------------------
{{2,1},{2,4},{6,5}}
(1 row)
SELECT array_sort('{{"1 2","3 4"}, {"1 -2","-1 4"}}'::int2vector[]);
array_sort
---------------------------------
{{"1 -2","-1 4"},{"1 2","3 4"}}
(1 row)
-- no ordering operator tests
SELECT array_sort('{1}'::xid[]); -- no error because no sort is required
array_sort
------------
{1}
(1 row)
SELECT array_sort('{1,2,3}'::xid[]);
ERROR: could not identify a comparison function for type xid
SELECT array_sort('{{1,2,3},{2,3,4}}'::xid[]);
ERROR: could not identify a comparison function for type xid
-- bounds preservation tests
SELECT array_sort(a) FROM (VALUES ('[10:12][20:21]={{1,2},{10,20},{3,4}}'::int[])) v(a);
array_sort
--------------------------------------
[10:12][20:21]={{1,2},{3,4},{10,20}}
(1 row)
SELECT array_sort(a) FROM (VALUES ('[-1:0]={7,1}'::int[])) v(a);
array_sort
--------------
[-1:0]={1,7}
(1 row)
SELECT array_sort(a) FROM (VALUES ('[-2:0][20:21]={{1,2},{10,20},{1,-4}}'::int[])) v(a);
array_sort
--------------------------------------
[-2:0][20:21]={{1,-4},{1,2},{10,20}}
(1 row)
SELECT array_sort(a [-1:0]) FROM (VALUES ('[-2:0][20:21]={{1,2},{10,20},{1,-4}}'::int[])) v(a);
array_sort
------------------
{{1,-4},{10,20}}
(1 row)
SELECT array_sort(a [-1:0][20:20]) FROM (VALUES ('[-2:0][20:21]={{1,2},{10,20},{1,-4}}'::int[])) v(a);
array_sort
------------
{{1},{10}}
(1 row)

View File

@@ -1471,6 +1471,19 @@ SELECT 'abc' <= 'ABC' COLLATE case_insensitive, 'abc' >= 'ABC' COLLATE case_inse
t | t
(1 row)
-- tests with array_sort
SELECT array_sort('{a,B}'::text[] COLLATE case_insensitive);
array_sort
------------
{a,B}
(1 row)
SELECT array_sort('{a,B}'::text[] COLLATE "C");
array_sort
------------
{B,a}
(1 row)
-- test language tags
CREATE COLLATION lt_insensitive (provider = icu, locale = 'en-u-ks-level1', deterministic = false);
SELECT 'aBcD' COLLATE lt_insensitive = 'AbCd' COLLATE lt_insensitive;

View File

@@ -856,3 +856,39 @@ SELECT array_reverse('{1}'::int[]);
SELECT array_reverse('{1,2}'::int[]);
SELECT array_reverse('{1,2,3,NULL,4,5,6}'::int[]);
SELECT array_reverse('{{1,2},{3,4},{5,6},{7,8}}'::int[]);
-- array_sort
SELECT array_sort('{}'::int[]);
SELECT array_sort('{1}'::int[]);
SELECT array_sort('{1,3,5,2,4,6}'::int[]);
SELECT array_sort('{1.1,3.3,5.5,2.2,4.4,6.6}'::numeric[]);
SELECT array_sort('{foo,bar,CCC,Abc,bbc}'::text[] COLLATE "C");
SELECT array_sort('{foo,bar,null,CCC,Abc,bbc}'::text[] COLLATE "C");
SELECT array_sort(ARRAY(SELECT '1 4'::int2vector UNION ALL SELECT '1 2'::int2vector));
-- array_sort with order specified
SELECT array_sort('{1.1,3.3,5.5,2.2,null,4.4,6.6}'::float8[], true);
SELECT array_sort('{1.1,3.3,5.5,2.2,null,4.4,6.6}'::float8[], false);
-- array_sort with order and nullsfirst flag specified
SELECT array_sort('{1.1,3.3,5.5,2.2,null,4.4,6.6}'::float8[], true, true);
SELECT array_sort('{1.1,3.3,5.5,2.2,null,4.4,6.6}'::float8[], true, false);
SELECT array_sort('{1.1,3.3,5.5,2.2,null,4.4,6.6}'::float8[], false, true);
SELECT array_sort('{1.1,3.3,5.5,2.2,null,4.4,6.6}'::float8[], false, false);
-- multidimensional array tests
SELECT array_sort('{{1}}'::int[]);
SELECT array_sort(ARRAY[[2,4],[2,1],[6,5]]);
SELECT array_sort('{{"1 2","3 4"}, {"1 -2","-1 4"}}'::int2vector[]);
-- no ordering operator tests
SELECT array_sort('{1}'::xid[]); -- no error because no sort is required
SELECT array_sort('{1,2,3}'::xid[]);
SELECT array_sort('{{1,2,3},{2,3,4}}'::xid[]);
-- bounds preservation tests
SELECT array_sort(a) FROM (VALUES ('[10:12][20:21]={{1,2},{10,20},{3,4}}'::int[])) v(a);
SELECT array_sort(a) FROM (VALUES ('[-1:0]={7,1}'::int[])) v(a);
SELECT array_sort(a) FROM (VALUES ('[-2:0][20:21]={{1,2},{10,20},{1,-4}}'::int[])) v(a);
SELECT array_sort(a [-1:0]) FROM (VALUES ('[-2:0][20:21]={{1,2},{10,20},{1,-4}}'::int[])) v(a);
SELECT array_sort(a [-1:0][20:20]) FROM (VALUES ('[-2:0][20:21]={{1,2},{10,20},{1,-4}}'::int[])) v(a);

View File

@@ -564,6 +564,10 @@ CREATE COLLATION case_insensitive (provider = icu, locale = '@colStrength=second
SELECT 'abc' <= 'ABC' COLLATE case_sensitive, 'abc' >= 'ABC' COLLATE case_sensitive;
SELECT 'abc' <= 'ABC' COLLATE case_insensitive, 'abc' >= 'ABC' COLLATE case_insensitive;
-- tests with array_sort
SELECT array_sort('{a,B}'::text[] COLLATE case_insensitive);
SELECT array_sort('{a,B}'::text[] COLLATE "C");
-- test language tags
CREATE COLLATION lt_insensitive (provider = icu, locale = 'en-u-ks-level1', deterministic = false);
SELECT 'aBcD' COLLATE lt_insensitive = 'AbCd' COLLATE lt_insensitive;