8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -2965,10 +2965,9 @@ array_eq(PG_FUNCTION_ARGS)
2965
2965
int ndims2 = ARR_NDIM (array2 );
2966
2966
int * dims1 = ARR_DIMS (array1 );
2967
2967
int * dims2 = ARR_DIMS (array2 );
2968
- int nitems1 = ArrayGetNItems (ndims1 , dims1 );
2969
- int nitems2 = ArrayGetNItems (ndims2 , dims2 );
2970
2968
Oid element_type = ARR_ELEMTYPE (array1 );
2971
2969
bool result = true;
2970
+ int nitems ;
2972
2971
TypeCacheEntry * typentry ;
2973
2972
int typlen ;
2974
2973
bool typbyval ;
@@ -2986,8 +2985,9 @@ array_eq(PG_FUNCTION_ARGS)
2986
2985
(errcode (ERRCODE_DATATYPE_MISMATCH ),
2987
2986
errmsg ("cannot compare arrays of different element types" )));
2988
2987
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 )
2991
2991
result = false;
2992
2992
else
2993
2993
{
@@ -3021,13 +3021,14 @@ array_eq(PG_FUNCTION_ARGS)
3021
3021
NULL , NULL );
3022
3022
3023
3023
/* Loop over source data */
3024
+ nitems = ArrayGetNItems (ndims1 , dims1 );
3024
3025
ptr1 = ARR_DATA_PTR (array1 );
3025
3026
ptr2 = ARR_DATA_PTR (array2 );
3026
3027
bitmap1 = ARR_NULLBITMAP (array1 );
3027
3028
bitmap2 = ARR_NULLBITMAP (array2 );
3028
3029
bitmask = 1 ; /* use same bitmask for both arrays */
3029
3030
3030
- for (i = 0 ; i < nitems1 ; i ++ )
3031
+ for (i = 0 ; i < nitems ; i ++ )
3031
3032
{
3032
3033
Datum elt1 ;
3033
3034
Datum elt2 ;
@@ -3221,13 +3222,13 @@ array_cmp(FunctionCallInfo fcinfo)
3221
3222
NULL , NULL );
3222
3223
3223
3224
/* Loop over source data */
3225
+ min_nitems = Min (nitems1 , nitems2 );
3224
3226
ptr1 = ARR_DATA_PTR (array1 );
3225
3227
ptr2 = ARR_DATA_PTR (array2 );
3226
3228
bitmap1 = ARR_NULLBITMAP (array1 );
3227
3229
bitmap2 = ARR_NULLBITMAP (array2 );
3228
3230
bitmask = 1 ; /* use same bitmask for both arrays */
3229
3231
3230
- min_nitems = Min (nitems1 , nitems2 );
3231
3232
for (i = 0 ; i < min_nitems ; i ++ )
3232
3233
{
3233
3234
Datum elt1 ;
@@ -3317,8 +3318,31 @@ array_cmp(FunctionCallInfo fcinfo)
3317
3318
}
3318
3319
}
3319
3320
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
+ }
3322
3346
3323
3347
/* Avoid leaking memory when handed toasted input. */
3324
3348
PG_FREE_IF_COPY (array1 , 0 );
0 commit comments