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

Commitcfc7191

Browse files
committed
Move scanint8() to numutils.c
Move scanint8() to numutils.c and rename to pg_strtoint64(). Wealready have a "16" and "32" version of that, and the code inside thefunctions was aligned, so this move makes all three versionsconsistent. The API is also changed to no longer provide the errorOKcase. Users that need the error checking can use strtoi64().Reviewed-by: John Naylor <john.naylor@enterprisedb.com>Discussion:https://www.postgresql.org/message-id/flat/b239564c-cad0-b23e-c57e-166d883cb97d@enterprisedb.com
1 parent291ec6e commitcfc7191

File tree

7 files changed

+104
-122
lines changed

7 files changed

+104
-122
lines changed

‎src/backend/parser/parse_node.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
#include"parser/parse_relation.h"
2727
#include"parser/parsetree.h"
2828
#include"utils/builtins.h"
29-
#include"utils/int8.h"
3029
#include"utils/lsyscache.h"
3130
#include"utils/syscache.h"
3231
#include"utils/varbit.h"
@@ -353,7 +352,6 @@ make_const(ParseState *pstate, A_Const *aconst)
353352
{
354353
Const*con;
355354
Datumval;
356-
int64val64;
357355
Oidtypeid;
358356
inttypelen;
359357
booltypebyval;
@@ -384,8 +382,15 @@ make_const(ParseState *pstate, A_Const *aconst)
384382
break;
385383

386384
caseT_Float:
385+
{
387386
/* could be an oversize integer as well as a float ... */
388-
if (scanint8(aconst->val.fval.fval, true,&val64))
387+
388+
int64val64;
389+
char*endptr;
390+
391+
errno=0;
392+
val64=strtoi64(aconst->val.fval.fval,&endptr,10);
393+
if (errno==0&&*endptr=='\0')
389394
{
390395
/*
391396
* It might actually fit in int32. Probably only INT_MIN can
@@ -425,6 +430,7 @@ make_const(ParseState *pstate, A_Const *aconst)
425430
typebyval= false;
426431
}
427432
break;
433+
}
428434

429435
caseT_Boolean:
430436
val=BoolGetDatum(boolVal(&aconst->val));

‎src/backend/replication/pgoutput/pgoutput.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
#include"replication/logicalproto.h"
2222
#include"replication/origin.h"
2323
#include"replication/pgoutput.h"
24-
#include"utils/int8.h"
2524
#include"utils/inval.h"
2625
#include"utils/lsyscache.h"
2726
#include"utils/memutils.h"
@@ -207,20 +206,23 @@ parse_output_parameters(List *options, PGOutputData *data)
207206
/* Check each param, whether or not we recognize it */
208207
if (strcmp(defel->defname,"proto_version")==0)
209208
{
210-
int64parsed;
209+
unsigned longparsed;
210+
char*endptr;
211211

212212
if (protocol_version_given)
213213
ereport(ERROR,
214214
(errcode(ERRCODE_SYNTAX_ERROR),
215215
errmsg("conflicting or redundant options")));
216216
protocol_version_given= true;
217217

218-
if (!scanint8(strVal(defel->arg), true,&parsed))
218+
errno=0;
219+
parsed=strtoul(strVal(defel->arg),&endptr,10);
220+
if (errno!=0||*endptr!='\0')
219221
ereport(ERROR,
220222
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
221223
errmsg("invalid proto_version")));
222224

223-
if (parsed>PG_UINT32_MAX||parsed<0)
225+
if (parsed>PG_UINT32_MAX)
224226
ereport(ERROR,
225227
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
226228
errmsg("proto_version \"%s\" out of range",

‎src/backend/utils/adt/int8.c

Lines changed: 2 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
#include"nodes/supportnodes.h"
2525
#include"optimizer/optimizer.h"
2626
#include"utils/builtins.h"
27-
#include"utils/int8.h"
2827

2928

3029
typedefstruct
@@ -45,99 +44,14 @@ typedef struct
4544
* Formatting and conversion routines.
4645
*---------------------------------------------------------*/
4746

48-
/*
49-
* scanint8 --- try to parse a string into an int8.
50-
*
51-
* If errorOK is false, ereport a useful error message if the string is bad.
52-
* If errorOK is true, just return "false" for bad input.
53-
*/
54-
bool
55-
scanint8(constchar*str,boolerrorOK,int64*result)
56-
{
57-
constchar*ptr=str;
58-
int64tmp=0;
59-
boolneg= false;
60-
61-
/*
62-
* Do our own scan, rather than relying on sscanf which might be broken
63-
* for long long.
64-
*
65-
* As INT64_MIN can't be stored as a positive 64 bit integer, accumulate
66-
* value as a negative number.
67-
*/
68-
69-
/* skip leading spaces */
70-
while (*ptr&&isspace((unsignedchar)*ptr))
71-
ptr++;
72-
73-
/* handle sign */
74-
if (*ptr=='-')
75-
{
76-
ptr++;
77-
neg= true;
78-
}
79-
elseif (*ptr=='+')
80-
ptr++;
81-
82-
/* require at least one digit */
83-
if (unlikely(!isdigit((unsignedchar)*ptr)))
84-
gotoinvalid_syntax;
85-
86-
/* process digits */
87-
while (*ptr&&isdigit((unsignedchar)*ptr))
88-
{
89-
int8digit= (*ptr++-'0');
90-
91-
if (unlikely(pg_mul_s64_overflow(tmp,10,&tmp))||
92-
unlikely(pg_sub_s64_overflow(tmp,digit,&tmp)))
93-
gotoout_of_range;
94-
}
95-
96-
/* allow trailing whitespace, but not other trailing chars */
97-
while (*ptr!='\0'&&isspace((unsignedchar)*ptr))
98-
ptr++;
99-
100-
if (unlikely(*ptr!='\0'))
101-
gotoinvalid_syntax;
102-
103-
if (!neg)
104-
{
105-
/* could fail if input is most negative number */
106-
if (unlikely(tmp==PG_INT64_MIN))
107-
gotoout_of_range;
108-
tmp=-tmp;
109-
}
110-
111-
*result=tmp;
112-
return true;
113-
114-
out_of_range:
115-
if (!errorOK)
116-
ereport(ERROR,
117-
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
118-
errmsg("value \"%s\" is out of range for type %s",
119-
str,"bigint")));
120-
return false;
121-
122-
invalid_syntax:
123-
if (!errorOK)
124-
ereport(ERROR,
125-
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
126-
errmsg("invalid input syntax for type %s: \"%s\"",
127-
"bigint",str)));
128-
return false;
129-
}
130-
13147
/* int8in()
13248
*/
13349
Datum
13450
int8in(PG_FUNCTION_ARGS)
13551
{
136-
char*str=PG_GETARG_CSTRING(0);
137-
int64result;
52+
char*num=PG_GETARG_CSTRING(0);
13853

139-
(void)scanint8(str, false,&result);
140-
PG_RETURN_INT64(result);
54+
PG_RETURN_INT64(pg_strtoint64(num));
14155
}
14256

14357

‎src/backend/utils/adt/numutils.c

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,90 @@ pg_strtoint32(const char *s)
325325
return0;/* keep compiler quiet */
326326
}
327327

328+
/*
329+
* Convert input string to a signed 64 bit integer.
330+
*
331+
* Allows any number of leading or trailing whitespace characters. Will throw
332+
* ereport() upon bad input format or overflow.
333+
*
334+
* NB: Accumulate input as a negative number, to deal with two's complement
335+
* representation of the most negative number, which can't be represented as a
336+
* positive number.
337+
*/
338+
int64
339+
pg_strtoint64(constchar*s)
340+
{
341+
constchar*ptr=s;
342+
int64tmp=0;
343+
boolneg= false;
344+
345+
/*
346+
* Do our own scan, rather than relying on sscanf which might be broken
347+
* for long long.
348+
*
349+
* As INT64_MIN can't be stored as a positive 64 bit integer, accumulate
350+
* value as a negative number.
351+
*/
352+
353+
/* skip leading spaces */
354+
while (*ptr&&isspace((unsignedchar)*ptr))
355+
ptr++;
356+
357+
/* handle sign */
358+
if (*ptr=='-')
359+
{
360+
ptr++;
361+
neg= true;
362+
}
363+
elseif (*ptr=='+')
364+
ptr++;
365+
366+
/* require at least one digit */
367+
if (unlikely(!isdigit((unsignedchar)*ptr)))
368+
gotoinvalid_syntax;
369+
370+
/* process digits */
371+
while (*ptr&&isdigit((unsignedchar)*ptr))
372+
{
373+
int8digit= (*ptr++-'0');
374+
375+
if (unlikely(pg_mul_s64_overflow(tmp,10,&tmp))||
376+
unlikely(pg_sub_s64_overflow(tmp,digit,&tmp)))
377+
gotoout_of_range;
378+
}
379+
380+
/* allow trailing whitespace, but not other trailing chars */
381+
while (*ptr!='\0'&&isspace((unsignedchar)*ptr))
382+
ptr++;
383+
384+
if (unlikely(*ptr!='\0'))
385+
gotoinvalid_syntax;
386+
387+
if (!neg)
388+
{
389+
/* could fail if input is most negative number */
390+
if (unlikely(tmp==PG_INT64_MIN))
391+
gotoout_of_range;
392+
tmp=-tmp;
393+
}
394+
395+
returntmp;
396+
397+
out_of_range:
398+
ereport(ERROR,
399+
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
400+
errmsg("value \"%s\" is out of range for type %s",
401+
s,"bigint")));
402+
403+
invalid_syntax:
404+
ereport(ERROR,
405+
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
406+
errmsg("invalid input syntax for type %s: \"%s\"",
407+
"bigint",s)));
408+
409+
return0;/* keep compiler quiet */
410+
}
411+
328412
/*
329413
* pg_itoa: converts a signed 16-bit integer to its string representation
330414
* and returns strlen(a).

‎src/bin/pgbench/pgbench.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -787,8 +787,8 @@ is_an_int(const char *str)
787787
/*
788788
* strtoint64 -- convert a string to 64-bit integer
789789
*
790-
* This function is a slightly modified version ofscanint8() from
791-
* src/backend/utils/adt/int8.c.
790+
* This function is a slightly modified version ofpg_strtoint64() from
791+
* src/backend/utils/adt/numutils.c.
792792
*
793793
* The function returns whether the conversion worked, and if so
794794
* "*result" is set to the result.

‎src/include/utils/builtins.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ extern intnamestrcmp(Name name, const char *str);
4646
externint32pg_atoi(constchar*s,intsize,intc);
4747
externint16pg_strtoint16(constchar*s);
4848
externint32pg_strtoint32(constchar*s);
49+
externint64pg_strtoint64(constchar*s);
4950
externintpg_itoa(int16i,char*a);
5051
externintpg_ultoa_n(uint32l,char*a);
5152
externintpg_ulltoa_n(uint64l,char*a);

‎src/include/utils/int8.h

Lines changed: 0 additions & 25 deletions
This file was deleted.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp