* array_eq : * compares two arrays for equality * result : * returns true if the arrays are equal, false otherwise. * * Note: we do not use array_cmp here, since equality may be meaningful in * datatypes that don't have a total ordering (and hence no btree support). */
| 3702 | * datatypes that don't have a total ordering (and hence no btree support). |
| 3703 | */ |
| 3704 | Datum |
| 3705 | array_eq(PG_FUNCTION_ARGS) |
| 3706 | { |
| 3707 | LOCAL_FCINFO(locfcinfo, 2); |
| 3708 | AnyArrayType *array1 = PG_GETARG_ANY_ARRAY_P(0); |
| 3709 | AnyArrayType *array2 = PG_GETARG_ANY_ARRAY_P(1); |
| 3710 | Oid collation = PG_GET_COLLATION(); |
| 3711 | int ndims1 = AARR_NDIM(array1); |
| 3712 | int ndims2 = AARR_NDIM(array2); |
| 3713 | int *dims1 = AARR_DIMS(array1); |
| 3714 | int *dims2 = AARR_DIMS(array2); |
| 3715 | int *lbs1 = AARR_LBOUND(array1); |
| 3716 | int *lbs2 = AARR_LBOUND(array2); |
| 3717 | Oid element_type = AARR_ELEMTYPE(array1); |
| 3718 | bool result = true; |
| 3719 | int nitems; |
| 3720 | TypeCacheEntry *typentry; |
| 3721 | int typlen; |
| 3722 | bool typbyval; |
| 3723 | char typalign; |
| 3724 | array_iter it1; |
| 3725 | array_iter it2; |
| 3726 | int i; |
| 3727 | |
| 3728 | if (element_type != AARR_ELEMTYPE(array2)) |
| 3729 | ereport(ERROR, |
| 3730 | (errcode(ERRCODE_DATATYPE_MISMATCH), |
| 3731 | errmsg("cannot compare arrays of different element types"))); |
| 3732 | |
| 3733 | /* fast path if the arrays do not have the same dimensionality */ |
| 3734 | if (ndims1 != ndims2 || |
| 3735 | memcmp(dims1, dims2, ndims1 * sizeof(int)) != 0 || |
| 3736 | memcmp(lbs1, lbs2, ndims1 * sizeof(int)) != 0) |
| 3737 | result = false; |
| 3738 | else |
| 3739 | { |
| 3740 | /* |
| 3741 | * We arrange to look up the equality function only once per series of |
| 3742 | * calls, assuming the element type doesn't change underneath us. The |
| 3743 | * typcache is used so that we have no memory leakage when being used |
| 3744 | * as an index support function. |
| 3745 | */ |
| 3746 | typentry = (TypeCacheEntry *) fcinfo->flinfo->fn_extra; |
| 3747 | if (typentry == NULL || |
| 3748 | typentry->type_id != element_type) |
| 3749 | { |
| 3750 | typentry = lookup_type_cache(element_type, |
| 3751 | TYPECACHE_EQ_OPR_FINFO); |
| 3752 | if (!OidIsValid(typentry->eq_opr_finfo.fn_oid)) |
| 3753 | ereport(ERROR, |
| 3754 | (errcode(ERRCODE_UNDEFINED_FUNCTION), |
| 3755 | errmsg("could not identify an equality operator for type %s", |
| 3756 | format_type_be(element_type)))); |
| 3757 | fcinfo->flinfo->fn_extra = (void *) typentry; |
| 3758 | } |
| 3759 | typlen = typentry->typlen; |
| 3760 | typbyval = typentry->typbyval; |
| 3761 | typalign = typentry->typalign; |
no test coverage detected