mirror of
https://github.com/postgres/postgres.git
synced 2025-06-13 07:41:39 +03:00
PG_FINALLY
This gives an alternative way of catching exceptions, for the common case where the cleanup code is the same in the error and non-error cases. So instead of PG_TRY(); { ... code that might throw ereport(ERROR) ... } PG_CATCH(); { cleanup(); PG_RE_THROW(); } PG_END_TRY(); cleanup(); one can write PG_TRY(); { ... code that might throw ereport(ERROR) ... } PG_FINALLY(); { cleanup(); } PG_END_TRY(); Discussion: https://www.postgresql.org/message-id/flat/95a822c3-728b-af0e-d7e5-71890507ae0c%402ndquadrant.com
This commit is contained in:
@ -320,12 +320,10 @@ explain_ExecutorRun(QueryDesc *queryDesc, ScanDirection direction,
|
||||
prev_ExecutorRun(queryDesc, direction, count, execute_once);
|
||||
else
|
||||
standard_ExecutorRun(queryDesc, direction, count, execute_once);
|
||||
nesting_level--;
|
||||
}
|
||||
PG_CATCH();
|
||||
PG_FINALLY();
|
||||
{
|
||||
nesting_level--;
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
}
|
||||
@ -343,12 +341,10 @@ explain_ExecutorFinish(QueryDesc *queryDesc)
|
||||
prev_ExecutorFinish(queryDesc);
|
||||
else
|
||||
standard_ExecutorFinish(queryDesc);
|
||||
nesting_level--;
|
||||
}
|
||||
PG_CATCH();
|
||||
PG_FINALLY();
|
||||
{
|
||||
nesting_level--;
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
}
|
||||
|
@ -776,19 +776,14 @@ dblink_record_internal(FunctionCallInfo fcinfo, bool is_async)
|
||||
}
|
||||
}
|
||||
}
|
||||
PG_CATCH();
|
||||
PG_FINALLY();
|
||||
{
|
||||
/* if needed, close the connection to the database */
|
||||
if (freeconn)
|
||||
PQfinish(conn);
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
|
||||
/* if needed, close the connection to the database */
|
||||
if (freeconn)
|
||||
PQfinish(conn);
|
||||
|
||||
return (Datum) 0;
|
||||
}
|
||||
|
||||
@ -952,14 +947,11 @@ materializeResult(FunctionCallInfo fcinfo, PGconn *conn, PGresult *res)
|
||||
/* clean up and return the tuplestore */
|
||||
tuplestore_donestoring(tupstore);
|
||||
}
|
||||
|
||||
PQclear(res);
|
||||
}
|
||||
PG_CATCH();
|
||||
PG_FINALLY();
|
||||
{
|
||||
/* be sure to release the libpq result */
|
||||
PQclear(res);
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
}
|
||||
@ -1464,19 +1456,14 @@ dblink_exec(PG_FUNCTION_ARGS)
|
||||
errmsg("statement returning results not allowed")));
|
||||
}
|
||||
}
|
||||
PG_CATCH();
|
||||
PG_FINALLY();
|
||||
{
|
||||
/* if needed, close the connection to the database */
|
||||
if (freeconn)
|
||||
PQfinish(conn);
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
|
||||
/* if needed, close the connection to the database */
|
||||
if (freeconn)
|
||||
PQfinish(conn);
|
||||
|
||||
PG_RETURN_TEXT_P(sql_cmd_status);
|
||||
}
|
||||
|
||||
|
@ -180,14 +180,11 @@ plpython_to_hstore(PG_FUNCTION_ARGS)
|
||||
pcount = hstoreUniquePairs(pairs, pcount, &buflen);
|
||||
out = hstorePairs(pairs, pcount, buflen);
|
||||
}
|
||||
PG_CATCH();
|
||||
PG_FINALLY();
|
||||
{
|
||||
Py_DECREF(items);
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
|
||||
Py_DECREF(items);
|
||||
|
||||
PG_RETURN_POINTER(out);
|
||||
}
|
||||
|
@ -307,15 +307,12 @@ PLyMapping_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state)
|
||||
|
||||
out = pushJsonbValue(jsonb_state, WJB_END_OBJECT, NULL);
|
||||
}
|
||||
PG_CATCH();
|
||||
PG_FINALLY();
|
||||
{
|
||||
Py_DECREF(items);
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
|
||||
Py_DECREF(items);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -892,12 +892,10 @@ pgss_ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count,
|
||||
prev_ExecutorRun(queryDesc, direction, count, execute_once);
|
||||
else
|
||||
standard_ExecutorRun(queryDesc, direction, count, execute_once);
|
||||
nested_level--;
|
||||
}
|
||||
PG_CATCH();
|
||||
PG_FINALLY();
|
||||
{
|
||||
nested_level--;
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
}
|
||||
@ -915,12 +913,10 @@ pgss_ExecutorFinish(QueryDesc *queryDesc)
|
||||
prev_ExecutorFinish(queryDesc);
|
||||
else
|
||||
standard_ExecutorFinish(queryDesc);
|
||||
nested_level--;
|
||||
}
|
||||
PG_CATCH();
|
||||
PG_FINALLY();
|
||||
{
|
||||
nested_level--;
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
}
|
||||
@ -1007,12 +1003,10 @@ pgss_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
|
||||
standard_ProcessUtility(pstmt, queryString,
|
||||
context, params, queryEnv,
|
||||
dest, completionTag);
|
||||
nested_level--;
|
||||
}
|
||||
PG_CATCH();
|
||||
PG_FINALLY();
|
||||
{
|
||||
nested_level--;
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
|
||||
|
@ -555,15 +555,12 @@ createTrgmNFA(text *text_re, Oid collation,
|
||||
{
|
||||
trg = createTrgmNFAInternal(®ex, graph, rcontext);
|
||||
}
|
||||
PG_CATCH();
|
||||
PG_FINALLY();
|
||||
{
|
||||
pg_regfree(®ex);
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
|
||||
pg_regfree(®ex);
|
||||
|
||||
/* Clean up all the cruft we created */
|
||||
MemoryContextSwitchTo(oldcontext);
|
||||
MemoryContextDelete(tmpcontext);
|
||||
|
@ -631,15 +631,12 @@ pgfdw_report_error(int elevel, PGresult *res, PGconn *conn,
|
||||
message_context ? errcontext("%s", message_context) : 0,
|
||||
sql ? errcontext("remote SQL command: %s", sql) : 0));
|
||||
}
|
||||
PG_CATCH();
|
||||
PG_FINALLY();
|
||||
{
|
||||
if (clear)
|
||||
PQclear(res);
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
if (clear)
|
||||
PQclear(res);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -3155,15 +3155,11 @@ get_remote_estimate(const char *sql, PGconn *conn,
|
||||
startup_cost, total_cost, rows, width);
|
||||
if (n != 4)
|
||||
elog(ERROR, "could not interpret EXPLAIN output: \"%s\"", line);
|
||||
|
||||
PQclear(res);
|
||||
res = NULL;
|
||||
}
|
||||
PG_CATCH();
|
||||
PG_FINALLY();
|
||||
{
|
||||
if (res)
|
||||
PQclear(res);
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
}
|
||||
@ -3383,15 +3379,11 @@ fetch_more_data(ForeignScanState *node)
|
||||
|
||||
/* Must be EOF if we didn't get as many tuples as we asked for. */
|
||||
fsstate->eof_reached = (numrows < fsstate->fetch_size);
|
||||
|
||||
PQclear(res);
|
||||
res = NULL;
|
||||
}
|
||||
PG_CATCH();
|
||||
PG_FINALLY();
|
||||
{
|
||||
if (res)
|
||||
PQclear(res);
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
|
||||
@ -4404,15 +4396,11 @@ postgresAnalyzeForeignTable(Relation relation,
|
||||
if (PQntuples(res) != 1 || PQnfields(res) != 1)
|
||||
elog(ERROR, "unexpected result from deparseAnalyzeSizeSql query");
|
||||
*totalpages = strtoul(PQgetvalue(res, 0, 0), NULL, 10);
|
||||
|
||||
PQclear(res);
|
||||
res = NULL;
|
||||
}
|
||||
PG_CATCH();
|
||||
PG_FINALLY();
|
||||
{
|
||||
if (res)
|
||||
PQclear(res);
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
|
||||
@ -4925,16 +4913,11 @@ postgresImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid)
|
||||
|
||||
commands = lappend(commands, pstrdup(buf.data));
|
||||
}
|
||||
|
||||
/* Clean up */
|
||||
PQclear(res);
|
||||
res = NULL;
|
||||
}
|
||||
PG_CATCH();
|
||||
PG_FINALLY();
|
||||
{
|
||||
if (res)
|
||||
PQclear(res);
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
|
||||
|
@ -372,13 +372,11 @@ sepgsql_utility_command(PlannedStmt *pstmt,
|
||||
context, params, queryEnv,
|
||||
dest, completionTag);
|
||||
}
|
||||
PG_CATCH();
|
||||
PG_FINALLY();
|
||||
{
|
||||
sepgsql_context_info = saved_context_info;
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
sepgsql_context_info = saved_context_info;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -465,14 +465,11 @@ sepgsql_get_label(Oid classId, Oid objectId, int32 subId)
|
||||
{
|
||||
label = pstrdup(unlabeled);
|
||||
}
|
||||
PG_CATCH();
|
||||
PG_FINALLY();
|
||||
{
|
||||
freecon(unlabeled);
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
|
||||
freecon(unlabeled);
|
||||
}
|
||||
return label;
|
||||
}
|
||||
@ -600,13 +597,11 @@ sepgsql_mcstrans_in(PG_FUNCTION_ARGS)
|
||||
{
|
||||
result = pstrdup(raw_label);
|
||||
}
|
||||
PG_CATCH();
|
||||
PG_FINALLY();
|
||||
{
|
||||
freecon(raw_label);
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
freecon(raw_label);
|
||||
|
||||
PG_RETURN_TEXT_P(cstring_to_text(result));
|
||||
}
|
||||
@ -640,13 +635,11 @@ sepgsql_mcstrans_out(PG_FUNCTION_ARGS)
|
||||
{
|
||||
result = pstrdup(qual_label);
|
||||
}
|
||||
PG_CATCH();
|
||||
PG_FINALLY();
|
||||
{
|
||||
freecon(qual_label);
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
freecon(qual_label);
|
||||
|
||||
PG_RETURN_TEXT_P(cstring_to_text(result));
|
||||
}
|
||||
@ -851,13 +844,11 @@ exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId)
|
||||
|
||||
SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, context);
|
||||
}
|
||||
PG_CATCH();
|
||||
PG_FINALLY();
|
||||
{
|
||||
freecon(context);
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
freecon(context);
|
||||
}
|
||||
else if (errno == ENOENT)
|
||||
ereport(WARNING,
|
||||
@ -937,14 +928,11 @@ sepgsql_restorecon(PG_FUNCTION_ARGS)
|
||||
exec_object_restorecon(sehnd, AttributeRelationId);
|
||||
exec_object_restorecon(sehnd, ProcedureRelationId);
|
||||
}
|
||||
PG_CATCH();
|
||||
PG_FINALLY();
|
||||
{
|
||||
selabel_close(sehnd);
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
|
||||
selabel_close(sehnd);
|
||||
|
||||
PG_RETURN_BOOL(true);
|
||||
}
|
||||
|
@ -871,13 +871,11 @@ sepgsql_compute_create(const char *scontext,
|
||||
{
|
||||
result = pstrdup(ncontext);
|
||||
}
|
||||
PG_CATCH();
|
||||
PG_FINALLY();
|
||||
{
|
||||
freecon(ncontext);
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
freecon(ncontext);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -181,14 +181,11 @@ sepgsql_avc_unlabeled(void)
|
||||
{
|
||||
avc_unlabeled = MemoryContextStrdup(avc_mem_cxt, unlabeled);
|
||||
}
|
||||
PG_CATCH();
|
||||
PG_FINALLY();
|
||||
{
|
||||
freecon(unlabeled);
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
|
||||
freecon(unlabeled);
|
||||
}
|
||||
return avc_unlabeled;
|
||||
}
|
||||
|
Reference in New Issue
Block a user