Handle EXPLAIN: plan the inner SQL and return the plan description.
(
&self,
identity: &AuthenticatedIdentity,
addr: &std::net::SocketAddr,
sql: &str,
)
| 536 | |
| 537 | /// Handle EXPLAIN: plan the inner SQL and return the plan description. |
| 538 | pub(super) async fn handle_explain( |
| 539 | &self, |
| 540 | identity: &AuthenticatedIdentity, |
| 541 | addr: &std::net::SocketAddr, |
| 542 | sql: &str, |
| 543 | ) -> PgWireResult<Vec<Response>> { |
| 544 | let upper = sql.to_uppercase(); |
| 545 | let is_analyze = upper.starts_with("EXPLAIN ANALYZE "); |
| 546 | |
| 547 | let inner_sql = if is_analyze { |
| 548 | sql[16..].trim() |
| 549 | } else if upper.starts_with("EXPLAIN ") { |
| 550 | sql[8..].trim() |
| 551 | } else { |
| 552 | return Err(PgWireError::UserError(Box::new(ErrorInfo::new( |
| 553 | "ERROR".to_owned(), |
| 554 | "42601".to_owned(), |
| 555 | "syntax error in EXPLAIN".to_owned(), |
| 556 | )))); |
| 557 | }; |
| 558 | |
| 559 | let database_id = self |
| 560 | .sessions |
| 561 | .get_current_database(addr) |
| 562 | .unwrap_or(crate::types::DatabaseId::DEFAULT); |
| 563 | if super::super::ddl::dispatch(&self.state, identity, inner_sql, database_id) |
| 564 | .await |
| 565 | .is_some() |
| 566 | { |
| 567 | let schema = Arc::new(vec![text_field("QUERY PLAN")]); |
| 568 | let plan_text = format!( |
| 569 | "DDL: {}", |
| 570 | inner_sql |
| 571 | .split_whitespace() |
| 572 | .take(3) |
| 573 | .collect::<Vec<_>>() |
| 574 | .join(" ") |
| 575 | ); |
| 576 | let mut encoder = DataRowEncoder::new(schema.clone()); |
| 577 | encoder.encode_field(&plan_text)?; |
| 578 | let row = encoder.take_row(); |
| 579 | return Ok(vec![Response::Query(QueryResponse::new( |
| 580 | schema, |
| 581 | futures::stream::iter(vec![Ok(row)]), |
| 582 | ))]); |
| 583 | } |
| 584 | |
| 585 | let tenant_id = identity.tenant_id; |
| 586 | let auth_ctx = crate::control::server::session_auth::build_auth_context(identity); |
| 587 | let perm_cache = self.state.permission_cache.read().await; |
| 588 | let sec = crate::control::planner::context::PlanSecurityContext { |
| 589 | identity, |
| 590 | auth: &auth_ctx, |
| 591 | rls_store: &self.state.rls, |
| 592 | permissions: &self.state.permissions, |
| 593 | roles: &self.state.roles, |
| 594 | permission_cache: Some(&*perm_cache), |
| 595 | }; |
no test coverage detected