Skip to content

Commit eb1d453

Browse files
committed
Don't capture hard errors in with-clause parser
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 exhausting the error stack. This commit solves this by using checking the category of the thrown error and only allow errors in the data exception and the syntax errors and access rules violation 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 a4b2fb9 commit eb1d453

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed

.unreleased/pr_7893

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixes: #7893 Don't capture hard errors in with-clause parser

src/with_clause_parser.c

+22
Original file line numberDiff line numberDiff line change
@@ -161,12 +161,34 @@ parse_arg(WithClauseDefinition arg, DefElem *def)
161161

162162
Assert(OidIsValid(in_fn));
163163

164+
/*
165+
* We could use InputFunctionCallSafe() here but this is just supported
166+
* for PG16 and later, so we opt for checking if the failure is what we
167+
* expected and re-throwing the error otherwise.
168+
*/
164169
PG_TRY();
165170
{
166171
val = OidInputFunctionCall(in_fn, value, typIOParam, -1);
167172
}
168173
PG_CATCH();
169174
{
175+
const int sqlerrcode = geterrcode();
176+
/*
177+
* We can deal with the Data Exception category and in the Syntax
178+
* Error or Access Rule Violation category, but if the error is an
179+
* insufficient resources category, for example, an out of memory
180+
* error, we should just re-throw it.
181+
*
182+
* Errors in other categories are unlikely, but we cannot do anything
183+
* with them anyway, so just re-throw them as well.
184+
*/
185+
if (ERRCODE_TO_CATEGORY(sqlerrcode) != ERRCODE_DATA_EXCEPTION &&
186+
ERRCODE_TO_CATEGORY(sqlerrcode) != ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION)
187+
{
188+
PG_RE_THROW();
189+
}
190+
FlushErrorState();
191+
170192
Form_pg_type typetup;
171193
HeapTuple tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(arg.type_id));
172194
if (!HeapTupleIsValid(tup))

0 commit comments

Comments
 (0)