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:
@@ -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)
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user