Commit f3f3aae4 authored by Tom Lane's avatar Tom Lane

Improve conversions from uint64 to Perl types.

Perl's integers are pointer-sized, so can hold more than INT_MAX on LP64
platforms, and come in both signed (IV) and unsigned (UV).  Floating
point values (NV) may also be larger than double.

Since Perl 5.19.4 array indices are SSize_t instead of I32, so allow up
to SSize_t_max on those versions.  The limit is not imposed just by
av_extend's argument type, but all the array handling code, so remove
the speculative comment.

Dagfinn Ilmari Mannsåker
parent 6be84eeb
...@@ -3104,9 +3104,9 @@ plperl_spi_execute_fetch_result(SPITupleTable *tuptable, uint64 processed, ...@@ -3104,9 +3104,9 @@ plperl_spi_execute_fetch_result(SPITupleTable *tuptable, uint64 processed,
hv_store_string(result, "status", hv_store_string(result, "status",
cstr2sv(SPI_result_code_string(status))); cstr2sv(SPI_result_code_string(status)));
hv_store_string(result, "processed", hv_store_string(result, "processed",
(processed > (uint64) INT_MAX) ? (processed > (uint64) UV_MAX) ?
newSVnv((double) processed) : newSVnv((NV) processed) :
newSViv((int) processed)); newSVuv((UV) processed));
if (status > 0 && tuptable) if (status > 0 && tuptable)
{ {
...@@ -3114,12 +3114,8 @@ plperl_spi_execute_fetch_result(SPITupleTable *tuptable, uint64 processed, ...@@ -3114,12 +3114,8 @@ plperl_spi_execute_fetch_result(SPITupleTable *tuptable, uint64 processed,
SV *row; SV *row;
uint64 i; uint64 i;
/* /* Prevent overflow in call to av_extend() */
* av_extend's 2nd argument is declared I32. It's possible we could if (processed > (uint64) AV_SIZE_MAX)
* 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, ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("query result has too many rows to fit in a Perl array"))); errmsg("query result has too many rows to fit in a Perl array")));
......
...@@ -88,6 +88,13 @@ ...@@ -88,6 +88,13 @@
#define GvCV_set(gv, cv) (GvCV(gv) = cv) #define GvCV_set(gv, cv) (GvCV(gv) = cv)
#endif #endif
/* Perl 5.19.4 changed array indices from I32 to SSize_t */
#if PERL_BCDVERSION >= 0x5019004
#define AV_SIZE_MAX SSize_t_MAX
#else
#define AV_SIZE_MAX I32_MAX
#endif
/* declare routines from plperl.c for access by .xs files */ /* declare routines from plperl.c for access by .xs files */
HV *plperl_spi_exec(char *, int); HV *plperl_spi_exec(char *, int);
void plperl_return_next(SV *); void plperl_return_next(SV *);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment