1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-26 01:22:12 +03:00

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.
This commit is contained in:
Tom Lane
2000-02-21 18:47:12 +00:00
parent ee97d103cc
commit 393f313227
12 changed files with 186 additions and 186 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.107 2000/02/20 21:32:05 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.108 2000/02/21 18:47:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -1501,14 +1501,12 @@ _copyValue(Value *from)
newnode->type = from->type;
switch (from->type)
{
case T_String:
newnode->val.str = pstrdup(from->val.str);
break;
case T_Integer:
newnode->val.ival = from->val.ival;
break;
case T_Float:
newnode->val.dval = from->val.dval;
case T_String:
newnode->val.str = pstrdup(from->val.str);
break;
default:
break;
@ -1722,8 +1720,8 @@ copyObject(void *from)
* VALUE NODES
*/
case T_Integer:
case T_String:
case T_Float:
case T_String:
retval = _copyValue(from);
break;
case T_List:

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.62 2000/02/20 21:32:05 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.63 2000/02/21 18:47:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -737,12 +737,11 @@ _equalValue(Value *a, Value *b)
switch (a->type)
{
case T_String:
return strcmp(a->val.str, b->val.str);
case T_Integer:
return a->val.ival == b->val.ival;
case T_Float:
return a->val.dval == b->val.dval;
case T_String:
return strcmp(a->val.str, b->val.str) == 0;
default:
break;
}
@ -870,8 +869,8 @@ equal(void *a, void *b)
retval = _equalEState(a, b);
break;
case T_Integer:
case T_String:
case T_Float:
case T_String:
retval = _equalValue(a, b);
break;
case T_List:

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/Attic/freefuncs.c,v 1.37 2000/02/20 21:32:05 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/Attic/freefuncs.c,v 1.38 2000/02/21 18:47:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -1130,7 +1130,8 @@ _freeValue(Value *node)
{
switch (node->type)
{
case T_String:
case T_Float:
case T_String:
pfree(node->val.str);
break;
default:
@ -1345,8 +1346,8 @@ freeObject(void *node)
* VALUE NODES
*/
case T_Integer:
case T_String:
case T_Float:
case T_String:
_freeValue(node);
break;
case T_List:

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.29 2000/02/06 03:27:32 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.30 2000/02/21 18:47:00 tgl Exp $
*
* NOTES
* XXX a few of the following functions are duplicated to handle
@ -73,19 +73,23 @@ makeInteger(long i)
/*
* makeFloat
*
* Caller is responsible for passing a palloc'd string.
*/
Value *
makeFloat(double d)
makeFloat(char *numericStr)
{
Value *v = makeNode(Value);
v->type = T_Float;
v->val.dval = d;
v->val.str = numericStr;
return v;
}
/*
* makeString
*
* Caller is responsible for passing a palloc'd string.
*/
Value *
makeString(char *str)

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.109 2000/02/20 21:32:05 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.110 2000/02/21 18:47:00 tgl Exp $
*
* NOTES
* Every (plan) node in POSTGRES has an associated "out" routine which
@ -1265,16 +1265,19 @@ _outValue(StringInfo str, Value *value)
{
switch (value->type)
{
case T_String:
appendStringInfo(str, " \"");
_outToken(str, value->val.str);
appendStringInfo(str, "\" ");
break;
case T_Integer:
appendStringInfo(str, " %ld ", value->val.ival);
break;
case T_Float:
appendStringInfo(str, " %.17g ", value->val.dval);
/* We assume the value is a valid numeric literal
* and so does not need quoting.
*/
appendStringInfo(str, " %s ", value->val.str);
break;
case T_String:
appendStringInfo(str, " \"");
_outToken(str, value->val.str);
appendStringInfo(str, "\" ");
break;
default:
elog(NOTICE, "_outValue: don't know how to print type %d ",

View File

@ -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));
case T_Integer:
/* 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_Integer:
/* we know that the token terminates on a char atoi will stop at */
this_value = (Node *) makeInteger(atoi(token));
make_dotted_pair_cell = true;
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;