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

Commit393f313

Browse files
committed
Change parse-time representation of float literals (which include oversize
integers) to be strings instead of 'double'. We convert from string formto internal representation only after type resolution has determined thecorrect type for the constant. This eliminates loss-of-precision worriesand gets rid of the change in behavior seen at 17 digits with theprevious kluge.
1 parentee97d10 commit393f313

File tree

12 files changed

+184
-184
lines changed

12 files changed

+184
-184
lines changed

‎src/backend/nodes/copyfuncs.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.107 2000/02/20 21:32:05 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.108 2000/02/21 18:47:00 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1501,14 +1501,12 @@ _copyValue(Value *from)
15011501
newnode->type=from->type;
15021502
switch (from->type)
15031503
{
1504-
caseT_String:
1505-
newnode->val.str=pstrdup(from->val.str);
1506-
break;
15071504
caseT_Integer:
15081505
newnode->val.ival=from->val.ival;
15091506
break;
15101507
caseT_Float:
1511-
newnode->val.dval=from->val.dval;
1508+
caseT_String:
1509+
newnode->val.str=pstrdup(from->val.str);
15121510
break;
15131511
default:
15141512
break;
@@ -1722,8 +1720,8 @@ copyObject(void *from)
17221720
* VALUE NODES
17231721
*/
17241722
caseT_Integer:
1725-
caseT_String:
17261723
caseT_Float:
1724+
caseT_String:
17271725
retval=_copyValue(from);
17281726
break;
17291727
caseT_List:

‎src/backend/nodes/equalfuncs.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.62 2000/02/20 21:32:05 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.63 2000/02/21 18:47:00 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -737,12 +737,11 @@ _equalValue(Value *a, Value *b)
737737

738738
switch (a->type)
739739
{
740-
caseT_String:
741-
returnstrcmp(a->val.str,b->val.str);
742740
caseT_Integer:
743741
returna->val.ival==b->val.ival;
744742
caseT_Float:
745-
returna->val.dval==b->val.dval;
743+
caseT_String:
744+
returnstrcmp(a->val.str,b->val.str)==0;
746745
default:
747746
break;
748747
}
@@ -870,8 +869,8 @@ equal(void *a, void *b)
870869
retval=_equalEState(a,b);
871870
break;
872871
caseT_Integer:
873-
caseT_String:
874872
caseT_Float:
873+
caseT_String:
875874
retval=_equalValue(a,b);
876875
break;
877876
caseT_List:

‎src/backend/nodes/freefuncs.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/nodes/Attic/freefuncs.c,v 1.37 2000/02/20 21:32:05 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/nodes/Attic/freefuncs.c,v 1.38 2000/02/21 18:47:00 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1130,7 +1130,8 @@ _freeValue(Value *node)
11301130
{
11311131
switch (node->type)
11321132
{
1133-
caseT_String:
1133+
caseT_Float:
1134+
caseT_String:
11341135
pfree(node->val.str);
11351136
break;
11361137
default:
@@ -1345,8 +1346,8 @@ freeObject(void *node)
13451346
* VALUE NODES
13461347
*/
13471348
caseT_Integer:
1348-
caseT_String:
13491349
caseT_Float:
1350+
caseT_String:
13501351
_freeValue(node);
13511352
break;
13521353
caseT_List:

‎src/backend/nodes/list.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.29 2000/02/06 03:27:32 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.30 2000/02/21 18:47:00 tgl Exp $
1212
*
1313
* NOTES
1414
* XXX a few of the following functions are duplicated to handle
@@ -73,19 +73,23 @@ makeInteger(long i)
7373

7474
/*
7575
*makeFloat
76+
*
77+
* Caller is responsible for passing a palloc'd string.
7678
*/
7779
Value*
78-
makeFloat(doubled)
80+
makeFloat(char*numericStr)
7981
{
8082
Value*v=makeNode(Value);
8183

8284
v->type=T_Float;
83-
v->val.dval=d;
85+
v->val.str=numericStr;
8486
returnv;
8587
}
8688

8789
/*
8890
*makeString
91+
*
92+
* Caller is responsible for passing a palloc'd string.
8993
*/
9094
Value*
9195
makeString(char*str)

‎src/backend/nodes/outfuncs.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
*$Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.109 2000/02/20 21:32:05 tgl Exp $
9+
*$Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.110 2000/02/21 18:47:00 tgl Exp $
1010
*
1111
* NOTES
1212
* Every (plan) node in POSTGRES has an associated "out" routine which
@@ -1265,16 +1265,19 @@ _outValue(StringInfo str, Value *value)
12651265
{
12661266
switch (value->type)
12671267
{
1268-
caseT_String:
1269-
appendStringInfo(str," \"");
1270-
_outToken(str,value->val.str);
1271-
appendStringInfo(str,"\" ");
1272-
break;
12731268
caseT_Integer:
12741269
appendStringInfo(str," %ld ",value->val.ival);
12751270
break;
12761271
caseT_Float:
1277-
appendStringInfo(str," %.17g ",value->val.dval);
1272+
/* We assume the value is a valid numeric literal
1273+
* and so does not need quoting.
1274+
*/
1275+
appendStringInfo(str," %s ",value->val.str);
1276+
break;
1277+
caseT_String:
1278+
appendStringInfo(str," \"");
1279+
_outToken(str,value->val.str);
1280+
appendStringInfo(str,"\" ");
12781281
break;
12791282
default:
12801283
elog(NOTICE,"_outValue: don't know how to print type %d ",

‎src/backend/nodes/read.c

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/backend/nodes/read.c,v 1.20 2000/01/26 05:56:32 momjian Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/nodes/read.c,v 1.21 2000/02/21 18:47:00 tgl Exp $
1313
*
1414
* HISTORY
1515
* AUTHORDATEMAJOR EVENT
@@ -18,6 +18,7 @@
1818
*-------------------------------------------------------------------------
1919
*/
2020
#include<ctype.h>
21+
#include<errno.h>
2122

2223
#include"postgres.h"
2324

@@ -193,30 +194,32 @@ static NodeTag
193194
nodeTokenType(char*token,intlength)
194195
{
195196
NodeTagretval;
197+
char*numptr;
198+
intnumlen;
199+
char*endptr;
196200

197201
/*
198-
* Check if the token is a number (decimal or integer, positive or
199-
* negative)
202+
* Check if the token is a number
200203
*/
201-
if (isdigit(*token)||
202-
(length >=2&&*token=='-'&&isdigit(token[1])))
204+
numptr=token;
205+
numlen=length;
206+
if (*numptr=='+'||*numptr=='-')
207+
numptr++,numlen--;
208+
if ((numlen>0&&isdigit(*numptr))||
209+
(numlen>1&&*numptr=='.'&&isdigit(numptr[1])))
203210
{
204211
/*
205-
* skip the optional '-' (i.e. negative number)
212+
* Yes. Figure out whether it is integral or float;
213+
* this requires both a syntax check and a range check.
214+
* strtol() can do both for us.
215+
* We know the token will end at a character that strtol will
216+
* stop at, so we do not need to modify the string.
206217
*/
207-
if (*token=='-')
208-
token++,length--;
209-
210-
/*
211-
* See if there is a decimal point
212-
*/
213-
while (length>0&&*token!='.')
214-
token++,length--;
215-
216-
/*
217-
* if there isn't, token's an int, otherwise it's a float.
218-
*/
219-
retval= (*token!='.') ?T_Integer :T_Float;
218+
errno=0;
219+
(void)strtol(token,&endptr,10);
220+
if (endptr!=token+length||errno==ERANGE)
221+
returnT_Float;
222+
returnT_Integer;
220223
}
221224
/*
222225
* these three cases do not need length checks, since lsptok()
@@ -317,17 +320,23 @@ nodeRead(bool read_car_only)
317320
make_dotted_pair_cell= true;
318321
}
319322
break;
320-
caseT_Float:
321-
/* we know that the token terminates on a char atof will stop at */
322-
this_value= (Node*)makeFloat(atof(token));
323-
make_dotted_pair_cell= true;
324-
break;
325323
caseT_Integer:
326-
/* we know that the token terminates on a charatoi will stop at */
327-
this_value= (Node*)makeInteger(atoi(token));
324+
/* we know that the token terminates on a charatol will stop at */
325+
this_value= (Node*)makeInteger(atol(token));
328326
make_dotted_pair_cell= true;
329327
break;
328+
caseT_Float:
329+
{
330+
char*fval= (char*)palloc(tok_len+1);
331+
332+
memcpy(fval,token,tok_len);
333+
fval[tok_len]='\0';
334+
this_value= (Node*)makeFloat(fval);
335+
make_dotted_pair_cell= true;
336+
}
337+
break;
330338
caseT_String:
339+
/* need to remove leading and trailing quotes, and backslashes */
331340
this_value= (Node*)makeString(debackslash(token+1,tok_len-2));
332341
make_dotted_pair_cell= true;
333342
break;

‎src/backend/parser/gram.y

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.147 2000/02/20 02:14:58 tgl Exp $
14+
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.148 2000/02/21 18:47:02 tgl Exp $
1515
*
1616
* HISTORY
1717
* AUTHORDATEMAJOR EVENT
@@ -78,6 +78,7 @@ static Node *makeRowExpr(char *opr, List *largs, List *rargs);
7878
staticvoidmapTargetColumns(List *source, List *target);
7979
staticvoidparam_type_init(Oid *typev,int nargs);
8080
static Node *doNegate(Node *n);
81+
staticvoiddoNegateFloat(Value *v);
8182

8283
/* old versions of flex define this as a macro*/
8384
#if defined(yywrap)
@@ -88,7 +89,6 @@ static Node *doNegate(Node *n);
8889

8990
%union
9091
{
91-
doubledval;
9292
intival;
9393
charchr;
9494
char*str;
@@ -352,9 +352,8 @@ static Node *doNegate(Node *n);
352352
UNLISTEN,UNTIL,VACUUM,VALID,VERBOSE,VERSION
353353

354354
/* Special keywords, not in the query language - see the "lex" file*/
355-
%token<str>IDENT,SCONST,Op
355+
%token<str>IDENT,FCONST,SCONST,Op
356356
%token<ival>ICONST,PARAM
357-
%token<dval>FCONST
358357

359358
/* these are not real. they are here so that they get generated as #define's*/
360359
%tokenOP
@@ -1567,7 +1566,7 @@ FloatOnly: FCONST
15671566
|'-'FCONST
15681567
{
15691568
$$ = makeFloat($2);
1570-
$$->val.dval = -$$->val.dval;
1569+
doNegateFloat($$);
15711570
}
15721571
;
15731572

@@ -1722,16 +1721,11 @@ TriggerFuncArgs: TriggerFuncArg
17221721

17231722
TriggerFuncArg:ICONST
17241723
{
1725-
char *s = (char *) palloc (256);
1724+
char *s = (char *) palloc(64);
17261725
sprintf (s,"%d", $1);
17271726
$$ = s;
17281727
}
1729-
|FCONST
1730-
{
1731-
char *s = (char *) palloc (256);
1732-
sprintf (s,"%g", $1);
1733-
$$ = s;
1734-
}
1728+
|FCONST{$$ =$1; }
17351729
|Sconst{$$ =$1; }
17361730
|IDENT{$$ =$1; }
17371731
;
@@ -5183,7 +5177,7 @@ AexprConst: Iconst
51835177
{
51845178
A_Const *n = makeNode(A_Const);
51855179
n->val.type = T_Float;
5186-
n->val.val.dval =$1;
5180+
n->val.val.str =$1;
51875181
$$ = (Node *)n;
51885182
}
51895183
|Sconst
@@ -5621,7 +5615,8 @@ Oid param_type(int t)
56215615
*a few cycles throughout the parse and rewrite stages if we collapse
56225616
*the minus into the constant sooner rather than later...
56235617
*/
5624-
static Node *doNegate(Node *n)
5618+
static Node *
5619+
doNegate(Node *n)
56255620
{
56265621
if (IsA(n, A_Const))
56275622
{
@@ -5634,10 +5629,30 @@ static Node *doNegate(Node *n)
56345629
}
56355630
if (con->val.type == T_Float)
56365631
{
5637-
con->val.val.dval = -con->val.val.dval;
5632+
doNegateFloat(&con->val);
56385633
return n;
56395634
}
56405635
}
56415636

56425637
returnmakeA_Expr(OP,"-",NULL, n);
56435638
}
5639+
5640+
staticvoid
5641+
doNegateFloat(Value *v)
5642+
{
5643+
char *oldval = v->val.str;
5644+
5645+
Assert(IsA(v, Float));
5646+
if (*oldval =='+')
5647+
oldval++;
5648+
if (*oldval =='-')
5649+
v->val.str = oldval;/* just strip the '-'*/
5650+
else
5651+
{
5652+
char *newval = (char *)palloc(strlen(oldval) +2);
5653+
5654+
*newval ='-';
5655+
strcpy(newval+1, oldval);
5656+
v->val.str = newval;
5657+
}
5658+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp