Skip to content

Commit d35a1af

Browse files
committed
Convert range_in and multirange_in to report errors softly.
This is mostly straightforward, except that if the range type has a canonical function, that might throw an error during range input. (Such errors probably only occur for edge cases: in the in-core canonical functions, it happens only if a bound has the maximum valid value for the underlying type.) Hence, this patch extends the soft-error regime to allow canonical functions to return errors softly as well. Extensions implementing range canonical functions will need modification anyway because of the API change for range_serialize(); while at it, they might want to do something similar to what's been done here in the in-core canonical functions. Discussion: https://postgr.es/m/3284599.1671075185@sss.pgh.pa.us
1 parent 75f4922 commit d35a1af

File tree

12 files changed

+289
-66
lines changed

12 files changed

+289
-66
lines changed

src/backend/utils/adt/multirangetypes.c

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ multirange_in(PG_FUNCTION_ARGS)
120120
char *input_str = PG_GETARG_CSTRING(0);
121121
Oid mltrngtypoid = PG_GETARG_OID(1);
122122
Oid typmod = PG_GETARG_INT32(2);
123+
Node *escontext = fcinfo->context;
123124
TypeCacheEntry *rangetyp;
124125
int32 ranges_seen = 0;
125126
int32 range_count = 0;
@@ -133,6 +134,7 @@ multirange_in(PG_FUNCTION_ARGS)
133134
const char *range_str_begin = NULL;
134135
int32 range_str_len;
135136
char *range_str;
137+
Datum range_datum;
136138

137139
cache = get_multirange_io_data(fcinfo, mltrngtypoid, IOFunc_input);
138140
rangetyp = cache->typcache->rngtype;
@@ -144,7 +146,7 @@ multirange_in(PG_FUNCTION_ARGS)
144146
if (*ptr == '{')
145147
ptr++;
146148
else
147-
ereport(ERROR,
149+
ereturn(escontext, (Datum) 0,
148150
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
149151
errmsg("malformed multirange literal: \"%s\"",
150152
input_str),
@@ -157,7 +159,7 @@ multirange_in(PG_FUNCTION_ARGS)
157159
char ch = *ptr;
158160

159161
if (ch == '\0')
160-
ereport(ERROR,
162+
ereturn(escontext, (Datum) 0,
161163
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
162164
errmsg("malformed multirange literal: \"%s\"",
163165
input_str),
@@ -186,7 +188,7 @@ multirange_in(PG_FUNCTION_ARGS)
186188
parse_state = MULTIRANGE_AFTER_RANGE;
187189
}
188190
else
189-
ereport(ERROR,
191+
ereturn(escontext, (Datum) 0,
190192
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
191193
errmsg("malformed multirange literal: \"%s\"",
192194
input_str),
@@ -204,10 +206,14 @@ multirange_in(PG_FUNCTION_ARGS)
204206
repalloc(ranges, range_capacity * sizeof(RangeType *));
205207
}
206208
ranges_seen++;
207-
range = DatumGetRangeTypeP(InputFunctionCall(&cache->typioproc,
208-
range_str,
209-
cache->typioparam,
210-
typmod));
209+
if (!InputFunctionCallSafe(&cache->typioproc,
210+
range_str,
211+
cache->typioparam,
212+
typmod,
213+
escontext,
214+
&range_datum))
215+
PG_RETURN_NULL();
216+
range = DatumGetRangeTypeP(range_datum);
211217
if (!RangeIsEmpty(range))
212218
ranges[range_count++] = range;
213219
parse_state = MULTIRANGE_AFTER_RANGE;
@@ -256,7 +262,7 @@ multirange_in(PG_FUNCTION_ARGS)
256262
else if (ch == '}')
257263
parse_state = MULTIRANGE_FINISHED;
258264
else
259-
ereport(ERROR,
265+
ereturn(escontext, (Datum) 0,
260266
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
261267
errmsg("malformed multirange literal: \"%s\"",
262268
input_str),
@@ -280,7 +286,7 @@ multirange_in(PG_FUNCTION_ARGS)
280286
ptr++;
281287

282288
if (*ptr != '\0')
283-
ereport(ERROR,
289+
ereturn(escontext, (Datum) 0,
284290
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
285291
errmsg("malformed multirange literal: \"%s\"",
286292
input_str),
@@ -807,7 +813,7 @@ multirange_get_union_range(TypeCacheEntry *rangetyp,
807813
multirange_get_bounds(rangetyp, mr, 0, &lower, &tmp);
808814
multirange_get_bounds(rangetyp, mr, mr->rangeCount - 1, &tmp, &upper);
809815

810-
return make_range(rangetyp, &lower, &upper, false);
816+
return make_range(rangetyp, &lower, &upper, false, NULL);
811817
}
812818

813819

@@ -2696,7 +2702,8 @@ range_merge_from_multirange(PG_FUNCTION_ARGS)
26962702
multirange_get_bounds(typcache->rngtype, mr, mr->rangeCount - 1,
26972703
&lastLower, &lastUpper);
26982704

2699-
result = make_range(typcache->rngtype, &firstLower, &lastUpper, false);
2705+
result = make_range(typcache->rngtype, &firstLower, &lastUpper,
2706+
false, NULL);
27002707
}
27012708

27022709
PG_RETURN_RANGE_P(result);

src/backend/utils/adt/multirangetypes_selfuncs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,8 @@ multirangesel(PG_FUNCTION_ARGS)
221221
upper.val = ((Const *) other)->constvalue;
222222
upper.infinite = false;
223223
upper.lower = false;
224-
constrange = range_serialize(typcache->rngtype, &lower, &upper, false);
224+
constrange = range_serialize(typcache->rngtype, &lower, &upper,
225+
false, NULL);
225226
constmultirange = make_multirange(typcache->type_id, typcache->rngtype,
226227
1, &constrange);
227228
}

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