Skip to content

Commit

Permalink
sql: preliminary executor logic for savepoints
Browse files Browse the repository at this point in the history
This commit introduces support for regular SQL savepoints in the
executor.

The following is supported:

- recognizing the SAVEPOINT / ROLLBACK TO SAVEPOINT / RELEASE
  SAVEPOINT statements even when the savepoint name is not
  "cockroach_restart".
- maintaining a list of current active savepoints, and detect
  when SAVEPOINT and RELEASE/ROLLBACK are mismatched.
- issue the `GetSavepoint()` / `RollbackToSavepoint()` /
  `ReleaseSavepoint()` API calls to the KV layers.
- enforce that `cockroarch_restart` (and retry savepoints in general)
  are not started "under" a regular savepoint.

What is not supported yet:

- Rejecting ROLLBACK after a DDL statement has executed successfully.
- ROLLBACK when the txn is aborted (i.e. after an error).

Release note (sql change): CockroachDB now provides
rudimentary (incomplete) and experimental support for SQL savepoints.

Release note (sql change): CockroachDB supports a new statement `SHOW
SAVEPOINT STATUS` which reveals the current stack of active
savepoints. This can be used to teach savepoint usage.
  • Loading branch information
knz committed Feb 5, 2020
1 parent 108cb3e commit 29a6460
Show file tree
Hide file tree
Showing 11 changed files with 786 additions and 129 deletions.
9 changes: 3 additions & 6 deletions pkg/sql/conn_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -2407,22 +2407,19 @@ func (sc *StatementCounters) incrementCount(ex *connExecutor, stmt tree.Statemen
case *tree.RollbackTransaction:
sc.TxnRollbackCount.Inc()
case *tree.Savepoint:
// TODO(knz): Sanitize this.
if err := ex.validateSavepointName(t.Name); err == nil {
if ex.isRestartSavepoint(t.Name) {
sc.RestartSavepointCount.Inc()
} else {
sc.SavepointCount.Inc()
}
case *tree.ReleaseSavepoint:
// TODO(knz): Sanitize this.
if err := ex.validateSavepointName(t.Savepoint); err == nil {
if ex.isRestartSavepoint(t.Savepoint) {
sc.ReleaseRestartSavepointCount.Inc()
} else {
sc.ReleaseSavepointCount.Inc()
}
case *tree.RollbackToSavepoint:
// TODO(knz): Sanitize this.
if err := ex.validateSavepointName(t.Savepoint); err == nil {
if ex.isRestartSavepoint(t.Savepoint) {
sc.RollbackToRestartSavepointCount.Inc()
} else {
sc.RollbackToSavepointCount.Inc()
Expand Down
2 changes: 2 additions & 0 deletions pkg/sql/conn_executor_exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -1026,6 +1026,8 @@ func (ex *connExecutor) runObserverStatement(
switch sqlStmt := stmt.AST.(type) {
case *tree.ShowTransactionStatus:
return ex.runShowTransactionState(ctx, res)
case *tree.ShowSavepointStatus:
return ex.runShowSavepointState(ctx, res)
case *tree.ShowSyntax:
return ex.runShowSyntax(ctx, sqlStmt.Statement, res)
case *tree.SetTracing:
Expand Down
Loading

0 comments on commit 29a6460

Please sign in to comment.