Skip to content

Commit

Permalink
Do transaction checks before SPI call
Browse files Browse the repository at this point in the history
  • Loading branch information
staticlibs authored and fabriziomello committed Jan 7, 2025
1 parent 300e737 commit 54c7e6a
Showing 1 changed file with 14 additions and 14 deletions.
28 changes: 14 additions & 14 deletions tsl/src/continuous_aggs/refresh.c
Original file line number Diff line number Diff line change
Expand Up @@ -768,13 +768,24 @@ continuous_agg_refresh_internal(const ContinuousAgg *cagg,
bool nonatomic = ts_process_utility_is_context_nonatomic();

/* Reset the saved ProcessUtilityContext value promptly before
* calling PreventCommandIfReadOnly so the potential unsupported
* (atomic) value won't linger there in case of ereport exit.
* calling Prevent* checks so the potential unsupported (atomic)
* value won't linger there in case of ereport exit.
*/
ts_process_utility_context_reset();

PreventCommandIfReadOnly(REFRESH_FUNCTION_NAME);

/* Prevent running refresh if we're in a transaction block since a refresh
* can run two transactions and might take a long time to release locks if
* there's a lot to materialize. Strictly, it is optional to prohibit
* transaction blocks since there will be only one transaction if the
* invalidation threshold needs no update. However, materialization might
* still take a long time and it is probably best for consistency to always
* prevent transaction blocks. */
PreventInTransactionBlock(nonatomic, REFRESH_FUNCTION_NAME);

/* Connect to SPI manager due to the underlying SPI calls */
int rc = SPI_connect_ext(nonatomic ? SPI_OPT_NONATOMIC : 0);
int rc = SPI_connect_ext(SPI_OPT_NONATOMIC);
if (rc != SPI_OK_CONNECT)
elog(ERROR, "SPI_connect failed: %s", SPI_result_code_string(rc));

Expand All @@ -788,17 +799,6 @@ continuous_agg_refresh_internal(const ContinuousAgg *cagg,
get_relkind_objtype(get_rel_relkind(cagg->relid)),
get_rel_name(cagg->relid));

PreventCommandIfReadOnly(REFRESH_FUNCTION_NAME);

/* Prevent running refresh if we're in a transaction block since a refresh
* can run two transactions and might take a long time to release locks if
* there's a lot to materialize. Strictly, it is optional to prohibit
* transaction blocks since there will be only one transaction if the
* invalidation threshold needs no update. However, materialization might
* still take a long time and it is probably best for consistency to always
* prevent transaction blocks. */
PreventInTransactionBlock(nonatomic, REFRESH_FUNCTION_NAME);

/* No bucketing when open ended */
if (!(start_isnull && end_isnull))
{
Expand Down

0 comments on commit 54c7e6a

Please sign in to comment.