88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.124 2005/11/17 22:14:52 tgl Exp $
11+ * $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.125 2005/11/19 19:44:55 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -2965,10 +2965,9 @@ array_eq(PG_FUNCTION_ARGS)
29652965 int ndims2 = ARR_NDIM (array2 );
29662966 int * dims1 = ARR_DIMS (array1 );
29672967 int * dims2 = ARR_DIMS (array2 );
2968- int nitems1 = ArrayGetNItems (ndims1 , dims1 );
2969- int nitems2 = ArrayGetNItems (ndims2 , dims2 );
29702968 Oid element_type = ARR_ELEMTYPE (array1 );
29712969 bool result = true;
2970+ int nitems ;
29722971 TypeCacheEntry * typentry ;
29732972 int typlen ;
29742973 bool typbyval ;
@@ -2986,8 +2985,9 @@ array_eq(PG_FUNCTION_ARGS)
29862985 (errcode (ERRCODE_DATATYPE_MISMATCH ),
29872986 errmsg ("cannot compare arrays of different element types" )));
29882987
2989- /* fast path if the arrays do not have the same number of elements */
2990- if (nitems1 != nitems2 )
2988+ /* fast path if the arrays do not have the same dimensionality */
2989+ if (ndims1 != ndims2 ||
2990+ memcmp (dims1 , dims2 , 2 * ndims1 * sizeof (int )) != 0 )
29912991 result = false;
29922992 else
29932993 {
@@ -3021,13 +3021,14 @@ array_eq(PG_FUNCTION_ARGS)
30213021 NULL , NULL );
30223022
30233023 /* Loop over source data */
3024+ nitems = ArrayGetNItems (ndims1 , dims1 );
30243025 ptr1 = ARR_DATA_PTR (array1 );
30253026 ptr2 = ARR_DATA_PTR (array2 );
30263027 bitmap1 = ARR_NULLBITMAP (array1 );
30273028 bitmap2 = ARR_NULLBITMAP (array2 );
30283029 bitmask = 1 ; /* use same bitmask for both arrays */
30293030
3030- for (i = 0 ; i < nitems1 ; i ++ )
3031+ for (i = 0 ; i < nitems ; i ++ )
30313032 {
30323033 Datum elt1 ;
30333034 Datum elt2 ;
@@ -3221,13 +3222,13 @@ array_cmp(FunctionCallInfo fcinfo)
32213222 NULL , NULL );
32223223
32233224 /* Loop over source data */
3225+ min_nitems = Min (nitems1 , nitems2 );
32243226 ptr1 = ARR_DATA_PTR (array1 );
32253227 ptr2 = ARR_DATA_PTR (array2 );
32263228 bitmap1 = ARR_NULLBITMAP (array1 );
32273229 bitmap2 = ARR_NULLBITMAP (array2 );
32283230 bitmask = 1 ; /* use same bitmask for both arrays */
32293231
3230- min_nitems = Min (nitems1 , nitems2 );
32313232 for (i = 0 ; i < min_nitems ; i ++ )
32323233 {
32333234 Datum elt1 ;
@@ -3317,8 +3318,31 @@ array_cmp(FunctionCallInfo fcinfo)
33173318 }
33183319 }
33193320
3320- if ((result == 0 ) && (nitems1 != nitems2 ))
3321- result = (nitems1 < nitems2 ) ? -1 : 1 ;
3321+ /*
3322+ * If arrays contain same data (up to end of shorter one), apply additional
3323+ * rules to sort by dimensionality. The relative significance of the
3324+ * different bits of information is historical; mainly we just care that
3325+ * we don't say "equal" for arrays of different dimensionality.
3326+ */
3327+ if (result == 0 )
3328+ {
3329+ if (nitems1 != nitems2 )
3330+ result = (nitems1 < nitems2 ) ? -1 : 1 ;
3331+ else if (ndims1 != ndims2 )
3332+ result = (ndims1 < ndims2 ) ? -1 : 1 ;
3333+ else
3334+ {
3335+ /* this relies on LB array immediately following DIMS array */
3336+ for (i = 0 ; i < ndims1 * 2 ; i ++ )
3337+ {
3338+ if (dims1 [i ] != dims2 [i ])
3339+ {
3340+ result = (dims1 [i ] < dims2 [i ]) ? -1 : 1 ;
3341+ break ;
3342+ }
3343+ }
3344+ }
3345+ }
33223346
33233347 /* Avoid leaking memory when handed toasted input. */
33243348 PG_FREE_IF_COPY (array1 , 0 );
0 commit comments