From b0da2d95d994bf25ec7c80d296b61272a4d85041 Mon Sep 17 00:00:00 2001 From: Andrew Kane Date: Thu, 19 Sep 2024 19:52:16 -0700 Subject: [PATCH] Fixed array_to_sparsevec on Windows [skip ci] --- src/sparsevec.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/sparsevec.c b/src/sparsevec.c index 55c14c4..50f6fb8 100644 --- a/src/sparsevec.c +++ b/src/sparsevec.c @@ -707,25 +707,32 @@ array_to_sparsevec(PG_FUNCTION_ARGS) CheckDim(nelemsp); CheckExpectedDim(typmod, nelemsp); +#ifdef _MSC_VER +/* /fp:fast may not propagate +/-Infinity or NaN */ +#define IS_NOT_ZERO(v) (isnan((float) v) || isinf((float) v) || ((float) v) != 0) +#else +#define IS_NOT_ZERO(v) (((float) (v)) != 0) +#endif + if (ARR_ELEMTYPE(array) == INT4OID) { for (int i = 0; i < nelemsp; i++) - nnz += ((float) DatumGetInt32(elemsp[i])) != 0; + nnz += IS_NOT_ZERO(DatumGetInt32(elemsp[i])); } else if (ARR_ELEMTYPE(array) == FLOAT8OID) { for (int i = 0; i < nelemsp; i++) - nnz += ((float) DatumGetFloat8(elemsp[i])) != 0; + nnz += IS_NOT_ZERO(DatumGetFloat8(elemsp[i])); } else if (ARR_ELEMTYPE(array) == FLOAT4OID) { for (int i = 0; i < nelemsp; i++) - nnz += (DatumGetFloat4(elemsp[i]) != 0); + nnz += IS_NOT_ZERO(DatumGetFloat4(elemsp[i])); } else if (ARR_ELEMTYPE(array) == NUMERICOID) { for (int i = 0; i < nelemsp; i++) - nnz += (DatumGetFloat4(DirectFunctionCall1(numeric_float4, elemsp[i])) != 0); + nnz += IS_NOT_ZERO(DirectFunctionCall1(numeric_float4, elemsp[i])); } else { @@ -740,7 +747,7 @@ array_to_sparsevec(PG_FUNCTION_ARGS) #define PROCESS_ARRAY_ELEM(elem) \ do { \ float v = (float) (elem); \ - if (v != 0) { \ + if (IS_NOT_ZERO(v)) { \ /* Safety check */ \ if (j >= result->nnz) \ elog(ERROR, "safety check failed"); \ @@ -778,6 +785,7 @@ array_to_sparsevec(PG_FUNCTION_ARGS) } #undef PROCESS_ARRAY_ELEM +#undef IS_NOT_ZERO /* * Free allocation from deconstruct_array. Do not free individual elements @@ -785,6 +793,9 @@ array_to_sparsevec(PG_FUNCTION_ARGS) */ pfree(elemsp); + if (j != result->nnz) + elog(ERROR, "correctness check failed"); + /* Check elements */ for (int i = 0; i < result->nnz; i++) CheckElement(values[i]);