1// Copyright Materialize, Inc. and contributors. All rights reserved.
2//
3// Use of this software is governed by the Business Source License
4// included in the LICENSE file.
5//
6// As of the Change Date specified in that file, in accordance with
7// the Business Source License, use of this software will be governed
8// by the Apache License, Version 2.0.
910use anyhow::{Context, bail};
11use mz_ore::option::OptionExt;
12use tokio::process::Command;
1314use crate::action::{ControlFlow, State};
15use crate::parser::BuiltinCommand;
16use crate::util::text;
1718pub async fn run_execute(
19mut cmd: BuiltinCommand,
20 state: &State,
21) -> Result<ControlFlow, anyhow::Error> {
22let command = cmd.args.string("command")?;
23 cmd.args.done()?;
2425let expected_output = cmd.input.join("\n");
26let output = Command::new("psql")
27 .args([
28// Ignore .psqlrc so that local execution of testdrive isn't
29 // affected by it.
30"--no-psqlrc",
31"--pset",
32"footer=off",
33"--command",
34&command,
35&format!(
36"postgres://{}@{}",
37 state.materialize.user, state.materialize.sql_addr
38 ),
39 ])
40 .output()
41 .await
42.context("execution of `psql` failed")?;
43if !output.status.success() {
44bail!(
45"psql reported failure with exit code {}: {}",
46 output.status.code().display_or("unknown"),
47 String::from_utf8_lossy(&output.stderr),
48 );
49 }
50let stdout = text::trim_trailing_space(&String::from_utf8_lossy(&output.stdout));
51if expected_output != stdout {
52 text::print_diff(&expected_output, &*stdout);
53bail!("psql returned unexpected output (diff above)");
54 }
55Ok(ControlFlow::Continue)
56}