Skip to content

Commit 33dd895

Browse files
committed
Introduce float4in_internal
This is the guts of float4in, callable as a routine to input floats, which will be useful in an upcoming patch for allowing soft errors in the seg module's input function. A similar operation was performed some years ago for float8in in commit 50861cd. Reviewed by Tom Lane Discussion: https://postgr.es/m/cee4e426-d014-c0b7-aa22-a659f2cd9130@dunslane.net
1 parent eb706fd commit 33dd895

File tree

2 files changed

+45
-15
lines changed

2 files changed

+45
-15
lines changed

src/backend/utils/adt/float.c

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -163,17 +163,35 @@ Datum
163163
float4in(PG_FUNCTION_ARGS)
164164
{
165165
char *num = PG_GETARG_CSTRING(0);
166-
Node *escontext = fcinfo->context;
167-
char *orig_num;
166+
167+
PG_RETURN_FLOAT4(float4in_internal(num, NULL, "real", num,
168+
fcinfo->context));
169+
}
170+
171+
/*
172+
* float4in_internal - guts of float4in()
173+
*
174+
* This is exposed for use by functions that want a reasonably
175+
* platform-independent way of inputting floats. The behavior is
176+
* essentially like strtof + ereturn on error.
177+
*
178+
* Uses the same API as float8in_internal below, so most of its
179+
* comments also apply here, except regarding use in geometric types.
180+
*/
181+
float4
182+
float4in_internal(char *num, char **endptr_p,
183+
const char *type_name, const char *orig_string,
184+
struct Node *escontext)
185+
{
168186
float val;
169187
char *endptr;
170188

171189
/*
172190
* endptr points to the first character _after_ the sequence we recognized
173-
* as a valid floating point number. orig_num points to the original input
191+
* as a valid floating point number. orig_string points to the original
192+
* input
174193
* string.
175194
*/
176-
orig_num = num;
177195

178196
/* skip leading whitespace */
179197
while (*num != '\0' && isspace((unsigned char) *num))
@@ -184,10 +202,10 @@ float4in(PG_FUNCTION_ARGS)
184202
* strtod() on different platforms.
185203
*/
186204
if (*num == '\0')
187-
ereturn(escontext, (Datum) 0,
205+
ereturn(escontext, 0,
188206
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
189207
errmsg("invalid input syntax for type %s: \"%s\"",
190-
"real", orig_num)));
208+
type_name, orig_string)));
191209

192210
errno = 0;
193211
val = strtof(num, &endptr);
@@ -258,30 +276,39 @@ float4in(PG_FUNCTION_ARGS)
258276
(val >= HUGE_VALF || val <= -HUGE_VALF)
259277
#endif
260278
)
261-
ereturn(escontext, (Datum) 0,
279+
{
280+
/* see comments in float8in_internal for rationale */
281+
char *errnumber = pstrdup(num);
282+
283+
errnumber[endptr - num] = '\0';
284+
285+
ereturn(escontext, 0,
262286
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
263287
errmsg("\"%s\" is out of range for type real",
264-
orig_num)));
288+
errnumber)));
289+
}
265290
}
266291
else
267-
ereturn(escontext, (Datum) 0,
292+
ereturn(escontext, 0,
268293
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
269294
errmsg("invalid input syntax for type %s: \"%s\"",
270-
"real", orig_num)));
295+
type_name, orig_string)));
271296
}
272297

273298
/* skip trailing whitespace */
274299
while (*endptr != '\0' && isspace((unsigned char) *endptr))
275300
endptr++;
276301

277-
/* if there is any junk left at the end of the string, bail out */
278-
if (*endptr != '\0')
279-
ereturn(escontext, (Datum) 0,
302+
/* report stopping point if wanted, else complain if not end of string */
303+
if (endptr_p)
304+
*endptr_p = endptr;
305+
else if (*endptr != '\0')
306+
ereturn(escontext, 0,
280307
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
281308
errmsg("invalid input syntax for type %s: \"%s\"",
282-
"real", orig_num)));
309+
type_name, orig_string)));
283310

284-
PG_RETURN_FLOAT4(val);
311+
return val;
285312
}
286313

287314
/*

src/include/utils/float.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ extern int is_infinite(float8 val);
4444
extern float8 float8in_internal(char *num, char **endptr_p,
4545
const char *type_name, const char *orig_string,
4646
struct Node *escontext);
47+
extern float4 float4in_internal(char *num, char **endptr_p,
48+
const char *type_name, const char *orig_string,
49+
struct Node *escontext);
4750
extern char *float8out_internal(float8 num);
4851
extern int float4_cmp_internal(float4 a, float4 b);
4952
extern int float8_cmp_internal(float8 a, float8 b);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy