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

Commit49d6c7d

Browse files
committed
Add SQL function array_reverse()
This function takes in input an array, and reverses the position of allits elements. This operation only affects the first dimension of thearray, like array_shuffle().The implementation structure is inspired by array_shuffle(), with asubroutine called array_reverse_n() that may come in handy in thefuture, should more functions able to reverse portions of arrays beintroduced.Bump catalog version.Author: Aleksander AlekseevReviewed-by: Ashutosh Bapat, Tom Lane, Vladlen PopolitovDiscussion:https://postgr.es/m/CAJ7c6TMpeO_ke+QGOaAx9xdJuxa7r=49-anMh3G5476e3CX1CA@mail.gmail.com
1 parent2d8bff6 commit49d6c7d

File tree

6 files changed

+171
-1
lines changed

6 files changed

+171
-1
lines changed

‎doc/src/sgml/func.sgml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20379,6 +20379,23 @@ SELECT NULLIF(value, '(none)') ...
2037920379
</para></entry>
2038020380
</row>
2038120381

20382+
<row>
20383+
<entry role="func_table_entry"><para role="func_signature">
20384+
<indexterm>
20385+
<primary>array_reverse</primary>
20386+
</indexterm>
20387+
<function>array_reverse</function> ( <type>anyarray</type> )
20388+
<returnvalue>anyarray</returnvalue>
20389+
</para>
20390+
<para>
20391+
Reverses the first dimension of the array.
20392+
</para>
20393+
<para>
20394+
<literal>array_reverse(ARRAY[[1,2],[3,4],[5,6]])</literal>
20395+
<returnvalue>{{5,6},{3,4},{1,2}}</returnvalue>
20396+
</para></entry>
20397+
</row>
20398+
2038220399
<row>
2038320400
<entry role="func_table_entry"><para role="func_signature">
2038420401
<indexterm>

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

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1685,3 +1685,115 @@ array_sample(PG_FUNCTION_ARGS)
16851685

16861686
PG_RETURN_ARRAYTYPE_P(result);
16871687
}
1688+
1689+
1690+
/*
1691+
* array_reverse_n
1692+
*Return a copy of array with reversed items.
1693+
*
1694+
* NOTE: it would be cleaner to look up the elmlen/elmbval/elmalign info
1695+
* from the system catalogs, given only the elmtyp. However, the caller is
1696+
* in a better position to cache this info across multiple calls.
1697+
*/
1698+
staticArrayType*
1699+
array_reverse_n(ArrayType*array,Oidelmtyp,TypeCacheEntry*typentry)
1700+
{
1701+
ArrayType*result;
1702+
intndim,
1703+
*dims,
1704+
*lbs,
1705+
nelm,
1706+
nitem,
1707+
rdims[MAXDIM],
1708+
rlbs[MAXDIM];
1709+
int16elmlen;
1710+
boolelmbyval;
1711+
charelmalign;
1712+
Datum*elms,
1713+
*ielms;
1714+
bool*nuls,
1715+
*inuls;
1716+
1717+
ndim=ARR_NDIM(array);
1718+
dims=ARR_DIMS(array);
1719+
lbs=ARR_LBOUND(array);
1720+
1721+
elmlen=typentry->typlen;
1722+
elmbyval=typentry->typbyval;
1723+
elmalign=typentry->typalign;
1724+
1725+
deconstruct_array(array,elmtyp,elmlen,elmbyval,elmalign,
1726+
&elms,&nuls,&nelm);
1727+
1728+
nitem=dims[0];/* total number of items */
1729+
nelm /=nitem;/* number of elements per item */
1730+
1731+
/* Reverse the array */
1732+
ielms=elms;
1733+
inuls=nuls;
1734+
for (inti=0;i<nitem /2;i++)
1735+
{
1736+
intj= (nitem-i-1)*nelm;
1737+
Datum*jelms=elms+j;
1738+
bool*jnuls=nuls+j;
1739+
1740+
/* Swap i'th and j'th items; advance ielms/inuls to next item */
1741+
for (intk=0;k<nelm;k++)
1742+
{
1743+
Datumelm=*ielms;
1744+
boolnul=*inuls;
1745+
1746+
*ielms++=*jelms;
1747+
*inuls++=*jnuls;
1748+
*jelms++=elm;
1749+
*jnuls++=nul;
1750+
}
1751+
}
1752+
1753+
/* Set up dimensions of the result */
1754+
memcpy(rdims,dims,ndim*sizeof(int));
1755+
memcpy(rlbs,lbs,ndim*sizeof(int));
1756+
rdims[0]=nitem;
1757+
1758+
result=construct_md_array(elms,nuls,ndim,rdims,rlbs,
1759+
elmtyp,elmlen,elmbyval,elmalign);
1760+
1761+
pfree(elms);
1762+
pfree(nuls);
1763+
1764+
returnresult;
1765+
}
1766+
1767+
/*
1768+
* array_reverse
1769+
*
1770+
* Returns an array with the same dimensions as the input array, with its
1771+
* first-dimension elements in reverse order.
1772+
*/
1773+
Datum
1774+
array_reverse(PG_FUNCTION_ARGS)
1775+
{
1776+
ArrayType*array=PG_GETARG_ARRAYTYPE_P(0);
1777+
ArrayType*result;
1778+
Oidelmtyp;
1779+
TypeCacheEntry*typentry;
1780+
1781+
/*
1782+
* There is no point in reversing empty arrays or arrays with less than
1783+
* two items.
1784+
*/
1785+
if (ARR_NDIM(array)<1||ARR_DIMS(array)[0]<2)
1786+
PG_RETURN_ARRAYTYPE_P(array);
1787+
1788+
elmtyp=ARR_ELEMTYPE(array);
1789+
typentry= (TypeCacheEntry*)fcinfo->flinfo->fn_extra;
1790+
if (typentry==NULL||typentry->type_id!=elmtyp)
1791+
{
1792+
typentry=lookup_type_cache(elmtyp,0);
1793+
fcinfo->flinfo->fn_extra= (void*)typentry;
1794+
}
1795+
1796+
result=array_reverse_n(array,elmtyp,typentry);
1797+
1798+
PG_RETURN_ARRAYTYPE_P(result);
1799+
}

