@@ -707,25 +707,32 @@ array_to_sparsevec(PG_FUNCTION_ARGS)
707
707
CheckDim (nelemsp );
708
708
CheckExpectedDim (typmod , nelemsp );
709
709
710
+ #ifdef _MSC_VER
711
+ /* /fp:fast may not propagate +/-Infinity or NaN */
712
+ #define IS_NOT_ZERO (v ) (isnan((float) v) || isinf((float) v) || ((float) v) != 0)
713
+ #else
714
+ #define IS_NOT_ZERO (v ) (((float) (v)) != 0)
715
+ #endif
716
+
710
717
if (ARR_ELEMTYPE (array ) == INT4OID )
711
718
{
712
719
for (int i = 0 ; i < nelemsp ; i ++ )
713
- nnz += (( float ) DatumGetInt32 (elemsp [i ])) != 0 ;
720
+ nnz += IS_NOT_ZERO ( DatumGetInt32 (elemsp [i ]));
714
721
}
715
722
else if (ARR_ELEMTYPE (array ) == FLOAT8OID )
716
723
{
717
724
for (int i = 0 ; i < nelemsp ; i ++ )
718
- nnz += (( float ) DatumGetFloat8 (elemsp [i ])) != 0 ;
725
+ nnz += IS_NOT_ZERO ( DatumGetFloat8 (elemsp [i ]));
719
726
}
720
727
else if (ARR_ELEMTYPE (array ) == FLOAT4OID )
721
728
{
722
729
for (int i = 0 ; i < nelemsp ; i ++ )
723
- nnz += (DatumGetFloat4 (elemsp [i ]) != 0 );
730
+ nnz += IS_NOT_ZERO (DatumGetFloat4 (elemsp [i ]));
724
731
}
725
732
else if (ARR_ELEMTYPE (array ) == NUMERICOID )
726
733
{
727
734
for (int i = 0 ; i < nelemsp ; i ++ )
728
- nnz += ( DatumGetFloat4 ( DirectFunctionCall1 (numeric_float4 , elemsp [i ])) != 0 );
735
+ nnz += IS_NOT_ZERO ( DirectFunctionCall1 (numeric_float4 , elemsp [i ]));
729
736
}
730
737
else
731
738
{
@@ -740,7 +747,7 @@ array_to_sparsevec(PG_FUNCTION_ARGS)
740
747
#define PROCESS_ARRAY_ELEM (elem ) \
741
748
do { \
742
749
float v = (float) (elem); \
743
- if (v != 0 ) { \
750
+ if (IS_NOT_ZERO(v) ) { \
744
751
/* Safety check */ \
745
752
if (j >= result -> nnz ) \
746
753
elog (ERROR , "safety check failed" ); \
@@ -778,13 +785,17 @@ array_to_sparsevec(PG_FUNCTION_ARGS)
778
785
}
779
786
780
787
#undef PROCESS_ARRAY_ELEM
788
+ #undef IS_NOT_ZERO
781
789
782
790
/*
783
791
* Free allocation from deconstruct_array. Do not free individual elements
784
792
* when pass-by-reference since they point to original array.
785
793
*/
786
794
pfree (elemsp );
787
795
796
+ if (j != result -> nnz )
797
+ elog (ERROR , "correctness check failed" );
798
+
788
799
/* Check elements */
789
800
for (int i = 0 ; i < result -> nnz ; i ++ )
790
801
CheckElement (values [i ]);
0 commit comments