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)
29652965int ndims2 = ARR_NDIM (array2 );
29662966int * dims1 = ARR_DIMS (array1 );
29672967int * dims2 = ARR_DIMS (array2 );
2968- int nitems1 = ArrayGetNItems (ndims1 ,dims1 );
2969- int nitems2 = ArrayGetNItems (ndims2 ,dims2 );
29702968Oid element_type = ARR_ELEMTYPE (array1 );
29712969bool result = true;
2970+ int nitems ;
29722971TypeCacheEntry * typentry ;
29732972int typlen ;
29742973bool typbyval ;
@@ -2986,8 +2985,9 @@ array_eq(PG_FUNCTION_ARGS)
29862985(errcode (ERRCODE_DATATYPE_MISMATCH ),
29872986errmsg ("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 )
29912991result = false;
29922992else
29932993{
@@ -3021,13 +3021,14 @@ array_eq(PG_FUNCTION_ARGS)
30213021NULL ,NULL );
30223022
30233023/* Loop over source data */
3024+ nitems = ArrayGetNItems (ndims1 ,dims1 );
30243025ptr1 = ARR_DATA_PTR (array1 );
30253026ptr2 = ARR_DATA_PTR (array2 );
30263027bitmap1 = ARR_NULLBITMAP (array1 );
30273028bitmap2 = ARR_NULLBITMAP (array2 );
30283029bitmask = 1 ;/* use same bitmask for both arrays */
30293030
3030- for (i = 0 ;i < nitems1 ;i ++ )
3031+ for (i = 0 ;i < nitems ;i ++ )
30313032{
30323033Datum elt1 ;
30333034Datum elt2 ;
@@ -3221,13 +3222,13 @@ array_cmp(FunctionCallInfo fcinfo)
32213222NULL ,NULL );
32223223
32233224/* Loop over source data */
3225+ min_nitems = Min (nitems1 ,nitems2 );
32243226ptr1 = ARR_DATA_PTR (array1 );
32253227ptr2 = ARR_DATA_PTR (array2 );
32263228bitmap1 = ARR_NULLBITMAP (array1 );
32273229bitmap2 = ARR_NULLBITMAP (array2 );
32283230bitmask = 1 ;/* use same bitmask for both arrays */
32293231
3230- min_nitems = Min (nitems1 ,nitems2 );
32313232for (i = 0 ;i < min_nitems ;i ++ )
32323233{
32333234Datum 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. */
33243348PG_FREE_IF_COPY (array1 ,0 );