Skip to content

Commit

Permalink
plpgsql: add execution support for OPEN statements
Browse files Browse the repository at this point in the history
This patch adds support for executing PLpgSQL OPEN statements, which
open a SQL cursor in the current transaction. The name of the cursor
is supplied through a PLpgSQL variable. Since the `REFCURSOR` type
hasn't been implemented yet, this patch uses `STRING` in the
meantime.

Limitations that will be lifted in future PRs:
1. Unnamed cursor declarations are not supported. If a cursor is opened
   with no name supplied, a name should be automatically generated.
2. Bound cursors are not yet supported. It should be possible to declare
   a cursor in the `DECLARE` block with the query already defined, at
   which point it can be opened with `OPEN <cursor>;`.
3. A cursor cannot be opened in a routine with an exception block. This
   is because correct handling of this case is waiting on separate work
   to implement rollback of changes to database state on exceptions.

Informs cockroachdb#109709

Release note (sql change): Added initial support for executing the
PLpgSQL `OPEN` statement, which allows a PLpgSQL routine to create a
cursor. Currently, opening bound or unnamed cursors is not supported.
In addition, `OPEN` statements cannot be used in a routine with an
exception block.
  • Loading branch information
DrewKimball committed Sep 26, 2023
1 parent c7dd314 commit 24d184a
Show file tree
Hide file tree
Showing 22 changed files with 963 additions and 23 deletions.
7 changes: 7 additions & 0 deletions pkg/ccl/logictestccl/tests/3node-tenant/generated_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 9 additions & 3 deletions pkg/sql/conn_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -1222,6 +1222,11 @@ func (ex *connExecutor) close(ctx context.Context, closeType closeType) {
ctx, &ex.extraTxnState.prepStmtsNamespaceMemAcc,
)

// Close all cursors.
if err := ex.extraTxnState.sqlCursors.closeAll(false /* errorOnWithHold */); err != nil {
log.Warningf(ctx, "error closing cursors: %v", err)
}

if closeType == normalClose {
// We'll cleanup the SQL txn by creating a non-retriable (commit:true) event.
// This event is guaranteed to be accepted in every state.
Expand Down Expand Up @@ -1278,9 +1283,6 @@ func (ex *connExecutor) close(ctx context.Context, closeType closeType) {
ctx, &ex.extraTxnState.prepStmtsNamespaceMemAcc,
)
ex.extraTxnState.prepStmtsNamespaceMemAcc.Close(ctx)
if err := ex.extraTxnState.sqlCursors.closeAll(false /* errorOnWithHold */); err != nil {
log.Warningf(ctx, "error closing cursors: %v", err)
}
}

if ex.sessionTracing.Enabled() {
Expand Down Expand Up @@ -3865,6 +3867,10 @@ func (ex *connExecutor) txnStateTransitionsApplyWrapper(
ex.extraTxnState.prepStmtsNamespaceAtTxnRewindPos.closeAllPortals(
ex.Ctx(), &ex.extraTxnState.prepStmtsNamespaceMemAcc,
)
// Close all cursors.
if err := ex.extraTxnState.sqlCursors.closeAll(false /* errorOnWithHold */); err != nil {
log.Warningf(ex.Ctx(), "error closing cursors: %v", err)
}
ex.resetPlanner(ex.Ctx(), &ex.planner, nil, ex.server.cfg.Clock.PhysicalTime())
case txnRestart:
// In addition to resetting the extraTxnState, the restart event may
Expand Down
Loading

0 comments on commit 24d184a

Please sign in to comment.