mirror of
https://github.com/postgres/postgres.git
synced 2025-04-27 22:56:53 +03:00
Change array comparison rules to consider dimensionality information,
not only the array contents, before claiming two arrays are equal. Per recent discussion.
This commit is contained in:
parent
daea4d8eae
commit
659f681638
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.294 2005/11/19 01:50:08 tgl Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.295 2005/11/19 19:44:54 tgl Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -7403,6 +7403,19 @@ SELECT NULLIF(value, '(none)') ...
|
|||||||
</tgroup>
|
</tgroup>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Array comparisons compare the array contents element-by-element,
|
||||||
|
using the default btree comparison function for the element data type.
|
||||||
|
In multidimensional arrays the elements are visited in row-major order
|
||||||
|
(last subscript varies most rapidly).
|
||||||
|
If the contents of two arrays are equal but the dimensionality is
|
||||||
|
different, the first difference in the dimensionality information
|
||||||
|
determines the sort order. (This is a change from versions of
|
||||||
|
<productname>PostgreSQL</> prior to 8.2: older versions would claim
|
||||||
|
that two arrays with the same contents were equal, even if the
|
||||||
|
number of dimensions or subscript ranges were different.)
|
||||||
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
See <xref linkend="arrays"> for more details about array operator
|
See <xref linkend="arrays"> for more details about array operator
|
||||||
behavior.
|
behavior.
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.124 2005/11/17 22:14:52 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.125 2005/11/19 19:44:55 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -2965,10 +2965,9 @@ array_eq(PG_FUNCTION_ARGS)
|
|||||||
int ndims2 = ARR_NDIM(array2);
|
int ndims2 = ARR_NDIM(array2);
|
||||||
int *dims1 = ARR_DIMS(array1);
|
int *dims1 = ARR_DIMS(array1);
|
||||||
int *dims2 = ARR_DIMS(array2);
|
int *dims2 = ARR_DIMS(array2);
|
||||||
int nitems1 = ArrayGetNItems(ndims1, dims1);
|
|
||||||
int nitems2 = ArrayGetNItems(ndims2, dims2);
|
|
||||||
Oid element_type = ARR_ELEMTYPE(array1);
|
Oid element_type = ARR_ELEMTYPE(array1);
|
||||||
bool result = true;
|
bool result = true;
|
||||||
|
int nitems;
|
||||||
TypeCacheEntry *typentry;
|
TypeCacheEntry *typentry;
|
||||||
int typlen;
|
int typlen;
|
||||||
bool typbyval;
|
bool typbyval;
|
||||||
@ -2986,8 +2985,9 @@ array_eq(PG_FUNCTION_ARGS)
|
|||||||
(errcode(ERRCODE_DATATYPE_MISMATCH),
|
(errcode(ERRCODE_DATATYPE_MISMATCH),
|
||||||
errmsg("cannot compare arrays of different element types")));
|
errmsg("cannot compare arrays of different element types")));
|
||||||
|
|
||||||
/* fast path if the arrays do not have the same number of elements */
|
/* fast path if the arrays do not have the same dimensionality */
|
||||||
if (nitems1 != nitems2)
|
if (ndims1 != ndims2 ||
|
||||||
|
memcmp(dims1, dims2, 2 * ndims1 * sizeof(int)) != 0)
|
||||||
result = false;
|
result = false;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -3021,13 +3021,14 @@ array_eq(PG_FUNCTION_ARGS)
|
|||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
|
|
||||||
/* Loop over source data */
|
/* Loop over source data */
|
||||||
|
nitems = ArrayGetNItems(ndims1, dims1);
|
||||||
ptr1 = ARR_DATA_PTR(array1);
|
ptr1 = ARR_DATA_PTR(array1);
|
||||||
ptr2 = ARR_DATA_PTR(array2);
|
ptr2 = ARR_DATA_PTR(array2);
|
||||||
bitmap1 = ARR_NULLBITMAP(array1);
|
bitmap1 = ARR_NULLBITMAP(array1);
|
||||||
bitmap2 = ARR_NULLBITMAP(array2);
|
bitmap2 = ARR_NULLBITMAP(array2);
|
||||||
bitmask = 1; /* use same bitmask for both arrays */
|
bitmask = 1; /* use same bitmask for both arrays */
|
||||||
|
|
||||||
for (i = 0; i < nitems1; i++)
|
for (i = 0; i < nitems; i++)
|
||||||
{
|
{
|
||||||
Datum elt1;
|
Datum elt1;
|
||||||
Datum elt2;
|
Datum elt2;
|
||||||
@ -3221,13 +3222,13 @@ array_cmp(FunctionCallInfo fcinfo)
|
|||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
|
|
||||||
/* Loop over source data */
|
/* Loop over source data */
|
||||||
|
min_nitems = Min(nitems1, nitems2);
|
||||||
ptr1 = ARR_DATA_PTR(array1);
|
ptr1 = ARR_DATA_PTR(array1);
|
||||||
ptr2 = ARR_DATA_PTR(array2);
|
ptr2 = ARR_DATA_PTR(array2);
|
||||||
bitmap1 = ARR_NULLBITMAP(array1);
|
bitmap1 = ARR_NULLBITMAP(array1);
|
||||||
bitmap2 = ARR_NULLBITMAP(array2);
|
bitmap2 = ARR_NULLBITMAP(array2);
|
||||||
bitmask = 1; /* use same bitmask for both arrays */
|
bitmask = 1; /* use same bitmask for both arrays */
|
||||||
|
|
||||||
min_nitems = Min(nitems1, nitems2);
|
|
||||||
for (i = 0; i < min_nitems; i++)
|
for (i = 0; i < min_nitems; i++)
|
||||||
{
|
{
|
||||||
Datum elt1;
|
Datum elt1;
|
||||||
@ -3317,8 +3318,31 @@ array_cmp(FunctionCallInfo fcinfo)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((result == 0) && (nitems1 != nitems2))
|
/*
|
||||||
|
* If arrays contain same data (up to end of shorter one), apply additional
|
||||||
|
* rules to sort by dimensionality. The relative significance of the
|
||||||
|
* different bits of information is historical; mainly we just care that
|
||||||
|
* we don't say "equal" for arrays of different dimensionality.
|
||||||
|
*/
|
||||||
|
if (result == 0)
|
||||||
|
{
|
||||||
|
if (nitems1 != nitems2)
|
||||||
result = (nitems1 < nitems2) ? -1 : 1;
|
result = (nitems1 < nitems2) ? -1 : 1;
|
||||||
|
else if (ndims1 != ndims2)
|
||||||
|
result = (ndims1 < ndims2) ? -1 : 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* this relies on LB array immediately following DIMS array */
|
||||||
|
for (i = 0; i < ndims1 * 2; i++)
|
||||||
|
{
|
||||||
|
if (dims1[i] != dims2[i])
|
||||||
|
{
|
||||||
|
result = (dims1[i] < dims2[i]) ? -1 : 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Avoid leaking memory when handed toasted input. */
|
/* Avoid leaking memory when handed toasted input. */
|
||||||
PG_FREE_IF_COPY(array1, 0);
|
PG_FREE_IF_COPY(array1, 0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user