cockroachdb / cockroachdb/cockroach

sql,plpgsql: RAISE statements prevent automatic retries

Open
#119,632 4 comments 0 reactions 0 assignees View on GitHub
A-sql-plpgsql C-bug T-sql-queries
Dominant language
Go
Stars
32.5k
Forks
4.1k
PR merge metrics
PR metrics pending

Description

When a PL/pgSQL RAISE statement is executed, its message is immediately flushed to the client in order to mirror postgres behavior. However, this interferes with transaction retries, because the transaction can no longer be automatically retried once results have been flushed to the client. This is demonstrated by this test:
```
CREATE SEQUENCE s1;
CREATE SEQUENCE s2;

CREATE PROCEDURE p_no_raise() LANGUAGE PLpgSQL AS $$
BEGIN
SELECT IF(nextval('s1')<3, crdb_internal.force_retry('1h':::INTERVAL), 0);
END
$$;

CREATE PROCEDURE p_raise() LANGUAGE PLpgSQL AS $$
BEGIN
RAISE NOTICE 'foo';
SELECT IF(nextval('s2')<3, crdb_internal.force_retry('1h':::INTERVAL), 0);
END
$$;

root@localhost:26257/defaultdb> CALL p_no_raise();
CALL

Time: 39ms total (execution 39ms / network 0ms)

root@localhost:26257/defaultdb> CALL p_raise();
NOTICE: foo
ERROR: restart transaction: crdb_internal.force_retry(): TransactionRetryWithProtoRefreshError: forced by crdb_internal.force_retry()
SQLSTATE: 40001
HINT: See: https://www.cockroachlabs.com/docs/v24.1/transaction-retry-error-reference.html
```
We probably don't want to start buffering notices until the client connection is closed, since that changes the behavior of RAISE statements and makes them less useful. We could avoid updating `flushInfo.lastFlushed` for notices, and that would allow retries again. However, that would mean that the client would see messages from the old, restarted transactions. Another possibility is to offer a setting that would change the behavior to buffering.

Notably, this limitation applies to read committed retries as well as serializable.

Jira issue: CRDB-36215

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.