(
&mut self,
portal_name: String,
mut session: Session,
tx: ClientTransmitter<ExecuteResponse>,
// If this command was part of another execute command
/
| 1060 | /// Handles an execute command. |
| 1061 | #[instrument(name = "coord::handle_execute", fields(session = session.uuid().to_string()))] |
| 1062 | pub(crate) async fn handle_execute( |
| 1063 | &mut self, |
| 1064 | portal_name: String, |
| 1065 | mut session: Session, |
| 1066 | tx: ClientTransmitter<ExecuteResponse>, |
| 1067 | // If this command was part of another execute command |
| 1068 | // (for example, executing a `FETCH` statement causes an execute to be |
| 1069 | // issued for the cursor it references), |
| 1070 | // then `outer_context` should be `Some`. |
| 1071 | // This instructs the coordinator that the |
| 1072 | // outer execute should be considered finished once the inner one is. |
| 1073 | outer_context: Option<ExecuteContextGuard>, |
| 1074 | ) { |
| 1075 | if session.vars().emit_trace_id_notice() { |
| 1076 | let span_context = tracing::Span::current() |
| 1077 | .context() |
| 1078 | .span() |
| 1079 | .span_context() |
| 1080 | .clone(); |
| 1081 | if span_context.is_valid() { |
| 1082 | session.add_notice(AdapterNotice::QueryTrace { |
| 1083 | trace_id: span_context.trace_id(), |
| 1084 | }); |
| 1085 | } |
| 1086 | } |
| 1087 | |
| 1088 | if let Err(err) = Self::verify_portal(self.catalog(), &mut session, &portal_name) { |
| 1089 | // If statement logging hasn't started yet, we don't need |
| 1090 | // to add any "end" event, so just make up a no-op |
| 1091 | // `ExecuteContextExtra` here, via `Default::default`. |
| 1092 | // |
| 1093 | // It's a bit unfortunate because the edge case of failed |
| 1094 | // portal verifications won't show up in statement |
| 1095 | // logging, but there seems to be nothing else we can do, |
| 1096 | // because we need access to the portal to begin logging. |
| 1097 | // |
| 1098 | // Another option would be to log a begin and end event, but just fill in NULLs |
| 1099 | // for everything we get from the portal (prepared statement id, params). |
| 1100 | let extra = outer_context.unwrap_or_else(Default::default); |
| 1101 | let ctx = ExecuteContext::from_parts(tx, self.internal_cmd_tx.clone(), session, extra); |
| 1102 | return ctx.retire(Err(err)); |
| 1103 | } |
| 1104 | |
| 1105 | // The reference to `portal` can't outlive `session`, which we |
| 1106 | // use to construct the context, so scope the reference to this block where we |
| 1107 | // get everything we need from the portal for later. |
| 1108 | let (stmt, ctx, params) = { |
| 1109 | let portal = session |
| 1110 | .get_portal_unverified(&portal_name) |
| 1111 | .expect("known to exist"); |
| 1112 | let params = portal.parameters.clone(); |
| 1113 | let stmt = portal.stmt.clone(); |
| 1114 | let logging = Arc::clone(&portal.logging); |
| 1115 | let lifecycle_timestamps = portal.lifecycle_timestamps.clone(); |
| 1116 | |
| 1117 | let extra = if let Some(extra) = outer_context { |
| 1118 | // We are executing in the context of another SQL statement, so we don't |
| 1119 | // want to begin statement logging anew. The context of the actual statement |
no test coverage detected