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

Commitccff2d2

Browse files
committed
Convert a few datatype input functions to use "soft" error reporting.
This patch converts the input functions for bool, int2, int4, int8,float4, float8, numeric, and contrib/cube to the new soft-error style.array_in and record_in are also converted. There's lots more to do,but this is enough to provide proof-of-concept that the soft-errorAPI is usable, as well as reference examples for how to convertinput functions.This patch is mostly by me, but it owes very substantial debt toearlier work by Nikita Glukhov, Andrew Dunstan, and Amul Sul.Thanks to Andres Freund for review.Discussion:https://postgr.es/m/3bbbb0df-7382-bf87-9737-340ba096e034@postgrespro.ru
1 parent1939d26 commitccff2d2

39 files changed

+727
-238
lines changed

‎contrib/cube/cube.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,9 @@ cube_in(PG_FUNCTION_ARGS)
123123

124124
cube_scanner_init(str,&scanbuflen);
125125

126-
cube_yyparse(&result,scanbuflen);
126+
cube_yyparse(&result,scanbuflen,fcinfo->context);
127127

128+
/* We might as well run this even on failure. */
128129
cube_scanner_finish();
129130

130131
PG_RETURN_NDBOX_P(result);

‎contrib/cube/cubedata.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,12 @@ typedef struct NDBOX
6161

6262
/* in cubescan.l */
6363
externintcube_yylex(void);
64-
externvoidcube_yyerror(NDBOX**result,Sizescanbuflen,constchar*message)pg_attribute_noreturn();
64+
externvoidcube_yyerror(NDBOX**result,Sizescanbuflen,
65+
structNode*escontext,
66+
constchar*message);
6567
externvoidcube_scanner_init(constchar*str,Size*scanbuflen);
6668
externvoidcube_scanner_finish(void);
6769

6870
/* in cubeparse.y */
69-
externintcube_yyparse(NDBOX**result,Sizescanbuflen);
71+
externintcube_yyparse(NDBOX**result,Sizescanbuflen,
72+
structNode*escontext);

‎contrib/cube/cubeparse.y

Lines changed: 52 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include"postgres.h"
88

99
#include"cubedata.h"
10+
#include"nodes/miscnodes.h"
1011
#include"utils/float.h"
1112

1213
/* All grammar constructs return strings*/
@@ -21,14 +22,17 @@
2122
#defineYYFREE pfree
2223

2324
staticintitem_count(constchar *s,char delim);
24-
static NDBOX *write_box(int dim,char *str1,char *str2);
25-
static NDBOX *write_point_as_box(int dim,char *str);
25+
staticboolwrite_box(int dim,char *str1,char *str2,
26+
NDBOX **result,structNode *escontext);
27+
staticboolwrite_point_as_box(int dim,char *str,
28+
NDBOX **result,structNode *escontext);
2629

2730
%}
2831

2932
/* BISON Declarations*/
3033
%parse-param {NDBOX **result}
3134
%parse-param {Size scanbuflen}
35+
%parse-param {structNode *escontext}
3236
%expect0
3337
%name-prefix="cube_yy"
3438

