summaryrefslogtreecommitdiff
path: root/src/backend/nodes/read.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2000-02-21 18:47:12 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2000-02-21 18:47:12 +0000
commit393f313227fba2b7905cfbd69b3e4c18d762bf4f (patch)
tree0eab81bd6705a19b625880d9b5cefb1d50c78d78 /src/backend/nodes/read.c
parentee97d103ccf68ae45343caea4188ca3dd5ce7365 (diff)
Change parse-time representation of float literals (which include oversize
integers) to be strings instead of 'double'. We convert from string form to internal representation only after type resolution has determined the correct type for the constant. This eliminates loss-of-precision worries and gets rid of the change in behavior seen at 17 digits with the previous kluge.
Diffstat (limited to 'src/backend/nodes/read.c')
-rw-r--r--src/backend/nodes/read.c61
1 files changed, 35 insertions, 26 deletions
diff --git a/src/backend/nodes/read.c b/src/backend/nodes/read.c
index 75e10576d5b..9f68f4d0e90 100644
--- a/src/backend/nodes/read.c
+++ b/src/backend/nodes/read.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/read.c,v 1.20 2000/01/26 05:56:32 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/read.c,v 1.21 2000/02/21 18:47:00 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -18,6 +18,7 @@
*-------------------------------------------------------------------------
*/
#include <ctype.h>
+#include <errno.h>
#include "postgres.h"
@@ -193,30 +194,32 @@ static NodeTag
nodeTokenType(char *token, int length)
{
NodeTag retval;
+ char *numptr;
+ int numlen;
+ char *endptr;
/*
- * Check if the token is a number (decimal or integer, positive or
- * negative)
+ * Check if the token is a number
*/
- if (isdigit(*token) ||
- (length >= 2 && *token == '-' && isdigit(token[1])))
+ numptr = token;
+ numlen = length;
+ if (*numptr == '+' || *numptr == '-')
+ numptr++, numlen--;
+ if ((numlen > 0 && isdigit(*numptr)) ||
+ (numlen > 1 && *numptr == '.' && isdigit(numptr[1])))
{
/*
- * skip the optional '-' (i.e. negative number)
+ * Yes. Figure out whether it is integral or float;
+ * this requires both a syntax check and a range check.
+ * strtol() can do both for us.
+ * We know the token will end at a character that strtol will
+ * stop at, so we do not need to modify the string.
*/
- if (*token == '-')
- token++, length--;
-
- /*
- * See if there is a decimal point
- */
- while (length > 0 && *token != '.')
- token++, length--;
-
- /*
- * if there isn't, token's an int, otherwise it's a float.
- */
- retval = (*token != '.') ? T_Integer : T_Float;
+ errno = 0;
+ (void) strtol(token, &endptr, 10);
+ if (endptr != token+length || errno == ERANGE)
+ return T_Float;
+ return T_Integer;
}
/*
* these three cases do not need length checks, since lsptok()
@@ -317,17 +320,23 @@ nodeRead(bool read_car_only)
make_dotted_pair_cell = true;
}
break;
- case T_Float:
- /* we know that the token terminates on a char atof will stop at */
- this_value = (Node *) makeFloat(atof(token));
- make_dotted_pair_cell = true;
- break;
case T_Integer:
- /* we know that the token terminates on a char atoi will stop at */
- this_value = (Node *) makeInteger(atoi(token));
+ /* we know that the token terminates on a char atol will stop at */
+ this_value = (Node *) makeInteger(atol(token));
make_dotted_pair_cell = true;
break;
+ case T_Float:
+ {
+ char *fval = (char *) palloc(tok_len + 1);
+
+ memcpy(fval, token, tok_len);
+ fval[tok_len] = '\0';
+ this_value = (Node *) makeFloat(fval);
+ make_dotted_pair_cell = true;
+ }
+ break;
case T_String:
+ /* need to remove leading and trailing quotes, and backslashes */
this_value = (Node *) makeString(debackslash(token+1, tok_len-2));
make_dotted_pair_cell = true;
break;