(self)
| 189 | |
| 190 | impl RunOpt { |
| 191 | pub async fn run(self) -> Result<()> { |
| 192 | println!("Running NLJ benchmarks with the following options: {self:#?}\n"); |
| 193 | |
| 194 | // Define query range |
| 195 | let query_range = match self.query { |
| 196 | Some(query_id) => { |
| 197 | if query_id >= 1 && query_id <= NLJ_QUERIES.len() { |
| 198 | query_id..=query_id |
| 199 | } else { |
| 200 | return exec_err!( |
| 201 | "Query {query_id} not found. Available queries: 1 to {}", |
| 202 | NLJ_QUERIES.len() |
| 203 | ); |
| 204 | } |
| 205 | } |
| 206 | None => 1..=NLJ_QUERIES.len(), |
| 207 | }; |
| 208 | |
| 209 | let config = self.common.config()?; |
| 210 | let rt = self.common.build_runtime()?; |
| 211 | let ctx = SessionContext::new_with_config_rt(config, rt); |
| 212 | |
| 213 | let mut benchmark_run = BenchmarkRun::new(); |
| 214 | for query_id in query_range { |
| 215 | let query_index = query_id - 1; // Convert 1-based to 0-based index |
| 216 | |
| 217 | let sql = NLJ_QUERIES[query_index]; |
| 218 | benchmark_run.start_new_case(&format!("Query {query_id}")); |
| 219 | let query_run = self.benchmark_query(sql, &query_id.to_string(), &ctx).await; |
| 220 | match query_run { |
| 221 | Ok(query_results) => { |
| 222 | for iter in query_results { |
| 223 | benchmark_run.write_iter(iter.elapsed, iter.row_count); |
| 224 | } |
| 225 | } |
| 226 | Err(e) => { |
| 227 | return Err(DataFusionError::Context( |
| 228 | "NLJ benchmark Q{query_id} failed with error:".to_string(), |
| 229 | Box::new(e), |
| 230 | )); |
| 231 | } |
| 232 | } |
| 233 | } |
| 234 | |
| 235 | benchmark_run.maybe_write_json(self.output_path.as_ref())?; |
| 236 | Ok(()) |
| 237 | } |
| 238 | |
| 239 | /// Validates that the query's physical plan uses a NestedLoopJoin (NLJ), |
| 240 | /// then executes the query and collects execution times. |
nothing calls this directly
no test coverage detected