Thread: Int2 vector to array equality

Int2 vector to array equality

From
Andreas Pflug
Date:
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,

Re: Int2 vector to array equality

From
Tom Lane
Date:
Andreas Pflug <pgadmin@pse-consulting.de> writes:
> The attached patch adds an equality operator
>     bool int2array_int2vector_eq(int2[], int2vector)

This seems like a remarkably specialized kluge ... gotta be a
better way ...

            regards, tom lane

Re: Int2 vector to array equality

From
Andreas Pflug
Date:
Tom Lane wrote:

>Andreas Pflug <pgadmin@pse-consulting.de> writes:
>
>
>>The attached patch adds an equality operator
>>    bool int2array_int2vector_eq(int2[], int2vector)
>>
>>
>
>This seems like a remarkably specialized kluge ... gotta be a
>better way ...
>
>

How? This could be coded to support any element type, but we only have
int2vector anyway.

Regards,
Andreas