Skip to content

Commit d724332

Browse files
committed
Run input function allowing soft errors only
When parsing WITH clause arguments for ALTER TABLE to extract compression parameters, syntax errors in the text format are caught using PG_TRY and PG_CATCH and then returning an indication if the parse succeeded or not. If an out of memory error occurs inside execution of the input function and this error is caught, it can continue executing and potentially cause cascading out of memory errors and in the end exhausing the error stack. This commit solves this by using checking the category of the thrown error and only allow errors in the data exception category, which are "soft" errors in this case. Hard errors, like out-of-memory errors, are re-thrown allowing the backend to deal with it properly.
1 parent 23a1fd3 commit d724332

File tree

1 file changed

+23
-0
lines changed

1 file changed

+23
-0
lines changed

src/with_clause_parser.c

+23
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ parse_arg(WithClauseDefinition arg, DefElem *def)
140140
Datum val;
141141
Oid in_fn;
142142
Oid typIOParam;
143+
MemoryContext ccxt = CurrentMemoryContext;
143144

144145
if (!OidIsValid(arg.type_id))
145146
ereport(ERROR,
@@ -161,12 +162,34 @@ parse_arg(WithClauseDefinition arg, DefElem *def)
161162

162163
Assert(OidIsValid(in_fn));
163164

165+
/*
166+
* We could use InputFunctionCallSafe() here but this is just supported
167+
* for PG16 and later, so we opt for checking if the failure is what we
168+
* expected and re-throwing the error otherwise.
169+
*/
164170
PG_TRY();
165171
{
166172
val = OidInputFunctionCall(in_fn, value, typIOParam, -1);
167173
}
168174
PG_CATCH();
169175
{
176+
MemoryContext ecxt = MemoryContextSwitchTo(ccxt);
177+
ErrorData *edata = CopyErrorData();
178+
/*
179+
* All syntax errors are in the data exception category. These we can
180+
* deal with, but if the error is an insufficient resources category,
181+
* for example, an out of memory error, we should just re-throw it.
182+
*
183+
* Errors in other categories are unlikely, but we cannot do anything
184+
* with them anyway, so just re-throw them as well.
185+
*/
186+
if (ERRCODE_TO_CATEGORY(edata->sqlerrcode) != ERRCODE_DATA_EXCEPTION)
187+
{
188+
FreeErrorData(edata);
189+
MemoryContextSwitchTo(ecxt);
190+
PG_RE_THROW();
191+
}
192+
170193
Form_pg_type typetup;
171194
HeapTuple tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(arg.type_id));
172195
if (!HeapTupleIsValid(tup))

0 commit comments

Comments
 (0)