@@ -45,7 +49,7 @@ box: O_BRACKET paren_list COMMA paren_list C_BRACKET
4549
dim =item_count($2,',');
4650
if (item_count($4,',') != dim)
4751
{
48-
ereport(ERROR,
52+
errsave(escontext,
4953
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
5054
errmsg("invalid input syntax for cube"),
5155
errdetail("Different point dimensions in (%s) and (%s).",
@@ -54,15 +58,16 @@ box: O_BRACKET paren_list COMMA paren_list C_BRACKET
5458
}
5559
if (dim > CUBE_MAX_DIM)
5660
{
57-
ereport(ERROR,
61+
errsave(escontext,
5862
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
5963
errmsg("invalid input syntax for cube"),
6064
errdetail("A cube cannot have more than %d dimensions.",
6165
CUBE_MAX_DIM)));
6266
YYABORT;
6367
}
6468

65-
*result = write_box( dim,$2,$4 );
69+
if (!write_box(dim, $2, $4, result, escontext))
70+
YYABORT;
6671
}
6772

6873
| paren_list COMMA paren_list
@@ -72,7 +77,7 @@ box: O_BRACKET paren_list COMMA paren_list C_BRACKET
7277
dim =item_count($1,',');
7378
if (item_count($3,',') != dim)
7479
{
75-
ereport(ERROR,
80+
errsave(escontext,
7681
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
7782
errmsg("invalid input syntax for cube"),
7883
errdetail("Different point dimensions in (%s) and (%s).",
@@ -81,15 +86,16 @@ box: O_BRACKET paren_list COMMA paren_list C_BRACKET
8186
}
8287
if (dim > CUBE_MAX_DIM)
8388
{
84-
ereport(ERROR,
89+
errsave(escontext,
8590
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
8691
errmsg("invalid input syntax for cube"),
8792
errdetail("A cube cannot have more than %d dimensions.",
8893
CUBE_MAX_DIM)));
8994
YYABORT;
9095
}
9196

92-
*result = write_box( dim,$1,$3 );
97+
if (!write_box(dim, $1, $3, result, escontext))
98+
YYABORT;
9399
}
94100

95101
| paren_list
@@ -99,15 +105,16 @@ box: O_BRACKET paren_list COMMA paren_list C_BRACKET
99105
dim =item_count($1,',');
100106
if (dim > CUBE_MAX_DIM)
101107
{
102-
ereport(ERROR,
108+
errsave(escontext,
103109
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
104110
errmsg("invalid input syntax for cube"),
105111
errdetail("A cube cannot have more than %d dimensions.",
106112
CUBE_MAX_DIM)));
107113
YYABORT;
108114
}
109115

110-
*result = write_point_as_box(dim,$1);
116+
if (!write_point_as_box(dim, $1, result, escontext))
117+
YYABORT;
111118
}
112119

113120
| list
@@ -117,15 +124,16 @@ box: O_BRACKET paren_list COMMA paren_list C_BRACKET
117124
dim =item_count($1,',');
118125
if (dim > CUBE_MAX_DIM)
119126
{
120-
ereport(ERROR,
127+
errsave(escontext,
121128
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
122129
errmsg("invalid input syntax for cube"),
123130
errdetail("A cube cannot have more than %d dimensions.",
124131
CUBE_MAX_DIM)));
125132
YYABORT;
126133
}
127134

128-
*result = write_point_as_box(dim,$1);
135+
if (!write_point_as_box(dim, $1, result, escontext))
136+
YYABORT;
129137
}
130138
;
131139

@@ -173,8 +181,9 @@ item_count(const char *s, char delim)
173181
return nitems;
174182
}
175183

176-
static NDBOX *
177-
write_box(int dim,char *str1,char *str2)
184+
staticbool
185+
write_box(int dim,char *str1,char *str2,
186+
NDBOX **result,structNode *escontext)
178187
{
179188
NDBOX *bp;
180189
char *s;
@@ -190,26 +199,36 @@ write_box(int dim, char *str1, char *str2)
190199
s = str1;
191200
i =0;
192201
if (dim >0)
193-
bp->x[i++] =float8in_internal(s, &endptr,"cube", str1);
202+
{
203+
bp->x[i++] =float8in_internal(s, &endptr,"cube", str1, escontext);
204+
if (SOFT_ERROR_OCCURRED(escontext))
205+
returnfalse;
206+
}
194207
while ((s =strchr(s,',')) !=NULL)
195208
{
196209
s++;
197-
bp->x[i++] =float8in_internal(s, &endptr,"cube", str1);
210+
bp->x[i++] =float8in_internal(s, &endptr,"cube", str1, escontext);
211+
if (SOFT_ERROR_OCCURRED(escontext))
212+
returnfalse;
198213
}
199214
Assert(i == dim);
200215

201216
s = str2;
202217
if (dim >0)
203218
{
204-
bp->x[i] =float8in_internal(s, &endptr,"cube", str2);
219+
bp->x[i] =float8in_internal(s, &endptr,"cube", str2, escontext);
220+
if (SOFT_ERROR_OCCURRED(escontext))
221+
returnfalse;
205222
/* code this way to do right thing with NaN*/
206223
point &= (bp->x[i] == bp->x[0]);
207224
i++;
208225
}
209226
while ((s =strchr(s,',')) !=NULL)
210227
{
211228
s++;
212-
bp->x[i] =float8in_internal(s, &endptr,"cube", str2);
229+
bp->x[i] =float8in_internal(s, &endptr,"cube", str2, escontext);
230+
if (SOFT_ERROR_OCCURRED(escontext))
231+
returnfalse;
213232
point &= (bp->x[i] == bp->x[i - dim]);
214233
i++;
215234
}
@@ -229,11 +248,13 @@ write_box(int dim, char *str1, char *str2)
229248
SET_POINT_BIT(bp);
230249
}
231250

232-
return bp;
251+
*result = bp;
252+
returntrue;
233253
}
234254

