aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/arrayfuncs.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2003-08-15 00:22:26 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2003-08-15 00:22:26 +0000
commit432ca9116bc51f6cfe6e88be33dbe6cb078cda9d (patch)
tree0c4b81a5a80bf29034ea1eb4b5e03eac15531383 /src/backend/utils/adt/arrayfuncs.c
parent43bb02863f870f2667ab5ae84c0fa5bbd2c8150f (diff)
downloadpostgresql-432ca9116bc51f6cfe6e88be33dbe6cb078cda9d.tar.gz
postgresql-432ca9116bc51f6cfe6e88be33dbe6cb078cda9d.zip
Rewrite array_cmp to not depend on deconstruct_array. Should be a little
faster, but more importantly does not leak memory. Still needs more work though, per my recent note to pgsql-hackers.
Diffstat (limited to 'src/backend/utils/adt/arrayfuncs.c')
-rw-r--r--src/backend/utils/adt/arrayfuncs.c83
1 files changed, 46 insertions, 37 deletions
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index df8265d9995..37504718ad5 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.97 2003/08/08 21:42:04 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.98 2003/08/15 00:22:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -2510,18 +2510,21 @@ array_cmp(FunctionCallInfo fcinfo)
{
ArrayType *array1 = PG_GETARG_ARRAYTYPE_P(0);
ArrayType *array2 = PG_GETARG_ARRAYTYPE_P(1);
+ char *p1 = (char *) ARR_DATA_PTR(array1);
+ char *p2 = (char *) ARR_DATA_PTR(array2);
+ int ndims1 = ARR_NDIM(array1);
+ int ndims2 = ARR_NDIM(array2);
+ int *dims1 = ARR_DIMS(array1);
+ int *dims2 = ARR_DIMS(array2);
+ int nitems1 = ArrayGetNItems(ndims1, dims1);
+ int nitems2 = ArrayGetNItems(ndims2, dims2);
+ Oid element_type = ARR_ELEMTYPE(array1);
FmgrInfo *ac_fmgr_info = fcinfo->flinfo;
- Datum opresult;
int result = 0;
- Oid element_type = InvalidOid;
int typlen;
bool typbyval;
char typalign;
- Datum *dvalues1;
- int nelems1;
- Datum *dvalues2;
- int nelems2;
- int min_nelems;
+ int min_nitems;
int i;
typedef struct
{
@@ -2534,7 +2537,6 @@ array_cmp(FunctionCallInfo fcinfo)
} ac_extra;
ac_extra *my_extra;
- element_type = ARR_ELEMTYPE(array1);
if (element_type != ARR_ELEMTYPE(array2))
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
@@ -2573,42 +2575,49 @@ array_cmp(FunctionCallInfo fcinfo)
typbyval = my_extra->typbyval;
typalign = my_extra->typalign;
- /* extract a C array of arg array datums */
- deconstruct_array(array1, element_type, typlen, typbyval, typalign,
- &dvalues1, &nelems1);
+ /* Loop over source data */
+ min_nitems = Min(nitems1, nitems2);
+ for (i = 0; i < min_nitems; i++)
+ {
+ Datum elt1;
+ Datum elt2;
+ Datum opresult;
+
+ /* Get element pair */
+ elt1 = fetch_att(p1, typbyval, typlen);
+ elt2 = fetch_att(p2, typbyval, typlen);
- deconstruct_array(array2, element_type, typlen, typbyval, typalign,
- &dvalues2, &nelems2);
+ p1 = att_addlength(p1, typlen, PointerGetDatum(p1));
+ p1 = (char *) att_align(p1, typalign);
+
+ p2 = att_addlength(p2, typlen, PointerGetDatum(p2));
+ p2 = (char *) att_align(p2, typalign);
+
+ /* Compare the pair of elements */
- min_nelems = Min(nelems1, nelems2);
- for (i = 0; i < min_nelems; i++)
- {
/* are they equal */
- opresult = FunctionCall2(&my_extra->eqproc,
- dvalues1[i], dvalues2[i]);
+ opresult = FunctionCall2(&my_extra->eqproc, elt1, elt2);
+ if (DatumGetBool(opresult))
+ continue;
- if (!DatumGetBool(opresult))
+ /* nope, see if arg1 is less than arg2 */
+ opresult = FunctionCall2(&my_extra->ordproc, elt1, elt2);
+ if (DatumGetBool(opresult))
{
- /* nope, see if arg1 is less than arg2 */
- opresult = FunctionCall2(&my_extra->ordproc,
- dvalues1[i], dvalues2[i]);
- if (DatumGetBool(opresult))
- {
- /* arg1 is less than arg2 */
- result = -1;
- break;
- }
- else
- {
- /* arg1 is greater than arg2 */
- result = 1;
- break;
- }
+ /* arg1 is less than arg2 */
+ result = -1;
+ break;
+ }
+ else
+ {
+ /* arg1 is greater than arg2 */
+ result = 1;
+ break;
}
}
- if ((result == 0) && (nelems1 != nelems2))
- result = (nelems1 < nelems2) ? -1 : 1;
+ if ((result == 0) && (nitems1 != nitems2))
+ result = (nitems1 < nitems2) ? -1 : 1;
/* Avoid leaking memory when handed toasted input. */
PG_FREE_IF_COPY(array1, 0);