Skip to content

Commit 2452d33

Browse files
committed
sql: unify revoking portal pausability
Previously, we were revoking portal pausability in two spots: once for not-read-only stmts and separately if we find any sub- or post-queries. We can actually check both things right after having performed the logical planning, which unifies the code a bit. Release note: None
1 parent 56c2bbf commit 2452d33

File tree

1 file changed

+40
-49
lines changed

1 file changed

+40
-49
lines changed

pkg/sql/conn_executor_exec.go

Lines changed: 40 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2740,31 +2740,42 @@ func (ex *connExecutor) dispatchToExecutionEngine(
27402740
if ppInfo := getPausablePortalInfo(planner); ppInfo != nil {
27412741
if !ppInfo.dispatchToExecutionEngine.cleanup.isComplete {
27422742
ctx, err = ex.makeExecPlan(ctx, planner)
2743-
// TODO(janexing): This is a temporary solution to disallow procedure
2744-
// call statements that contain mutations for pausable portals. Since
2745-
// relational.CanMutate is not yet propagated from the function body
2746-
// via builder.BuildCall(), we must temporarily disallow all
2747-
// TCL statements, which includes the CALL statements.
2748-
// This should be removed once CanMutate is fully propagated.
2749-
// (pending https://github.com/cockroachdb/cockroach/issues/147568)
2750-
isTCL := planner.curPlan.stmt.AST.StatementType() == tree.TypeTCL
2751-
if flags := planner.curPlan.flags; err == nil && (isTCL || flags.IsSet(planFlagContainsMutation) || flags.IsSet(planFlagIsDDL)) {
2752-
telemetry.Inc(sqltelemetry.NotReadOnlyStmtsTriedWithPausablePortals)
2753-
// We don't allow mutations in a pausable portal. Set it back to
2754-
// an un-pausable (normal) portal.
2755-
planner.pausablePortal.pauseInfo = nil
2756-
err = res.RevokePortalPausability()
2757-
// If this plan is a transaction control statement, we don't
2758-
// even execute it but just early exit.
2759-
if isTCL {
2760-
err = errors.CombineErrors(err, ErrStmtNotSupportedForPausablePortal)
2743+
if err == nil {
2744+
// TODO(janexing): This is a temporary solution to disallow procedure
2745+
// call statements that contain mutations for pausable portals. Since
2746+
// relational.CanMutate is not yet propagated from the function body
2747+
// via builder.BuildCall(), we must temporarily disallow all
2748+
// TCL statements, which includes the CALL statements.
2749+
// This should be removed once CanMutate is fully propagated.
2750+
// (pending https://github.com/cockroachdb/cockroach/issues/147568)
2751+
isTCL := planner.curPlan.stmt.AST.StatementType() == tree.TypeTCL
2752+
// We don't allow mutations in a pausable portal.
2753+
notReadOnly := isTCL || planner.curPlan.flags.IsSet(planFlagContainsMutation) || planner.curPlan.flags.IsSet(planFlagIsDDL)
2754+
// We don't allow sub / post queries for pausable portal.
2755+
hasSubOrPostQuery := len(planner.curPlan.subqueryPlans) != 0 || len(planner.curPlan.cascades) != 0 ||
2756+
len(planner.curPlan.checkPlans) != 0 || len(planner.curPlan.triggers) != 0
2757+
if notReadOnly || hasSubOrPostQuery {
2758+
if notReadOnly {
2759+
telemetry.Inc(sqltelemetry.NotReadOnlyStmtsTriedWithPausablePortals)
2760+
} else {
2761+
telemetry.Inc(sqltelemetry.SubOrPostQueryStmtsTriedWithPausablePortals)
2762+
}
2763+
// This stmt is not supported via the pausable portals model
2764+
// - set it back to an un-pausable (normal) portal.
2765+
planner.pausablePortal.pauseInfo = nil
2766+
err = res.RevokePortalPausability()
2767+
// If this plan is a transaction control statement, we don't
2768+
// even execute it but just early exit.
2769+
if isTCL {
2770+
err = errors.CombineErrors(err, ErrStmtNotSupportedForPausablePortal)
2771+
}
2772+
defer planner.curPlan.close(ctx)
2773+
} else {
2774+
ppInfo.dispatchToExecutionEngine.planTop = planner.curPlan
2775+
ppInfo.dispatchToExecutionEngine.cleanup.appendFunc(func(ctx context.Context) {
2776+
ppInfo.dispatchToExecutionEngine.planTop.close(ctx)
2777+
})
27612778
}
2762-
defer planner.curPlan.close(ctx)
2763-
} else {
2764-
ppInfo.dispatchToExecutionEngine.planTop = planner.curPlan
2765-
ppInfo.dispatchToExecutionEngine.cleanup.appendFunc(func(ctx context.Context) {
2766-
ppInfo.dispatchToExecutionEngine.planTop.close(ctx)
2767-
})
27682779
}
27692780
} else {
27702781
planner.curPlan = ppInfo.dispatchToExecutionEngine.planTop
@@ -2820,31 +2831,11 @@ func (ex *connExecutor) dispatchToExecutionEngine(
28202831

28212832
var afterGetPlanDistribution func()
28222833
if getPausablePortalInfo(planner) != nil {
2823-
if len(planner.curPlan.subqueryPlans) == 0 &&
2824-
len(planner.curPlan.cascades) == 0 &&
2825-
len(planner.curPlan.checkPlans) == 0 &&
2826-
len(planner.curPlan.triggers) == 0 {
2827-
// We don't allow a distributed plan for pausable portals.
2828-
origDistSQLMode := ex.sessionData().DistSQLMode
2829-
ex.sessionData().DistSQLMode = sessiondatapb.DistSQLOff
2830-
afterGetPlanDistribution = func() {
2831-
ex.sessionData().DistSQLMode = origDistSQLMode
2832-
}
2833-
} else {
2834-
telemetry.Inc(sqltelemetry.SubOrPostQueryStmtsTriedWithPausablePortals)
2835-
// We don't allow sub / post queries for pausable portal. Set it back to an
2836-
// un-pausable (normal) portal.
2837-
// With pauseInfo is nil, no cleanup function will be added to the stack
2838-
// and all clean-up steps will be performed as for normal portals.
2839-
// TODO(#115887): We may need to move resetting pauseInfo before we add
2840-
// the pausable portal cleanup step above.
2841-
planner.pausablePortal.pauseInfo = nil
2842-
// We need this so that the result consumption for this portal cannot be
2843-
// paused either.
2844-
if err := res.RevokePortalPausability(); err != nil {
2845-
res.SetError(err)
2846-
return nil
2847-
}
2834+
// We don't allow a distributed plan for pausable portals.
2835+
origDistSQLMode := ex.sessionData().DistSQLMode
2836+
ex.sessionData().DistSQLMode = sessiondatapb.DistSQLOff
2837+
afterGetPlanDistribution = func() {
2838+
ex.sessionData().DistSQLMode = origDistSQLMode
28482839
}
28492840
}
28502841
distributePlan, distSQLProhibitedErr := planner.getPlanDistribution(ctx, planner.curPlan.main)

0 commit comments

Comments
 (0)