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,
---------------------------(end of broadcast)---------------------------
TIP 4: Don't 'kill -9' the postmaster

Reply via email to