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

Lines changed: 46 additions & 37 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy