| 528 | } |
| 529 | |
| 530 | async fn try_run_fail_sql( |
| 531 | state: &State, |
| 532 | query: &str, |
| 533 | expected_error: &ErrorMatcher, |
| 534 | expected_detail: Option<&ErrorMatcher>, |
| 535 | expected_hint: Option<&ErrorMatcher>, |
| 536 | ) -> Result<(), anyhow::Error> { |
| 537 | // `query` is raw SQL from testdrive input and may include statements that |
| 538 | // cannot be represented as composable `Sql`. |
| 539 | #[allow(clippy::disallowed_methods)] |
| 540 | match state.materialize.pgclient.query(query, &[]).await { |
| 541 | Ok(_) => bail!("query succeeded, but expected {}", expected_error), |
| 542 | Err(err) => match err.source().and_then(|err| err.downcast_ref::<DbError>()) { |
| 543 | Some(err) => { |
| 544 | let mut err_string = err.message().to_string(); |
| 545 | if let Some(regex) = &state.regex { |
| 546 | err_string = regex |
| 547 | .replace_all(&err_string, state.regex_replacement.as_str()) |
| 548 | .to_string(); |
| 549 | } |
| 550 | if !expected_error.is_match(&err_string) { |
| 551 | bail!("expected {}, got {}", expected_error, err_string.quoted()); |
| 552 | } |
| 553 | |
| 554 | let check_additional = |
| 555 | |extra: Option<&str>, matcher: Option<&ErrorMatcher>, type_| { |
| 556 | let extra = extra.map(|s| s.to_string()); |
| 557 | match (extra, matcher) { |
| 558 | (Some(extra), Some(expected)) => { |
| 559 | if !expected.is_match(&extra) { |
| 560 | bail!( |
| 561 | "expected {}, got {}", |
| 562 | expected.fmt_with_type(type_), |
| 563 | extra.quoted() |
| 564 | ); |
| 565 | } |
| 566 | } |
| 567 | (None, Some(expected)) => { |
| 568 | bail!("expected {}, but found none", expected.fmt_with_type(type_)); |
| 569 | } |
| 570 | _ => {} |
| 571 | } |
| 572 | Ok(()) |
| 573 | }; |
| 574 | |
| 575 | check_additional(err.detail(), expected_detail, "DETAIL")?; |
| 576 | check_additional(err.hint(), expected_hint, "HINT")?; |
| 577 | |
| 578 | Ok(()) |
| 579 | } |
| 580 | None => Err(err.into()), |
| 581 | }, |
| 582 | } |
| 583 | } |
| 584 | |
| 585 | pub fn print_query(query: &str, stmt: Option<&Statement<Raw>>) { |
| 586 | use Statement::*; |