Skip to content

Commit f3afe9f

Browse files
committed
sql: harden logging logic in an error case
We just saw a sentry report where we hit a nil pointer with `planner.curPlan.instrumentationHelper` being nil when trying to log a statement. This happened after we hit an error in `handleAOST`, so we short-circuited "dispatch to execution engine" part, meaning that the plan is left uninitialized. Previously, in eac1971 we attempted to handle such scenarios by tracking a boolean indicating whether the dispatch has occurred, but in this case we marked the boolean "true" (meaning it has occurred), yet we short-circuited due to an error. This commit refactors how we ensure that the plan is initialized by simply checking whether the corresponding fields are set or not. In turn, this exposed the fact that we previously didn't unset `planner.curPlan` when resetting the planner, which is now fixed. I spent some time trying to come up with a repro but didn't succeed, so there is no regression test. Release note: None
1 parent 21f5b4f commit f3afe9f

File tree

2 files changed

+11
-20
lines changed

2 files changed

+11
-20
lines changed

pkg/sql/conn_executor_exec.go

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -693,11 +693,6 @@ func (ex *connExecutor) execStmtInOpenState(
693693
_ = p.FormatAstAsRedactableString(stmt.AST, p.extendedEvalCtx.Annotations)
694694
}
695695

696-
// This flag informs logging decisions.
697-
// Some statements are not dispatched to the execution engine and need
698-
// some special plan initialization for logging.
699-
dispatchToExecEngine := false
700-
701696
var logErr error
702697
defer func() {
703698
// Do not log if this is an eventTxnCommittedDueToDDL event. In that case,
@@ -707,10 +702,12 @@ func (ex *connExecutor) execStmtInOpenState(
707702
return
708703
}
709704

710-
// If we did not dispatch to the execution engine, we need to initialize
711-
// the plan here.
712-
if !dispatchToExecEngine {
705+
if p.curPlan.stmt == nil || p.curPlan.instrumentation == nil {
706+
// We short-circuited before we could initialize some fields that
707+
// are needed for logging, so do that here.
713708
p.curPlan.init(&p.stmt, &p.instrumentation)
709+
}
710+
if logErr == nil {
714711
if p, ok := retPayload.(payloadWithError); ok {
715712
logErr = p.errorCause()
716713
}
@@ -931,8 +928,6 @@ func (ex *connExecutor) execStmtInOpenState(
931928
return nil, nil, nil
932929
}
933930

934-
dispatchToExecEngine = true
935-
936931
// Check if we need to auto-commit the transaction due to DDL.
937932
if ev, payload := ex.maybeAutoCommitBeforeDDL(ctx, ast); ev != nil {
938933
return ev, payload, nil
@@ -1705,11 +1700,6 @@ func (ex *connExecutor) execStmtInOpenStateWithPausablePortal(
17051700
_ = p.FormatAstAsRedactableString(vars.stmt.AST, p.extendedEvalCtx.Annotations)
17061701
}
17071702

1708-
// This flag informs logging decisions.
1709-
// Some statements are not dispatched to the execution engine and need
1710-
// some special plan initialization for logging.
1711-
dispatchToExecEngine := false
1712-
17131703
defer processCleanupFunc(func() {
17141704
// Do not log if this is an eventTxnCommittedDueToDDL event. In that case,
17151705
// the transaction is committed, and the current statement is executed
@@ -1718,10 +1708,12 @@ func (ex *connExecutor) execStmtInOpenStateWithPausablePortal(
17181708
return
17191709
}
17201710

1721-
// If we did not dispatch to the execution engine, we need to initialize
1722-
// the plan here.
1723-
if !dispatchToExecEngine {
1711+
if p.curPlan.stmt == nil || p.curPlan.instrumentation == nil {
1712+
// We short-circuited before we could initialize some fields that
1713+
// are needed for logging, so do that here.
17241714
p.curPlan.init(&p.stmt, &p.instrumentation)
1715+
}
1716+
if vars.logErr == nil {
17251717
if p, ok := retPayload.(payloadWithError); ok {
17261718
vars.logErr = p.errorCause()
17271719
}
@@ -1975,8 +1967,6 @@ func (ex *connExecutor) execStmtInOpenStateWithPausablePortal(
19751967
return nil, nil, nil
19761968
}
19771969

1978-
dispatchToExecEngine = true
1979-
19801970
// Check if we need to auto-commit the transaction due to DDL.
19811971
if ev, payload := ex.maybeAutoCommitBeforeDDL(ctx, vars.ast); ev != nil {
19821972
return ev, payload, nil

pkg/sql/planner.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -941,6 +941,7 @@ func (p *planner) resetPlanner(
941941
p.txn = txn
942942
p.stmt = Statement{}
943943
p.instrumentation = instrumentationHelper{}
944+
p.curPlan = planTop{}
944945
p.monitor = plannerMon
945946
p.sessionMonitor = sessionMon
946947

0 commit comments

Comments
 (0)