Skip to content

Commit

Permalink
sql: fix exec+audit logs for BEGIN, COMMIT, SET stmts
Browse files Browse the repository at this point in the history
Release note (bug fix): Fixed a bug where BEGIN, COMMIT, SET, ROLLBACK,
and SAVEPOINT statements would not be written to the execution or audit
logs.
  • Loading branch information
rafiss committed Aug 3, 2023
1 parent a14d6bb commit e85d1f4
Showing 1 changed file with 71 additions and 24 deletions.
95 changes: 71 additions & 24 deletions pkg/sql/conn_executor_exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -750,10 +750,75 @@ func (ex *connExecutor) execStmtInOpenState(
}
}(ctx)

// If adminAuditLogging is enabled, we want to check for HasAdminRole
// before maybeLogStatement.
// We must check prior to execution in the case the txn is aborted due to
// an error. HasAdminRole can only be checked in a valid txn.
if adminAuditLog := adminAuditLogEnabled.Get(
&ex.planner.execCfg.Settings.SV,
); adminAuditLog {
if !ex.extraTxnState.hasAdminRoleCache.IsSet {
hasAdminRole, err := ex.planner.HasAdminRole(ctx)
if err != nil {
return makeErrEvent(err)
}
ex.extraTxnState.hasAdminRoleCache.HasAdminRole = hasAdminRole
ex.extraTxnState.hasAdminRoleCache.IsSet = true
}
}

p.stmt = stmt
p.semaCtx.Annotations = tree.MakeAnnotations(stmt.NumAnnotations)
p.extendedEvalCtx.Annotations = &p.semaCtx.Annotations
if err := p.semaCtx.Placeholders.Assign(pinfo, stmt.NumPlaceholders); err != nil {
return makeErrEvent(err)
}
p.extendedEvalCtx.Placeholders = &p.semaCtx.Placeholders

shouldLog := true
defer func() {
if !shouldLog {
// We don't want to log this statement, since another layer of the
// conn_executor will handle the logging for this statement.
return
}
var execErr error
if p, ok := retPayload.(payloadWithError); ok {
execErr = p.errorCause()
}
f := tree.NewFmtCtx(tree.FmtHideConstants)
f.FormatNode(ast)
stmtFingerprintID := appstatspb.ConstructStatementFingerprintID(
f.CloseAndGetString(),
execErr != nil,
ex.implicitTxn(),
ex.planner.CurrentDatabase(),
)

p.maybeLogStatement(
ctx,
ex.executorType,
false, /* isCopy */
int(ex.state.mu.autoRetryCounter),
ex.extraTxnState.txnCounter,
0, /* rowsAffected */
ex.state.mu.stmtCount,
0, /* bulkJobId */
execErr,
ex.statsCollector.PhaseTimes().GetSessionPhaseTime(sessionphase.SessionQueryReceived),
&ex.extraTxnState.hasAdminRoleCache,
ex.server.TelemetryLoggingMetrics,
stmtFingerprintID,
&topLevelQueryStats{},
ex.statsCollector,
)
}()

switch s := ast.(type) {
case *tree.BeginTransaction:
// BEGIN is only allowed if we are in an implicit txn.
if os.ImplicitTxn.Get() {
shouldLog = false
// When executing the BEGIN, we also need to set any transaction modes
// that were specified on the BEGIN statement.
if _, err := ex.planner.SetTransaction(ctx, &tree.SetTransaction{Modes: s.Modes}); err != nil {
Expand All @@ -765,6 +830,9 @@ func (ex *connExecutor) execStmtInOpenState(
return makeErrEvent(errTransactionInProgress)

case *tree.CommitTransaction:
if os.ImplicitTxn.Get() {
shouldLog = false
}
// CommitTransaction is executed fully here; there's no plan for it.
ev, payload := ex.commitSQLTransaction(ctx, ast, ex.commitSQLTransactionInternal)
return ev, payload, nil
Expand Down Expand Up @@ -838,7 +906,9 @@ func (ex *connExecutor) execStmtInOpenState(
return nil, nil, nil
}

p.semaCtx.Annotations = tree.MakeAnnotations(stmt.NumAnnotations)
// Don't write to the exec/audit logs here; it will be handled in
// dispatchToExecutionEngine.
shouldLog = false

// For regular statements (the ones that get to this point), we
// don't return any event unless an error happens.
Expand Down Expand Up @@ -891,12 +961,6 @@ func (ex *connExecutor) execStmtInOpenState(
return makeErrEvent(err)
}

if err := p.semaCtx.Placeholders.Assign(pinfo, stmt.NumPlaceholders); err != nil {
return makeErrEvent(err)
}
p.extendedEvalCtx.Placeholders = &p.semaCtx.Placeholders
p.extendedEvalCtx.Annotations = &p.semaCtx.Annotations
p.stmt = stmt
if isPausablePortal() {
p.pausablePortal = portal
}
Expand Down Expand Up @@ -1450,23 +1514,6 @@ func (ex *connExecutor) dispatchToExecutionEngine(
}
}

// If adminAuditLogging is enabled, we want to check for HasAdminRole
// before the deferred maybeLogStatement.
// We must check prior to execution in the case the txn is aborted due to
// an error. HasAdminRole can only be checked in a valid txn.
if adminAuditLog := adminAuditLogEnabled.Get(
&ex.planner.execCfg.Settings.SV,
); adminAuditLog {
if !ex.extraTxnState.hasAdminRoleCache.IsSet {
hasAdminRole, err := ex.planner.HasAdminRole(ctx)
if err != nil {
return err
}
ex.extraTxnState.hasAdminRoleCache.HasAdminRole = hasAdminRole
ex.extraTxnState.hasAdminRoleCache.IsSet = true
}
}

var err error
if ppInfo := getPausablePortalInfo(); ppInfo != nil {
if !ppInfo.dispatchToExecutionEngine.cleanup.isComplete {
Expand Down

0 comments on commit e85d1f4

Please sign in to comment.