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,