(
state: &mut State,
query: &str,
expected_output: &SqlOutput,
should_retry: bool,
)
| 209 | } |
| 210 | |
| 211 | async fn try_run_sql( |
| 212 | state: &mut State, |
| 213 | query: &str, |
| 214 | expected_output: &SqlOutput, |
| 215 | should_retry: bool, |
| 216 | ) -> Result<(), anyhow::Error> { |
| 217 | let stmt = state |
| 218 | .materialize |
| 219 | .pgclient |
| 220 | .prepare(query) |
| 221 | .await |
| 222 | .context("preparing query failed")?; |
| 223 | |
| 224 | let query_with_timeout = tokio::time::timeout( |
| 225 | state.timeout.clone(), |
| 226 | query_prepared(&state.materialize.pgclient, &stmt, &[]), |
| 227 | ) |
| 228 | .await; |
| 229 | |
| 230 | if query_with_timeout.is_err() { |
| 231 | bail!("query timed out\n") |
| 232 | } |
| 233 | |
| 234 | let rows: Vec<_> = query_with_timeout |
| 235 | .unwrap() |
| 236 | .context("executing query failed")? |
| 237 | .into_iter() |
| 238 | .map(|row| decode_row(state, row)) |
| 239 | .collect::<Result<_, _>>()?; |
| 240 | |
| 241 | let (mut actual, raw_actual): (Vec<_>, Vec<_>) = rows.into_iter().unzip(); |
| 242 | |
| 243 | let raw_actual: Option<Vec<_>> = if raw_actual.iter().any(|r| r.is_some()) { |
| 244 | // TODO(guswynn): Note we don't sort the raw rows, because |
| 245 | // there is no easy way of ensuring they sort the same way as actual. |
| 246 | Some( |
| 247 | actual |
| 248 | .iter() |
| 249 | .zip_eq(raw_actual) |
| 250 | .map(|(actual, unreplaced)| match unreplaced { |
| 251 | Some(raw_row) => raw_row, |
| 252 | None => actual.clone(), |
| 253 | }) |
| 254 | .collect(), |
| 255 | ) |
| 256 | } else { |
| 257 | None |
| 258 | }; |
| 259 | |
| 260 | actual.sort(); |
| 261 | let actual_columns: Vec<_> = stmt.columns().iter().map(|c| c.name()).collect(); |
| 262 | |
| 263 | match expected_output { |
| 264 | SqlOutput::Full { |
| 265 | expected_rows, |
| 266 | column_names, |
| 267 | } => { |
| 268 | if let Some(column_names) = column_names { |
no test coverage detected