Skip to content

Commit 432ca91

Browse files
committed
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.
1 parent 43bb028 commit 432ca91

File tree

1 file changed

+46
-37
lines changed

1 file changed

+46
-37
lines changed

src/backend/utils/adt/arrayfuncs.c

+46-37
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.97 2003/08/08 21:42:04 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.98 2003/08/15 00:22:26 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -2510,18 +2510,21 @@ array_cmp(FunctionCallInfo fcinfo)
25102510
{
25112511
ArrayType *array1 = PG_GETARG_ARRAYTYPE_P(0);
25122512
ArrayType *array2 = PG_GETARG_ARRAYTYPE_P(1);
2513+
char *p1 = (char *) ARR_DATA_PTR(array1);
2514+
char *p2 = (char *) ARR_DATA_PTR(array2);
2515+
int ndims1 = ARR_NDIM(array1);
2516+
int ndims2 = ARR_NDIM(array2);
2517+
int *dims1 = ARR_DIMS(array1);
2518+
int *dims2 = ARR_DIMS(array2);
2519+
int nitems1 = ArrayGetNItems(ndims1, dims1);
2520+
int nitems2 = ArrayGetNItems(ndims2, dims2);
2521+
Oid element_type = ARR_ELEMTYPE(array1);
25132522
FmgrInfo *ac_fmgr_info = fcinfo->flinfo;
2514-
Datum opresult;
25152523
int result = 0;
2516-
Oid element_type = InvalidOid;
25172524
int typlen;
25182525
bool typbyval;
25192526
char typalign;
2520-
Datum *dvalues1;
2521-
int nelems1;
2522-
Datum *dvalues2;
2523-
int nelems2;
2524-
int min_nelems;
2527+
int min_nitems;
25252528
int i;
25262529
typedef struct
25272530
{
@@ -2534,7 +2537,6 @@ array_cmp(FunctionCallInfo fcinfo)
25342537
} ac_extra;
25352538
ac_extra *my_extra;
25362539

2537-
element_type = ARR_ELEMTYPE(array1);
25382540
if (element_type != ARR_ELEMTYPE(array2))
25392541
ereport(ERROR,
25402542
(errcode(ERRCODE_DATATYPE_MISMATCH),
@@ -2573,42 +2575,49 @@ array_cmp(FunctionCallInfo fcinfo)
25732575
typbyval = my_extra->typbyval;
25742576
typalign = my_extra->typalign;
25752577

2576-
/* extract a C array of arg array datums */
2577-
deconstruct_array(array1, element_type, typlen, typbyval, typalign,
2578-
&dvalues1, &nelems1);
2578+
/* Loop over source data */
2579+
min_nitems = Min(nitems1, nitems2);
2580+
for (i = 0; i < min_nitems; i++)
2581+
{
2582+
Datum elt1;
2583+
Datum elt2;
2584+
Datum opresult;
2585+
2586+
/* Get element pair */
2587+
elt1 = fetch_att(p1, typbyval, typlen);
2588+
elt2 = fetch_att(p2, typbyval, typlen);
25792589

2580-
deconstruct_array(array2, element_type, typlen, typbyval, typalign,
2581-
&dvalues2, &nelems2);
2590+
p1 = att_addlength(p1, typlen, PointerGetDatum(p1));
2591+
p1 = (char *) att_align(p1, typalign);
2592+
2593+
p2 = att_addlength(p2, typlen, PointerGetDatum(p2));
2594+
p2 = (char *) att_align(p2, typalign);
2595+
2596+
/* Compare the pair of elements */
25822597

2583-
min_nelems = Min(nelems1, nelems2);
2584-
for (i = 0; i < min_nelems; i++)
2585-
{
25862598
/* are they equal */
2587-
opresult = FunctionCall2(&my_extra->eqproc,
2588-
dvalues1[i], dvalues2[i]);
2599+
opresult = FunctionCall2(&my_extra->eqproc, elt1, elt2);
2600+
if (DatumGetBool(opresult))
2601+
continue;
25892602

2590-
if (!DatumGetBool(opresult))
2603+
/* nope, see if arg1 is less than arg2 */
2604+
opresult = FunctionCall2(&my_extra->ordproc, elt1, elt2);
2605+
if (DatumGetBool(opresult))
25912606
{
2592-
/* nope, see if arg1 is less than arg2 */
2593-
opresult = FunctionCall2(&my_extra->ordproc,
2594-
dvalues1[i], dvalues2[i]);
2595-
if (DatumGetBool(opresult))
2596-
{
2597-
/* arg1 is less than arg2 */
2598-
result = -1;
2599-
break;
2600-
}
2601-
else
2602-
{
2603-
/* arg1 is greater than arg2 */
2604-
result = 1;
2605-
break;
2606-
}
2607+
/* arg1 is less than arg2 */
2608+
result = -1;
2609+
break;
2610+
}
2611+
else
2612+
{
2613+
/* arg1 is greater than arg2 */
2614+
result = 1;
2615+
break;
26072616
}
26082617
}
26092618

2610-
if ((result == 0) && (nelems1 != nelems2))
2611-
result = (nelems1 < nelems2) ? -1 : 1;
2619+
if ((result == 0) && (nitems1 != nitems2))
2620+
result = (nitems1 < nitems2) ? -1 : 1;
26122621

26132622
/* Avoid leaking memory when handed toasted input. */
26142623
PG_FREE_IF_COPY(array1, 0);

0 commit comments

Comments
 (0)