Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitcedae13

Browse files
author
Michael Meskes
committed
Fixed NaN/Infinity problems in ECPG for float/double/numeric/decimal by making it OS independant.
Patch done by Zoltán Böszörményi.
1 parent63f9282 commitcedae13

File tree

14 files changed

+859
-15
lines changed

14 files changed

+859
-15
lines changed

‎src/interfaces/ecpg/ecpglib/data.c

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/data.c,v 1.47 2009/12/31 19:41:36 tgl Exp $ */
1+
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/data.c,v 1.48 2010/02/02 16:09:11 meskes Exp $ */
22

33
#definePOSTGRES_ECPG_INTERNAL
44
#include"postgres_fe.h"
55

66
#include<stdlib.h>
77
#include<string.h>
8+
#include<math.h>
89

910
#include"ecpgtype.h"
1011
#include"ecpglib.h"
@@ -38,6 +39,58 @@ garbage_left(enum ARRAY_TYPE isarray, char *scan_length, enum COMPAT_MODE compat
3839
return false;
3940
}
4041

42+
/* stolen code from src/backend/utils/adt/float.c */
43+
#if defined(WIN32)&& !defined(NAN)
44+
staticconstuint32nan[2]= {0xffffffff,0x7fffffff};
45+
46+
#defineNAN (*(const double *) nan)
47+
#endif
48+
49+
staticdouble
50+
get_float8_infinity(void)
51+
{
52+
#ifdefINFINITY
53+
return (double)INFINITY;
54+
#else
55+
return (double) (HUGE_VAL*HUGE_VAL);
56+
#endif
57+
}
58+
59+
staticdouble
60+
get_float8_nan(void)
61+
{
62+
#ifdefNAN
63+
return (double)NAN;
64+
#else
65+
return (double) (0.0 /0.0);
66+
#endif
67+
}
68+
69+
staticbool
70+
check_special_value(char*ptr,double*retval,char**endptr)
71+
{
72+
if (!pg_strncasecmp(ptr,"NaN",3))
73+
{
74+
*retval=get_float8_nan();
75+
*endptr=ptr+3;
76+
return true;
77+
}
78+
elseif (!pg_strncasecmp(ptr,"Infinity",8))
79+
{
80+
*retval=get_float8_infinity();
81+
*endptr=ptr+8;
82+
return true;
83+
}
84+
elseif (!pg_strncasecmp(ptr,"-Infinity",9))
85+
{
86+
*retval=-get_float8_infinity();
87+
*endptr=ptr+9;
88+
return true;
89+
}
90+
91+
return false;
92+
}
93+
4194
bool
4295
ecpg_get_data(constPGresult*results,intact_tuple,intact_field,intlineno,
4396
enumECPGttypetype,enumECPGttypeind_type,
@@ -300,8 +353,9 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
300353
caseECPGt_float:
301354
caseECPGt_double:
302355
if (isarray&&*pval=='"')
303-
dres=strtod(pval+1,&scan_length);
304-
else
356+
pval++;
357+
358+
if (!check_special_value(pval,&dres,&scan_length))
305359
dres=strtod(pval,&scan_length);
306360

307361
if (isarray&&*scan_length=='"')

‎src/interfaces/ecpg/ecpglib/execute.c

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.90 2010/01/29 15:57:01 meskes Exp $ */
1+
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.91 2010/02/02 16:09:11 meskes Exp $ */
22

33
/*
44
* The aim is to get a simpler inteface to the database routines.
@@ -17,6 +17,7 @@
1717
#include"postgres_fe.h"
1818

1919
#include<locale.h>
20+
#include<math.h>
2021

2122
#include"pg_type.h"
2223

@@ -463,6 +464,38 @@ ecpg_store_result(const PGresult *results, int act_field,
463464
returnstatus;
464465
}
465466

467+
staticvoid
468+
sprintf_double_value(char*ptr,doublevalue,constchar*delim)
469+
{
470+
if (isinf(value))
471+
{
472+
if (value<0)
473+
sprintf(ptr,"%s%s","-Infinity",delim);
474+
else
475+
sprintf(ptr,"%s%s","Infinity",delim);
476+
}
477+
elseif (isnan(value))
478+
sprintf(ptr,"%s%s","NaN",delim);
479+
else
480+
sprintf(ptr,"%.14g%s",value,delim);
481+
}
482+
483+
staticvoid
484+
sprintf_float_value(char*ptr,floatvalue,constchar*delim)
485+
{
486+
if (isinf(value))
487+
{
488+
if (value<0)
489+
sprintf(ptr,"%s%s","-Infinity",delim);
490+
else
491+
sprintf(ptr,"%s%s","Infinity",delim);
492+
}
493+
elseif (isnan(value))
494+
sprintf(ptr,"%s%s","NaN",delim);
495+
else
496+
sprintf(ptr,"%.14g%s",value,delim);
497+
}
498+
466499
bool
467500
ecpg_store_input(constintlineno,constboolforce_indicator,conststructvariable*var,
468501
char**tobeinserted_p,boolquote)
@@ -693,12 +726,12 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
693726
strcpy(mallocedval,"array [");
694727

695728
for (element=0;element<asize;element++)
696-
sprintf(mallocedval+strlen(mallocedval),"%.14g,",((float*)var->value)[element]);
729+
sprintf_float_value(mallocedval+strlen(mallocedval), ((float*)var->value)[element],",");
697730

698731
strcpy(mallocedval+strlen(mallocedval)-1,"]");
699732
}
700733
else
701-
sprintf(mallocedval,"%.14g",*((float*)var->value));
734+
sprintf_float_value(mallocedval,*((float*)var->value),"");
702735

703736
*tobeinserted_p=mallocedval;
704737
break;
@@ -712,12 +745,12 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
712745
strcpy(mallocedval,"array [");
713746

714747
for (element=0;element<asize;element++)
715-
sprintf(mallocedval+strlen(mallocedval),"%.14g,",((double*)var->value)[element]);
748+
sprintf_double_value(mallocedval+strlen(mallocedval), ((double*)var->value)[element],",");
716749

717750
strcpy(mallocedval+strlen(mallocedval)-1,"]");
718751
}
719752
else
720-
sprintf(mallocedval,"%.14g",*((double*)var->value));
753+
sprintf_double_value(mallocedval,*((double*)var->value),"");
721754

722755
*tobeinserted_p=mallocedval;
723756
break;

‎src/interfaces/ecpg/ecpglib/misc.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/misc.c,v 1.54 2010/01/2609:07:31 meskes Exp $ */
1+
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/misc.c,v 1.55 2010/02/02 16:09:11 meskes Exp $ */
22

33
#definePOSTGRES_ECPG_INTERNAL
44
#include"postgres_fe.h"
@@ -344,11 +344,11 @@ ECPGset_noind_null(enum ECPGttype type, void *ptr)
344344
break;
345345
caseECPGt_decimal:
346346
memset((char*)ptr,0,sizeof(decimal));
347-
((decimal*)ptr)->sign=NUMERIC_NAN;
347+
((decimal*)ptr)->sign=NUMERIC_NULL;
348348
break;
349349
caseECPGt_numeric:
350350
memset((char*)ptr,0,sizeof(numeric));
351-
((numeric*)ptr)->sign=NUMERIC_NAN;
351+
((numeric*)ptr)->sign=NUMERIC_NULL;
352352
break;
353353
caseECPGt_interval:
354354
memset((char*)ptr,0xff,sizeof(interval));
@@ -416,11 +416,11 @@ ECPGis_noind_null(enum ECPGttype type, void *ptr)
416416
return true;
417417
break;
418418
caseECPGt_decimal:
419-
if (((decimal*)ptr)->sign==NUMERIC_NAN)
419+
if (((decimal*)ptr)->sign==NUMERIC_NULL)
420420
return true;
421421
break;
422422
caseECPGt_numeric:
423-
if (((numeric*)ptr)->sign==NUMERIC_NAN)
423+
if (((numeric*)ptr)->sign==NUMERIC_NULL)
424424
return true;
425425
break;
426426
caseECPGt_interval:

‎src/interfaces/ecpg/include/pgtypes_numeric.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#defineNUMERIC_POS0x0000
55
#defineNUMERIC_NEG0x4000
66
#defineNUMERIC_NAN0xC000
7+
#defineNUMERIC_NULL0xF000
78
#defineNUMERIC_MAX_PRECISION1000
89
#defineNUMERIC_MAX_DISPLAY_SCALENUMERIC_MAX_PRECISION
910
#defineNUMERIC_MIN_DISPLAY_SCALE0

‎src/interfaces/ecpg/pgtypeslib/numeric.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/numeric.c,v 1.34 2009/09/0309:59:20 meskes Exp $ */
1+
/* $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/numeric.c,v 1.35 2010/02/02 16:09:12 meskes Exp $ */
22

33
#include"postgres_fe.h"
44
#include<ctype.h>
@@ -173,6 +173,25 @@ set_var_from_str(char *str, char **ptr, numeric *dest)
173173
(*ptr)++;
174174
}
175175

176+
if (pg_strncasecmp(*ptr,"NaN",3)==0)
177+
{
178+
*ptr+=3;
179+
dest->sign=NUMERIC_NAN;
180+
181+
/* Should be nothing left but spaces */
182+
while (*(*ptr))
183+
{
184+
if (!isspace((unsignedchar)*(*ptr)))
185+
{
186+
errno=PGTYPES_NUM_BAD_NUMERIC;
187+
return-1;
188+
}
189+
(*ptr)++;
190+
}
191+
192+
return0;
193+
}
194+
176195
if (alloc_var(dest,strlen((*ptr)))<0)
177196
return-1;
178197
dest->weight=-1;
@@ -296,6 +315,15 @@ get_str_from_var(numeric *var, int dscale)
296315
inti;
297316
intd;
298317

318+
if (var->sign==NUMERIC_NAN)
319+
{
320+
str= (char*)pgtypes_alloc(4);
321+
if (str==NULL)
322+
returnNULL;
323+
sprintf(str,"NaN");
324+
returnstr;
325+
}
326+
299327
/*
300328
* Check if we must round up before printing the value and do so.
301329
*/

‎src/interfaces/ecpg/test/ecpg_schedule

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ test: pgtypeslib/dt_test
1515
test: pgtypeslib/dt_test2
1616
test: pgtypeslib/num_test
1717
test: pgtypeslib/num_test2
18+
test: pgtypeslib/nan_test
1819
test: preproc/array_of_struct
1920
test: preproc/autoprep
2021
test: preproc/comment

‎src/interfaces/ecpg/test/ecpg_schedule_tcp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ test: pgtypeslib/dt_test
1515
test: pgtypeslib/dt_test2
1616
test: pgtypeslib/num_test
1717
test: pgtypeslib/num_test2
18+
test: pgtypeslib/nan_test
1819
test: preproc/array_of_struct
1920
test: preproc/autoprep
2021
test: preproc/comment

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp