Int2 vector to array equality - Mailing list pgsql-patches
From | Andreas Pflug |
---|---|
Subject | Int2 vector to array equality |
Date | |
Msg-id | 40C3A932.5080108@pse-consulting.de Whole thread Raw |
Responses |
Re: Int2 vector to array equality
|
List | pgsql-patches |
While trying to pg_constraint JOIN pg_index ON indrelid=conrelid AND conkey=indkey I noticed (once again) that these columns have different types (although describing the same thing), and there's no equality operator for them. The attached patch adds an equality operator bool int2array_int2vector_eq(int2[], int2vector) to enable this join. Regards, Andreas Index: backend/utils/adt/arrayfuncs.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/utils/adt/arrayfuncs.c,v retrieving revision 1.103 diff -u -r1.103 arrayfuncs.c --- backend/utils/adt/arrayfuncs.c 6 Jun 2004 00:41:27 -0000 1.103 +++ backend/utils/adt/arrayfuncs.c 6 Jun 2004 23:14:44 -0000 @@ -2447,6 +2447,77 @@ } + +/*----------------------------------------------------------------------------- + * int2array_int2vector_eq : + * compares an int2[] and an int2vector for equality + * result : + * returns true if array and vector 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). + *----------------------------------------------------------------------------- + */ +Datum +int2array_int2vector_eq(PG_FUNCTION_ARGS) +{ + ArrayType *array = PG_GETARG_ARRAYTYPE_P(0); + int16 *vec = (int16 *) PG_GETARG_POINTER(1); + char *p = (char *) ARR_DATA_PTR(array); + int ndims = ARR_NDIM(array); + int *dims = ARR_DIMS(array); + int nitems = ArrayGetNItems(ndims, dims); + Oid element_type = ARR_ELEMTYPE(array); + bool result = true; + TypeCacheEntry *typentry; + int typlen; + bool typbyval; + char typalign; + int i; + + typentry = (TypeCacheEntry *) fcinfo->flinfo->fn_extra; + if (typentry == NULL || + typentry->type_id != element_type) + { + typentry = lookup_type_cache(element_type, + TYPECACHE_EQ_OPR_FINFO); + if (!OidIsValid(typentry->eq_opr_finfo.fn_oid)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_FUNCTION), + errmsg("could not identify an equality operator for type %s", + format_type_be(element_type)))); + fcinfo->flinfo->fn_extra = (void *) typentry; + } + typlen = typentry->typlen; + typbyval = typentry->typbyval; + typalign = typentry->typalign; + + /* Loop over source data */ + for (i = 0; i < nitems ; i++, vec++) + { + Datum elt; + bool oprresult; + + elt = fetch_att(p, typbyval, typlen); + + p = att_addlength(p, typlen, PointerGetDatum(p)); + p = (char*) att_align(p, typalign); + + oprresult = (DatumGetInt16(elt) == *vec); + if (!oprresult) + { + result = false; + break; + } + } + + /* Avoid leaking memory when handed toasted input. */ + PG_FREE_IF_COPY(array, 0); + + PG_RETURN_BOOL(result); +} + + /*----------------------------------------------------------------------------- * array-array bool operators: * Given two arrays, iterate comparison operators Index: include/catalog/pg_proc.h =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/include/catalog/pg_proc.h,v retrieving revision 1.334 diff -u -r1.334 pg_proc.h --- include/catalog/pg_proc.h 2 Jun 2004 21:29:29 -0000 1.334 +++ include/catalog/pg_proc.h 6 Jun 2004 23:15:00 -0000 @@ -3588,6 +3588,9 @@ DATA(insert OID = 2243 ( bit_or PGNSP PGUID 12 t f f f i 1 1560 "1560" _null_ aggregate_dummy- _null_)); DESCR("bitwise-or bit aggregate"); +DATA(insert OID = 2546( int2array_int2vector_eq PGNSP PGUID 12 f f t f i 2 16 "1005 22" _null_ int2array_int2vector_eq- _null_ )); +DESCR("int2array int2vector equal"); + /* * Symbolic values for provolatile column: these indicate whether the result * of a function is dependent *only* on the values of its explicit arguments,
pgsql-patches by date: