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:
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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 ",
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user