<!--
-$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
-->
</tgroup>
</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>
See <xref linkend="arrays"> for more details about array operator
behavior.
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
int ndims2 = ARR_NDIM(array2);
int *dims1 = ARR_DIMS(array1);
int *dims2 = ARR_DIMS(array2);
- int nitems1 = ArrayGetNItems(ndims1, dims1);
- int nitems2 = ArrayGetNItems(ndims2, dims2);
Oid element_type = ARR_ELEMTYPE(array1);
bool result = true;
+ int nitems;
TypeCacheEntry *typentry;
int typlen;
bool typbyval;
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("cannot compare arrays of different element types")));
- /* fast path if the arrays do not have the same number of elements */
- if (nitems1 != nitems2)
+ /* fast path if the arrays do not have the same dimensionality */
+ if (ndims1 != ndims2 ||
+ memcmp(dims1, dims2, 2 * ndims1 * sizeof(int)) != 0)
result = false;
else
{
NULL, NULL);
/* Loop over source data */
+ nitems = ArrayGetNItems(ndims1, dims1);
ptr1 = ARR_DATA_PTR(array1);
ptr2 = ARR_DATA_PTR(array2);
bitmap1 = ARR_NULLBITMAP(array1);
bitmap2 = ARR_NULLBITMAP(array2);
bitmask = 1; /* use same bitmask for both arrays */
- for (i = 0; i < nitems1; i++)
+ for (i = 0; i < nitems; i++)
{
Datum elt1;
Datum elt2;
NULL, NULL);
/* Loop over source data */
+ min_nitems = Min(nitems1, nitems2);
ptr1 = ARR_DATA_PTR(array1);
ptr2 = ARR_DATA_PTR(array2);
bitmap1 = ARR_NULLBITMAP(array1);
bitmap2 = ARR_NULLBITMAP(array2);
bitmask = 1; /* use same bitmask for both arrays */
- min_nitems = Min(nitems1, nitems2);
for (i = 0; i < min_nitems; i++)
{
Datum elt1;
}
}
- if ((result == 0) && (nitems1 != nitems2))
- result = (nitems1 < nitems2) ? -1 : 1;
+ /*
+ * 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;
+ 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. */
PG_FREE_IF_COPY(array1, 0);