Fixed array_to_sparsevec on Windows [skip ci]

This commit is contained in:
Andrew Kane
2024-09-19 19:52:16 -07:00
parent 3fb05eb847
commit b0da2d95d9

View File

@@ -707,25 +707,32 @@ array_to_sparsevec(PG_FUNCTION_ARGS)
CheckDim(nelemsp); CheckDim(nelemsp);
CheckExpectedDim(typmod, 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) if (ARR_ELEMTYPE(array) == INT4OID)
{ {
for (int i = 0; i < nelemsp; i++) 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) else if (ARR_ELEMTYPE(array) == FLOAT8OID)
{ {
for (int i = 0; i < nelemsp; i++) 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) else if (ARR_ELEMTYPE(array) == FLOAT4OID)
{ {
for (int i = 0; i < nelemsp; i++) 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) else if (ARR_ELEMTYPE(array) == NUMERICOID)
{ {
for (int i = 0; i < nelemsp; i++) 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 else
{ {
@@ -740,7 +747,7 @@ array_to_sparsevec(PG_FUNCTION_ARGS)
#define PROCESS_ARRAY_ELEM(elem) \ #define PROCESS_ARRAY_ELEM(elem) \
do { \ do { \
float v = (float) (elem); \ float v = (float) (elem); \
if (v != 0) { \ if (IS_NOT_ZERO(v)) { \
/* Safety check */ \ /* Safety check */ \
if (j >= result->nnz) \ if (j >= result->nnz) \
elog(ERROR, "safety check failed"); \ elog(ERROR, "safety check failed"); \
@@ -778,6 +785,7 @@ array_to_sparsevec(PG_FUNCTION_ARGS)
} }
#undef PROCESS_ARRAY_ELEM #undef PROCESS_ARRAY_ELEM
#undef IS_NOT_ZERO
/* /*
* Free allocation from deconstruct_array. Do not free individual elements * Free allocation from deconstruct_array. Do not free individual elements
@@ -785,6 +793,9 @@ array_to_sparsevec(PG_FUNCTION_ARGS)
*/ */
pfree(elemsp); pfree(elemsp);
if (j != result->nnz)
elog(ERROR, "correctness check failed");
/* Check elements */ /* Check elements */
for (int i = 0; i < result->nnz; i++) for (int i = 0; i < result->nnz; i++)
CheckElement(values[i]); CheckElement(values[i]);