diff --git a/contrib/hstore_plperl/hstore_plperl.c b/contrib/hstore_plperl/hstore_plperl.c index b5f72138f17..4977724a1bf 100644 --- a/contrib/hstore_plperl/hstore_plperl.c +++ b/contrib/hstore_plperl/hstore_plperl.c @@ -125,8 +125,9 @@ plperl_to_hstore(PG_FUNCTION_ARGS) errmsg("cannot transform non-hash Perl value to hstore"))); hv = (HV *) in; - pcount = hv_iterinit(hv); + (void) hv_iterinit(hv); + pcount = 64; /* arbitrary initial guess */ pairs = palloc_array(Pairs, pcount); i = 0; @@ -135,6 +136,12 @@ plperl_to_hstore(PG_FUNCTION_ARGS) char *key = sv2cstr(HeSVKEY_force(he)); SV *value = HeVAL(he); + if (i >= pcount) + { + pcount *= 2; + pairs = repalloc_array(pairs, Pairs, pcount); + } + pairs[i].key = pstrdup(key); pairs[i].keylen = hstoreCheckKeyLen(strlen(pairs[i].key)); pairs[i].needfree = true; @@ -155,7 +162,7 @@ plperl_to_hstore(PG_FUNCTION_ARGS) i++; } - pcount = hstoreUniquePairs(pairs, pcount, &buflen); + pcount = hstoreUniquePairs(pairs, i, &buflen); out = hstorePairs(pairs, pcount, buflen); PG_RETURN_POINTER(out); } diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index c50165923a8..d1751c3124c 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -1165,6 +1165,10 @@ get_perl_array_ref(SV *sv) * if we didn't do it like that, we'd need some other convention for knowing * whether we'd already found any scalars (and thus the number of dimensions * is frozen). + * + * Caller is required to have set dims[cur_depth - 1] to the length of the + * input array, i.e., av_len(av) + 1. We make this requirement so as to + * avoid reading av_len() twice, which is hazardous for tied arrays. */ static void array_to_datum_internal(AV *av, ArrayBuildState **astatep, @@ -1174,7 +1178,7 @@ array_to_datum_internal(AV *av, ArrayBuildState **astatep, { dTHX; int i; - int len = av_len(av) + 1; + int len = dims[cur_depth - 1]; for (i = 0; i < len; i++) {