diff --git a/CHANGELOG.md b/CHANGELOG.md index d117f72..9d0243d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +* runner: `RecordOutput` is now returned by `Runner::run` (or `Runner::run_async`). This allows users to access the output of each record, or check whether the record is skipped. + ## [0.20.6] - 2024-06-21 * runner: add logs for `system` command (with target `sqllogictest::system_command`) for ease of debugging. diff --git a/sqllogictest/src/runner.rs b/sqllogictest/src/runner.rs index 87a4928..9ad0cf2 100644 --- a/sqllogictest/src/runner.rs +++ b/sqllogictest/src/runner.rs @@ -23,19 +23,22 @@ use crate::{ColumnType, Connections, MakeConnection}; /// Type-erased error type. type AnyError = Arc; +/// Output of a record. #[derive(Debug, Clone)] #[non_exhaustive] pub enum RecordOutput { + /// No output. Occurs when the record is skipped or not a `query`, `statement`, or `system` + /// command. Nothing, + /// The output of a `query`. Query { types: Vec, rows: Vec>, error: Option, }, - Statement { - count: u64, - error: Option, - }, + /// The output of a `statement`. + Statement { count: u64, error: Option }, + /// The output of a `system` command. #[non_exhaustive] System { stdout: Option, @@ -833,10 +836,13 @@ impl> Runner { } /// Run a single record. - pub async fn run_async(&mut self, record: Record) -> Result<(), TestError> { + pub async fn run_async( + &mut self, + record: Record, + ) -> Result, TestError> { let result = self.apply_record(record.clone()).await; - match (record, result) { + match (record, &result) { (_, RecordOutput::Nothing) => {} // Tolerate the mismatched return type... ( @@ -894,7 +900,7 @@ impl> Runner { .at(loc)) } (None, StatementExpect::Count(expected_count)) => { - if expected_count != count { + if expected_count != *count { return Err(TestErrorKind::StatementResultMismatch { sql, expected: expected_count, @@ -908,7 +914,7 @@ impl> Runner { if !expected_error.is_match(&e.to_string()) { return Err(TestErrorKind::ErrorMismatch { sql, - err: Arc::new(e), + err: Arc::clone(e), expected_err: expected_error.to_string(), kind: RecordKind::Statement, } @@ -918,7 +924,7 @@ impl> Runner { (Some(e), StatementExpect::Count(_) | StatementExpect::Ok) => { return Err(TestErrorKind::Fail { sql, - err: Arc::new(e), + err: Arc::clone(e), kind: RecordKind::Statement, } .at(loc)); @@ -946,7 +952,7 @@ impl> Runner { if !expected_error.is_match(&e.to_string()) { return Err(TestErrorKind::ErrorMismatch { sql, - err: Arc::new(e), + err: Arc::clone(e), expected_err: expected_error.to_string(), kind: RecordKind::Query, } @@ -956,7 +962,7 @@ impl> Runner { (Some(e), QueryExpect::Results { .. }) => { return Err(TestErrorKind::Fail { sql, - err: Arc::new(e), + err: Arc::clone(e), kind: RecordKind::Query, } .at(loc)); @@ -1006,12 +1012,16 @@ impl> Runner { }, ) => { if let Some(err) = error { - return Err(TestErrorKind::SystemFail { command, err }.at(loc)); + return Err(TestErrorKind::SystemFail { + command, + err: Arc::clone(err), + } + .at(loc)); } match (expected_stdout, actual_stdout) { (None, _) => {} (Some(expected_stdout), actual_stdout) => { - let actual_stdout = actual_stdout.unwrap_or_default(); + let actual_stdout = actual_stdout.clone().unwrap_or_default(); // TODO: support newlines contained in expected_stdout if expected_stdout != actual_stdout.trim() { return Err(TestErrorKind::SystemStdoutMismatch { @@ -1027,17 +1037,24 @@ impl> Runner { _ => unreachable!(), } - Ok(()) + Ok(result) } /// Run a single record. - pub fn run(&mut self, record: Record) -> Result<(), TestError> { + /// + /// Returns the output of the record if successful. + pub fn run( + &mut self, + record: Record, + ) -> Result, TestError> { futures::executor::block_on(self.run_async(record)) } /// Run multiple records. /// /// The runner will stop early once a halt record is seen. + /// + /// To acquire the result of each record, manually call `run_async` for each record instead. pub async fn run_multi_async( &mut self, records: impl IntoIterator>, @@ -1054,6 +1071,8 @@ impl> Runner { /// Run multiple records. /// /// The runner will stop early once a halt record is seen. + /// + /// To acquire the result of each record, manually call `run` for each record instead. pub fn run_multi( &mut self, records: impl IntoIterator>,