Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sql: allow cursor WITH HOLD inside of txn as long as it gets closed #94127

Merged
merged 1 commit into from
Dec 27, 2022

Conversation

rafiss
Copy link
Collaborator

@rafiss rafiss commented Dec 22, 2022

informs #77101

The DECLARE foo CURSOR WITH HOLD ... syntax is now supported in a limited fashion. Unlike PG's WITH HOLD, this version can only be executed in a transaction block still. If there are any open cursors that have WITH HOLD open at the time a transaction is commited, the COMMIT fails.

No release note, since there's not actually any new functionality.

Release note: None

@cockroach-teamcity
Copy link
Member

This change is Reviewable

Copy link
Member

@jordanlewis jordanlewis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, one code organization comment to please take a look at.

@@ -988,6 +989,12 @@ func (ex *connExecutor) commitSQLTransactionInternal(ctx context.Context) error
ctx, sp := tracing.EnsureChildSpan(ctx, ex.server.cfg.AmbientCtx.Tracer, "commit sql txn")
defer sp.Finish()

for n, c := range ex.extraTxnState.sqlCursors.list() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to put this logic nearby where we close all of the cursors, perhaps even inside of closeAll. You might need to pass a boolean to closeAll because we also use it on server shutdown, but I feel this would prevent future refactorings from "forgetting" to do this check.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also need one for rollback too right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, we'll need to make sure txnRollback and txnRestart transitions are handled too, but that seems fine

@otan
Copy link
Contributor

otan commented Dec 22, 2022

was gonna do this today, but thank you :')

@@ -45,6 +42,9 @@ func (p *planner) DeclareCursor(ctx context.Context, s *tree.DeclareCursor) (pla
name: s.String(),
constructor: func(ctx context.Context, p *planner) (_ planNode, _ error) {
if p.extendedEvalCtx.TxnImplicit {
if s.Hold {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this no-op? or do we have an internal limitation that cursors require txns?

otan=# declare a cursor with hold for select 1;
DECLARE CURSOR

also wonder if we should have separate issues numbers for this and the closeAll scenario below for telemetry purposes

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

by default, cursors require transactions (in PG too). with hold is special because it does not require a transaction, but that is the thing we don't support. no-oping would be confusing IMO, since the user may think that it was created successfully.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm fine with one issue personally, because the underlying limitation for both is "cannot use a WITH HOLD cursor outside of an explicit transaction. both places where we return the unimplemented error will be fixed at the same time.

@@ -1153,7 +1153,7 @@ func (ex *connExecutor) close(ctx context.Context, closeType closeType) {
ctx, &ex.extraTxnState.prepStmtsNamespaceMemAcc,
)
ex.extraTxnState.prepStmtsNamespaceMemAcc.Close(ctx)
ex.extraTxnState.sqlCursors.closeAll()
_ = ex.extraTxnState.sqlCursors.closeAll(false /* errorOnWithHold */)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we log any errors here just in case? same with below.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

The `DECLARE foo CURSOR WITH HOLD ...` syntax is now supported in a
limited fashion. Unlike PG's `WITH HOLD` this version can only be
executed in a transaction block still. If there are any open cursors
that have `WITH HOLD` open at the time a transaction is commited, the
COMMIT fails.

No release note, since there's not actually any new functionality.

Release note: None
@rafiss
Copy link
Collaborator Author

rafiss commented Dec 27, 2022

tftr!

bors r=otan

@craig
Copy link
Contributor

craig bot commented Dec 27, 2022

Build succeeded:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants