diff options
Diffstat (limited to 'src/pl/plperl/plperl.c')
-rw-r--r-- | src/pl/plperl/plperl.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index cd917ab8e46..269f7f33220 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -12,8 +12,9 @@ /* system stuff */ #include <ctype.h> #include <fcntl.h> -#include <unistd.h> +#include <limits.h> #include <locale.h> +#include <unistd.h> /* postgreSQL stuff */ #include "access/htup_details.h" @@ -281,7 +282,7 @@ static Datum plperl_hash_to_datum(SV *src, TupleDesc td); static void plperl_init_shared_libs(pTHX); static void plperl_trusted_init(void); static void plperl_untrusted_init(void); -static HV *plperl_spi_execute_fetch_result(SPITupleTable *, int, int); +static HV *plperl_spi_execute_fetch_result(SPITupleTable *, uint64, int); static char *hek2cstr(HE *he); static SV **hv_store_string(HV *hv, const char *key, SV *val); static SV **hv_fetch_string(HV *hv, const char *key); @@ -1472,7 +1473,7 @@ plperl_ref_from_pg_array(Datum arg, Oid typid) hv = newHV(); (void) hv_store(hv, "array", 5, av, 0); - (void) hv_store(hv, "typeoid", 7, newSViv(typid), 0); + (void) hv_store(hv, "typeoid", 7, newSVuv(typid), 0); return sv_bless(newRV_noinc((SV *) hv), gv_stashpv("PostgreSQL::InServer::ARRAY", 0)); @@ -3091,7 +3092,7 @@ plperl_spi_exec(char *query, int limit) static HV * -plperl_spi_execute_fetch_result(SPITupleTable *tuptable, int processed, +plperl_spi_execute_fetch_result(SPITupleTable *tuptable, uint64 processed, int status) { HV *result; @@ -3103,13 +3104,25 @@ plperl_spi_execute_fetch_result(SPITupleTable *tuptable, int processed, hv_store_string(result, "status", cstr2sv(SPI_result_code_string(status))); hv_store_string(result, "processed", - newSViv(processed)); + (processed > (uint64) INT_MAX) ? + newSVnv((double) processed) : + newSViv((int) processed)); if (status > 0 && tuptable) { AV *rows; SV *row; - int i; + uint64 i; + + /* + * av_extend's 2nd argument is declared I32. It's possible we could + * nonetheless push more than INT_MAX elements into a Perl array, but + * let's just fail instead of trying. + */ + if (processed > (uint64) INT_MAX) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("query result has too many rows to fit in a Perl array"))); rows = newAV(); av_extend(rows, processed); |