‎src/include/catalog/catversion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,6 @@
5757
*/
5858

5959
/*yyyymmddN */
60-
#defineCATALOG_VERSION_NO202410311
60+
#defineCATALOG_VERSION_NO202411011
6161

6262
#endif

‎src/include/catalog/pg_proc.dat

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1741,6 +1741,9 @@
17411741
{ oid => '6216', descr => 'take samples from array',
17421742
proname => 'array_sample', provolatile => 'v', prorettype => 'anyarray',
17431743
proargtypes => 'anyarray int4', prosrc => 'array_sample' },
1744+
{ oid => '8686', descr => 'reverse array',
1745+
proname => 'array_reverse', prorettype => 'anyarray',
1746+
proargtypes => 'anyarray', prosrc => 'array_reverse' },
17441747
{ oid => '3816', descr => 'array typanalyze',
17451748
proname => 'array_typanalyze', provolatile => 's', prorettype => 'bool',
17461749
proargtypes => 'internal', prosrc => 'array_typanalyze' },

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2703,3 +2703,34 @@ SELECT array_sample('{1,2,3,4,5,6}'::int[], -1); -- fail
27032703
ERROR: sample size must be between 0 and 6
27042704
SELECT array_sample('{1,2,3,4,5,6}'::int[], 7); --fail
27052705
ERROR: sample size must be between 0 and 6
2706+
-- array_reverse
2707+
SELECT array_reverse('{}'::int[]);
2708+
array_reverse
2709+
---------------
2710+
{}
2711+
(1 row)
2712+
2713+
SELECT array_reverse('{1}'::int[]);
2714+
array_reverse
2715+
---------------
2716+
{1}
2717+
(1 row)
2718+
2719+
SELECT array_reverse('{1,2}'::int[]);
2720+
array_reverse
2721+
---------------
2722+
{2,1}
2723+
(1 row)
2724+
2725+
SELECT array_reverse('{1,2,3,NULL,4,5,6}'::int[]);
2726+
array_reverse
2727+
--------------------
2728+
{6,5,4,NULL,3,2,1}
2729+
(1 row)
2730+
2731+
SELECT array_reverse('{{1,2},{3,4},{5,6},{7,8}}'::int[]);
2732+
array_reverse
2733+
---------------------------
2734+
{{7,8},{5,6},{3,4},{1,2}}
2735+
(1 row)
2736+

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -827,3 +827,10 @@ SELECT array_dims(array_sample('[-1:2][2:3]={{1,2},{3,NULL},{5,6},{7,8}}'::int[]
827827
SELECT array_dims(array_sample('{{{1,2},{3,NULL}},{{5,6},{7,8}},{{9,10},{11,12}}}'::int[],2));
828828
SELECT array_sample('{1,2,3,4,5,6}'::int[],-1);-- fail
829829
SELECT array_sample('{1,2,3,4,5,6}'::int[],7);--fail
830+
831+
-- array_reverse
832+
SELECT array_reverse('{}'::int[]);
833+
SELECT array_reverse('{1}'::int[]);
834+
SELECT array_reverse('{1,2}'::int[]);
835+
SELECT array_reverse('{1,2,3,NULL,4,5,6}'::int[]);
836+
SELECT array_reverse('{{1,2},{3,4},{5,6},{7,8}}'::int[]);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp