Re: [HACKERS] numeric data type on 6.5 - Mailing list pgsql-hackers
From | Thomas Lockhart |
---|---|
Subject | Re: [HACKERS] numeric data type on 6.5 |
Date | |
Msg-id | 372F0201.2C9584E3@alumni.caltech.edu Whole thread Raw |
In response to | Re: [HACKERS] numeric data type on 6.5 (Tom Lane <tgl@sss.pgh.pa.us>) |
Responses |
Re: [HACKERS] numeric data type on 6.5
Re: [HACKERS] numeric data type on 6.5 |
List | pgsql-hackers |
> > I'm looking at this right now. I had coded in a fallback to FLOAT8 for > > the integer types because at the time that was the only other useful > > numeric type. However, I'm going to try changing the code to leave a > > failed INTx token as a string of unspecified type, which would be > > typed and converted later using the automatic coersion mechanism. > That would be good as far as it goes, but what about cases with a > decimal point in 'em? Converting to float and then to numeric will > lose precision. > I'm inclined to think you should prevent the parser from converting > *any* numeric constant out of string form until it knows the target data > type. > (IIRC, INT8 has problems similar to NUMERIC's...) Right. Here is a patch which tries to do something right for most cases. For the "integer" token (numbers w/o a decimal point) it keeps the token as a string if the conversion to int4 fails. I split the "real" token into "decimal" (w/o exponent) and "real"; at the moment "decimal" is forced to become a float8 if there are fewer than 18 characters in the string, but there may be a more robust strategy to be had. When a numeric token is kept as a string, the parser requires some typing context to handle the string later, otherwise it will complain. But that is probably better than silently swallowing numeric data and possibly mishandling it. Seems to do OK with numeric tokens of unspecified type which will become int8 and numeric in the parser. There may be some edge-effect cases (e.g. decimal data with 17 characters) which aren't quite right. Comments? - Tom -- Thomas Lockhart lockhart@alumni.caltech.edu South Pasadena, California*** ../src/backend/parser/scan.l.orig Tue Mar 30 15:08:02 1999 --- ../src/backend/parser/scan.l Tue Apr 27 16:29:21 1999 *************** *** 152,161 **** xmstop - integer [\-]?{digit}+ /* - real [\-]?{digit}+\.{digit}+([Ee][-+]?{digit}+)? - */ real [\-]?(((({digit}*\.{digit}+)|({digit}+\.{digit}*))([Ee][-+]?{digit}+)?)|({digit}+[Ee][-+]?{digit}+)) param \${integer} --- 152,162 ---- xmstop - integer [\-]?{digit}+ + decimal [\-]?(({digit}*\.{digit}+)|({digit}+\.{digit}*)) + real [\-]?((({digit}*\.{digit}+)|({digit}+\.{digit}*)|({digit}+))([Ee][-+]?{digit}+)) /* real [\-]?(((({digit}*\.{digit}+)|({digit}+\.{digit}*))([Ee][-+]?{digit}+)?)|({digit}+[Ee][-+]?{digit}+)) + */ param \${integer} *************** *** 334,348 **** --- 335,369 ---- if (*endptr != '\0' || errno == ERANGE) { errno = 0; + #if 0 yylval.dval = strtod(((char *)yytext),&endptr); if (*endptr != '\0' || errno == ERANGE) elog(ERROR,"Bad integer input '%s'",yytext); CheckFloat8Val(yylval.dval); elog(NOTICE,"Integer input '%s' is out of range; promoted to float", yytext); return FCONST; + #endif + yylval.str = pstrdup((char*)yytext); + return SCONST; } return ICONST; } + {decimal}/{space}*-{number} { + char* endptr; + + BEGIN(xm); + if (strlen((char *)yytext) <= 17) + { + errno = 0; + yylval.dval = strtod(((char *)yytext),&endptr); + if (*endptr != '\0' || errno == ERANGE) + elog(ERROR,"Bad float8 input '%s'",yytext); + CheckFloat8Val(yylval.dval); + return FCONST; + } + yylval.str = pstrdup((char*)yytext); + return SCONST; + } {real}/{space}*-{number} { char* endptr; *************** *** 362,375 **** --- 383,415 ---- if (*endptr != '\0' || errno == ERANGE) { errno = 0; + #if 0 yylval.dval = strtod(((char *)yytext),&endptr); if (*endptr != '\0' || errno == ERANGE) elog(ERROR,"Bad integer input '%s'",yytext); CheckFloat8Val(yylval.dval); elog(NOTICE,"Integer input '%s' is out of range; promoted to float", yytext); return FCONST; + #endif + yylval.str = pstrdup((char*)yytext); + return SCONST; } return ICONST; + } + {decimal} { + char* endptr; + + if (strlen((char *)yytext) <= 17) + { + errno = 0; + yylval.dval = strtod((char *)yytext,&endptr); + if (*endptr != '\0' || errno == ERANGE) + elog(ERROR,"Bad float input '%s'",yytext); + CheckFloat8Val(yylval.dval); + return FCONST; + } + yylval.str = pstrdup((char*)yytext); + return SCONST; } {real} { char* endptr;
pgsql-hackers by date: