@@ -133,7 +133,7 @@ func (ex *connExecutor) execStmt(
133133 // Note: when not using explicit transactions, we go through this transition
134134 // for every statement. It is important to minimize the amount of work and
135135 // allocations performed up to this point.
136- ev , payload = ex .execStmtInNoTxnState (ctx , ast , res )
136+ ev , payload = ex .execStmtInNoTxnState (ctx , parserStmt , res )
137137
138138 case stateOpen :
139139 var preparedStmt * PreparedStatement
@@ -753,6 +753,72 @@ func (ex *connExecutor) execStmtInOpenState(
753753 }
754754 }(ctx )
755755
756+ // If adminAuditLogging is enabled, we want to check for HasAdminRole
757+ // before maybeLogStatement.
758+ // We must check prior to execution in the case the txn is aborted due to
759+ // an error. HasAdminRole can only be checked in a valid txn.
760+ if adminAuditLog := adminAuditLogEnabled .Get (
761+ & ex .planner .execCfg .Settings .SV ,
762+ ); adminAuditLog {
763+ if ! ex .extraTxnState .hasAdminRoleCache .IsSet {
764+ hasAdminRole , err := ex .planner .HasAdminRole (ctx )
765+ if err != nil {
766+ return makeErrEvent (err )
767+ }
768+ ex .extraTxnState .hasAdminRoleCache .HasAdminRole = hasAdminRole
769+ ex .extraTxnState .hasAdminRoleCache .IsSet = true
770+ }
771+ }
772+
773+ p .stmt = stmt
774+ p .semaCtx .Annotations = tree .MakeAnnotations (stmt .NumAnnotations )
775+ p .extendedEvalCtx .Annotations = & p .semaCtx .Annotations
776+ if err := p .semaCtx .Placeholders .Assign (pinfo , stmt .NumPlaceholders ); err != nil {
777+ return makeErrEvent (err )
778+ }
779+ p .extendedEvalCtx .Placeholders = & p .semaCtx .Placeholders
780+
781+ shouldLogToExecAndAudit := true
782+ defer func () {
783+ if ! shouldLogToExecAndAudit {
784+ // We don't want to log this statement, since another layer of the
785+ // conn_executor will handle the logging for this statement.
786+ return
787+ }
788+
789+ p .curPlan .init (& p .stmt , & p .instrumentation )
790+ var execErr error
791+ if p , ok := retPayload .(payloadWithError ); ok {
792+ execErr = p .errorCause ()
793+ }
794+ f := tree .NewFmtCtx (tree .FmtHideConstants )
795+ f .FormatNode (ast )
796+ stmtFingerprintID := appstatspb .ConstructStatementFingerprintID (
797+ f .CloseAndGetString (),
798+ execErr != nil ,
799+ ex .implicitTxn (),
800+ p .CurrentDatabase (),
801+ )
802+
803+ p .maybeLogStatement (
804+ ctx ,
805+ ex .executorType ,
806+ false , /* isCopy */
807+ int (ex .state .mu .autoRetryCounter ),
808+ ex .extraTxnState .txnCounter ,
809+ 0 , /* rowsAffected */
810+ ex .state .mu .stmtCount ,
811+ 0 , /* bulkJobId */
812+ execErr ,
813+ ex .statsCollector .PhaseTimes ().GetSessionPhaseTime (sessionphase .SessionQueryReceived ),
814+ & ex .extraTxnState .hasAdminRoleCache ,
815+ ex .server .TelemetryLoggingMetrics ,
816+ stmtFingerprintID ,
817+ & topLevelQueryStats {},
818+ ex .statsCollector ,
819+ )
820+ }()
821+
756822 switch s := ast .(type ) {
757823 case * tree.BeginTransaction :
758824 // BEGIN is only allowed if we are in an implicit txn.
@@ -833,15 +899,27 @@ func (ex *connExecutor) execStmtInOpenState(
833899 ex .server .cfg .GenerateID (),
834900 )
835901 var rawTypeHints []oid.Oid
902+
903+ // Placeholders should be part of the statement being prepared, not the
904+ // PREPARE statement itself.
905+ oldPlaceholders := p .extendedEvalCtx .Placeholders
906+ p .extendedEvalCtx .Placeholders = nil
836907 if _ , err := ex .addPreparedStmt (
837908 ctx , name , prepStmt , typeHints , rawTypeHints , PreparedStatementOriginSQL ,
838909 ); err != nil {
839910 return makeErrEvent (err )
840911 }
912+ // The call to addPreparedStmt changed the planner stmt to the statement
913+ // being prepared. Set it back to the PREPARE statement, so that it's
914+ // logged correctly.
915+ p .stmt = stmt
916+ p .extendedEvalCtx .Placeholders = oldPlaceholders
841917 return nil , nil , nil
842918 }
843919
844- p .semaCtx .Annotations = tree .MakeAnnotations (stmt .NumAnnotations )
920+ // Don't write to the exec/audit logs here; it will be handled in
921+ // dispatchToExecutionEngine.
922+ shouldLogToExecAndAudit = false
845923
846924 // For regular statements (the ones that get to this point), we
847925 // don't return any event unless an error happens.
@@ -894,12 +972,6 @@ func (ex *connExecutor) execStmtInOpenState(
894972 return makeErrEvent (err )
895973 }
896974
897- if err := p .semaCtx .Placeholders .Assign (pinfo , stmt .NumPlaceholders ); err != nil {
898- return makeErrEvent (err )
899- }
900- p .extendedEvalCtx .Placeholders = & p .semaCtx .Placeholders
901- p .extendedEvalCtx .Annotations = & p .semaCtx .Annotations
902- p .stmt = stmt
903975 if isPausablePortal () {
904976 p .pausablePortal = portal
905977 }
@@ -1453,23 +1525,6 @@ func (ex *connExecutor) dispatchToExecutionEngine(
14531525 }
14541526 }
14551527
1456- // If adminAuditLogging is enabled, we want to check for HasAdminRole
1457- // before the deferred maybeLogStatement.
1458- // We must check prior to execution in the case the txn is aborted due to
1459- // an error. HasAdminRole can only be checked in a valid txn.
1460- if adminAuditLog := adminAuditLogEnabled .Get (
1461- & ex .planner .execCfg .Settings .SV ,
1462- ); adminAuditLog {
1463- if ! ex .extraTxnState .hasAdminRoleCache .IsSet {
1464- hasAdminRole , err := ex .planner .HasAdminRole (ctx )
1465- if err != nil {
1466- return err
1467- }
1468- ex .extraTxnState .hasAdminRoleCache .HasAdminRole = hasAdminRole
1469- ex .extraTxnState .hasAdminRoleCache .IsSet = true
1470- }
1471- }
1472-
14731528 var err error
14741529 if ppInfo := getPausablePortalInfo (); ppInfo != nil {
14751530 if ! ppInfo .dispatchToExecutionEngine .cleanup .isComplete {
@@ -2190,8 +2245,57 @@ var eventStartExplicitTxn fsm.Event = eventTxnStart{ImplicitTxn: fsm.False}
21902245// the cursor is not advanced. This means that the statement will run again in
21912246// stateOpen, at each point its results will also be flushed.
21922247func (ex * connExecutor ) execStmtInNoTxnState (
2193- ctx context.Context , ast tree.Statement , res RestrictedCommandResult ,
2248+ ctx context.Context , parserStmt statements. Statement [ tree.Statement ] , res RestrictedCommandResult ,
21942249) (_ fsm.Event , payload fsm.EventPayload ) {
2250+ shouldLogToExecAndAudit := true
2251+ defer func () {
2252+ if ! shouldLogToExecAndAudit {
2253+ // We don't want to log this statement, since another layer of the
2254+ // conn_executor will handle the logging for this statement.
2255+ return
2256+ }
2257+
2258+ p := & ex .planner
2259+ stmt := makeStatement (parserStmt , ex .server .cfg .GenerateID ())
2260+ p .stmt = stmt
2261+ p .semaCtx .Annotations = tree .MakeAnnotations (stmt .NumAnnotations )
2262+ p .extendedEvalCtx .Annotations = & p .semaCtx .Annotations
2263+ p .extendedEvalCtx .Placeholders = & tree.PlaceholderInfo {}
2264+ p .curPlan .init (& p .stmt , & p .instrumentation )
2265+ var execErr error
2266+ if p , ok := payload .(payloadWithError ); ok {
2267+ execErr = p .errorCause ()
2268+ }
2269+
2270+ f := tree .NewFmtCtx (tree .FmtHideConstants )
2271+ f .FormatNode (stmt .AST )
2272+ stmtFingerprintID := appstatspb .ConstructStatementFingerprintID (
2273+ f .CloseAndGetString (),
2274+ execErr != nil ,
2275+ ex .implicitTxn (),
2276+ p .CurrentDatabase (),
2277+ )
2278+
2279+ p .maybeLogStatement (
2280+ ctx ,
2281+ ex .executorType ,
2282+ false , /* isCopy */
2283+ int (ex .state .mu .autoRetryCounter ),
2284+ ex .extraTxnState .txnCounter ,
2285+ 0 , /* rowsAffected */
2286+ 0 , /* stmtCount */
2287+ 0 , /* bulkJobId */
2288+ execErr ,
2289+ ex .statsCollector .PhaseTimes ().GetSessionPhaseTime (sessionphase .SessionQueryReceived ),
2290+ & ex .extraTxnState .hasAdminRoleCache ,
2291+ ex .server .TelemetryLoggingMetrics ,
2292+ stmtFingerprintID ,
2293+ & topLevelQueryStats {},
2294+ ex .statsCollector ,
2295+ )
2296+ }()
2297+
2298+ ast := parserStmt .AST
21952299 switch s := ast .(type ) {
21962300 case * tree.BeginTransaction :
21972301 ex .incrementStartedStmtCounter (ast )
@@ -2225,6 +2329,7 @@ func (ex *connExecutor) execStmtInNoTxnState(
22252329 // historical timestamp even though the statement itself might contain
22262330 // an AOST clause. In these cases the clause is evaluated and applied
22272331 // execStmtInOpenState.
2332+ shouldLogToExecAndAudit = false
22282333 noBeginStmt := (* tree .BeginTransaction )(nil )
22292334 mode , sqlTs , historicalTs , err := ex .beginTransactionTimestampsAndReadMode (ctx , noBeginStmt )
22302335 if err != nil {
0 commit comments