diff --git a/CHANGELOG.md b/CHANGELOG.md index 3343948..907de43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +## [0.19.1] - 2024-01-04 + +* parser: `include` now returns error if no file is matched. + ## [0.19.0] - 2023-11-11 * parser: refactor `expect` field in sqllogictest parser to make it easier to work with. diff --git a/sqllogictest-bin/src/main.rs b/sqllogictest-bin/src/main.rs index f05502c..710a3e2 100644 --- a/sqllogictest-bin/src/main.rs +++ b/sqllogictest-bin/src/main.rs @@ -465,10 +465,9 @@ async fn run_test_file( filename: impl AsRef, ) -> Result { let filename = filename.as_ref(); - let records = tokio::task::block_in_place(|| { - sqllogictest::parse_file(filename).map_err(|e| anyhow!("{:?}", e)) - }) - .context("failed to parse sqllogictest file")?; + let records = + tokio::task::block_in_place(|| sqllogictest::parse_file(filename).map_err(|e| anyhow!(e))) + .context("failed to parse sqllogictest file")?; let mut begin_times = vec![]; let mut did_pop = false; diff --git a/sqllogictest/src/parser.rs b/sqllogictest/src/parser.rs index ac2f5ab..2dbede6 100644 --- a/sqllogictest/src/parser.rs +++ b/sqllogictest/src/parser.rs @@ -10,7 +10,6 @@ use itertools::Itertools; use regex::Regex; use crate::ColumnType; -use crate::ParseErrorKind::InvalidIncludeFile; const RESULTS_DELIMITER: &str = "----"; @@ -112,6 +111,7 @@ pub enum Record { /// An include copies all records from another files. Include { loc: Location, + /// A glob pattern filename: String, }, /// A statement is an SQL command that is to be evaluated but from which we do not expect to @@ -584,8 +584,10 @@ pub enum ParseErrorKind { InvalidDuration(String), #[error("invalid control: {0:?}")] InvalidControl(String), - #[error("invalid include file pattern: {0:?}")] + #[error("invalid include file pattern: {0}")] InvalidIncludeFile(String), + #[error("no files found for include file pattern: {0:?}")] + EmptyIncludeFile(String), #[error("no such file")] FileNotFound, } @@ -843,10 +845,16 @@ fn parse_file_inner(loc: Location) -> Result>, Pars path_buf.as_os_str().to_string_lossy().to_string() }; - for included_file in glob::glob(&complete_filename) - .map_err(|e| InvalidIncludeFile(format!("{e:?}")).at(loc.clone()))? - .filter_map(Result::ok) - { + let mut iter = glob::glob(&complete_filename) + .map_err(|e| ParseErrorKind::InvalidIncludeFile(e.to_string()).at(loc.clone()))? + .peekable(); + if iter.peek().is_none() { + return Err(ParseErrorKind::EmptyIncludeFile(filename).at(loc.clone())); + } + for included_file in iter { + let included_file = included_file.map_err(|e| { + ParseErrorKind::InvalidIncludeFile(format!("{e:?}")).at(loc.clone()) + })?; let included_file = included_file.as_os_str().to_string_lossy().to_string(); records.push(Record::Injected(Injected::BeginInclude(