aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/ecpg/ecpglib/data.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/interfaces/ecpg/ecpglib/data.c')
-rw-r--r--src/interfaces/ecpg/ecpglib/data.c60
1 files changed, 57 insertions, 3 deletions
diff --git a/src/interfaces/ecpg/ecpglib/data.c b/src/interfaces/ecpg/ecpglib/data.c
index f30fe8ba1e0..d816ff4b3b2 100644
--- a/src/interfaces/ecpg/ecpglib/data.c
+++ b/src/interfaces/ecpg/ecpglib/data.c
@@ -1,10 +1,11 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/data.c,v 1.47 2009/12/31 19:41:36 tgl Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/data.c,v 1.48 2010/02/02 16:09:11 meskes Exp $ */
#define POSTGRES_ECPG_INTERNAL
#include "postgres_fe.h"
#include <stdlib.h>
#include <string.h>
+#include <math.h>
#include "ecpgtype.h"
#include "ecpglib.h"
@@ -38,6 +39,58 @@ garbage_left(enum ARRAY_TYPE isarray, char *scan_length, enum COMPAT_MODE compat
return false;
}
+/* stolen code from src/backend/utils/adt/float.c */
+#if defined(WIN32) && !defined(NAN)
+static const uint32 nan[2] = {0xffffffff, 0x7fffffff};
+
+#define NAN (*(const double *) nan)
+#endif
+
+static double
+get_float8_infinity(void)
+{
+#ifdef INFINITY
+ return (double) INFINITY;
+#else
+ return (double) (HUGE_VAL * HUGE_VAL);
+#endif
+}
+
+static double
+get_float8_nan(void)
+{
+#ifdef NAN
+ return (double) NAN;
+#else
+ return (double) (0.0 / 0.0);
+#endif
+}
+
+static bool
+check_special_value(char *ptr, double *retval, char **endptr)
+{
+ if (!pg_strncasecmp(ptr, "NaN", 3))
+ {
+ *retval = get_float8_nan();
+ *endptr = ptr + 3;
+ return true;
+ }
+ else if (!pg_strncasecmp(ptr, "Infinity", 8))
+ {
+ *retval = get_float8_infinity();
+ *endptr = ptr + 8;
+ return true;
+ }
+ else if (!pg_strncasecmp(ptr, "-Infinity", 9))
+ {
+ *retval = -get_float8_infinity();
+ *endptr = ptr + 9;
+ return true;
+ }
+
+ return false;
+}
+
bool
ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
enum ECPGttype type, enum ECPGttype ind_type,
@@ -300,8 +353,9 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
case ECPGt_float:
case ECPGt_double:
if (isarray && *pval == '"')
- dres = strtod(pval + 1, &scan_length);
- else
+ pval++;
+
+ if (!check_special_value(pval, &dres, &scan_length))
dres = strtod(pval, &scan_length);
if (isarray && *scan_length == '"')