235-
static NDBOX *
236-
write_point_as_box(int dim,char *str)
255+
staticbool
256+
write_point_as_box(int dim,char *str,
257+
NDBOX **result,structNode *escontext)
237258
{
238259
NDBOX*bp;
239260
inti,
@@ -250,13 +271,20 @@ write_point_as_box(int dim, char *str)
250271
s = str;
251272
i =0;
252273
if (dim >0)
253-
bp->x[i++] =float8in_internal(s, &endptr,"cube", str);
274+
{
275+
bp->x[i++] =float8in_internal(s, &endptr,"cube", str, escontext);
276+
if (SOFT_ERROR_OCCURRED(escontext))
277+
returnfalse;
278+
}
254279
while ((s =strchr(s,',')) !=NULL)
255280
{
256281
s++;
257-
bp->x[i++] =float8in_internal(s, &endptr,"cube", str);
282+
bp->x[i++] =float8in_internal(s, &endptr,"cube", str, escontext);
283+
if (SOFT_ERROR_OCCURRED(escontext))
284+
returnfalse;
258285
}
259286
Assert(i == dim);
260287

261-
return bp;
288+
*result = bp;
289+
returntrue;
262290
}

‎contrib/cube/cubescan.l

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,19 +72,21 @@ NaN [nN][aA][nN]
7272

7373
/* result and scanbuflen are not used, but Bison expects this signature */
7474
void
75-
cube_yyerror(NDBOX **result, Size scanbuflen,constchar *message)
75+
cube_yyerror(NDBOX **result, Size scanbuflen,
76+
structNode *escontext,
77+
constchar *message)
7678
{
7779
if (*yytext == YY_END_OF_BUFFER_CHAR)
7880
{
79-
ereport(ERROR,
81+
errsave(escontext,
8082
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
8183
errmsg("invalid input syntax for cube"),
8284
/* translator: %s is typically "syntax error" */
8385
errdetail("%s at end of input", message)));
8486
}
8587
else
8688
{
87-
ereport(ERROR,
89+
errsave(escontext,
8890
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
8991
errmsg("invalid input syntax for cube"),
9092
/* translator: first %s is typically "syntax error" */

‎contrib/cube/expected/cube.out

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,31 @@ SELECT '-1e-700'::cube AS cube; -- out of range
325325
ERROR: "-1e-700" is out of range for type double precision
326326
LINE 1: SELECT '-1e-700'::cube AS cube;
327327
^
328+
-- Also try it with non-error-throwing API
329+
SELECT pg_input_is_valid('(1,2)', 'cube');
330+
pg_input_is_valid
331+
-------------------
332+
t
333+
(1 row)
334+
335+
SELECT pg_input_is_valid('[(1),]', 'cube');
336+
pg_input_is_valid
337+
-------------------
338+
f
339+
(1 row)
340+
341+
SELECT pg_input_is_valid('-1e-700', 'cube');
342+
pg_input_is_valid
343+
-------------------
344+
f
345+
(1 row)
346+
347+
SELECT pg_input_error_message('-1e-700', 'cube');
348+
pg_input_error_message
349+
-----------------------------------------------------
350+
"-1e-700" is out of range for type double precision
351+
(1 row)
352+
328353
--
329354
-- Testing building cubes from float8 values
330355
--

‎contrib/cube/sql/cube.sql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@ SELECT '1,2a'::cube AS cube; -- 7
7979
SELECT'1..2'::cubeAS cube;-- 7
8080
SELECT'-1e-700'::cubeAS cube;-- out of range
8181

82+
-- Also try it with non-error-throwing API
83+
SELECT pg_input_is_valid('(1,2)','cube');
84+
SELECT pg_input_is_valid('[(1),]','cube');
85+
SELECT pg_input_is_valid('-1e-700','cube');
86+
SELECT pg_input_error_message('-1e-700','cube');
87+
8288
--
8389
-- Testing building cubes from float8 values
8490
--

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp