This is an automated email from the ASF dual-hosted git repository.
alamb pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-datafusion.git
The following commit(s) were added to refs/heads/main by this push:
new 1901d6fd41 feat: allow `datafusion-cli` to accept multiple statements
(#7138)
1901d6fd41 is described below
commit 1901d6fd41b85656ff334b515ef5afc00ddb7355
Author: Niwaka <[email protected]>
AuthorDate: Thu Aug 3 21:44:15 2023 +0900
feat: allow `datafusion-cli` to accept multiple statements (#7138)
* feat: allow cli to accept multiple statements
* add empty line between results
* use current context dialect
* move empty line to print_timing_info
---
datafusion-cli/src/exec.rs | 34 ++++++++++++++++++++++-----------
datafusion-cli/src/helper.rs | 3 ---
datafusion-cli/src/print_options.rs | 2 +-
datafusion-cli/tests/cli_integration.rs | 4 ++++
4 files changed, 28 insertions(+), 15 deletions(-)
diff --git a/datafusion-cli/src/exec.rs b/datafusion-cli/src/exec.rs
index 88553648ff..adbdb06e52 100644
--- a/datafusion-cli/src/exec.rs
+++ b/datafusion-cli/src/exec.rs
@@ -26,6 +26,7 @@ use crate::{
},
print_options::PrintOptions,
};
+use datafusion::sql::{parser::DFParser, sqlparser::dialect::dialect_from_str};
use datafusion::{
datasource::listing::ListingTableUrl,
error::{DataFusionError, Result},
@@ -192,18 +193,29 @@ async fn exec_and_print(
let now = Instant::now();
let sql = unescape_input(&sql)?;
- let plan = ctx.state().create_logical_plan(&sql).await?;
- let df = match &plan {
- LogicalPlan::Ddl(DdlStatement::CreateExternalTable(cmd)) => {
- create_external_table(ctx, cmd).await?;
- ctx.execute_logical_plan(plan).await?
- }
- _ => ctx.execute_logical_plan(plan).await?,
- };
-
- let results = df.collect().await?;
- print_options.print_batches(&results, now)?;
+ let task_ctx = ctx.task_ctx();
+ let dialect = &task_ctx.session_config().options().sql_parser.dialect;
+ let dialect = dialect_from_str(dialect).ok_or_else(|| {
+ DataFusionError::Plan(format!(
+ "Unsupported SQL dialect: {dialect}. Available dialects: \
+ Generic, MySQL, PostgreSQL, Hive, SQLite, Snowflake,
Redshift, \
+ MsSQL, ClickHouse, BigQuery, Ansi."
+ ))
+ })?;
+ let statements = DFParser::parse_sql_with_dialect(&sql, dialect.as_ref())?;
+ for statement in statements {
+ let plan = ctx.state().statement_to_plan(statement).await?;
+ let df = match &plan {
+ LogicalPlan::Ddl(DdlStatement::CreateExternalTable(cmd)) => {
+ create_external_table(ctx, cmd).await?;
+ ctx.execute_logical_plan(plan).await?
+ }
+ _ => ctx.execute_logical_plan(plan).await?,
+ };
+ let results = df.collect().await?;
+ print_options.print_batches(&results, now)?;
+ }
Ok(())
}
diff --git a/datafusion-cli/src/helper.rs b/datafusion-cli/src/helper.rs
index 15464eec13..981c4b5aa3 100644
--- a/datafusion-cli/src/helper.rs
+++ b/datafusion-cli/src/helper.rs
@@ -54,9 +54,6 @@ impl CliHelper {
Ok(statements) if statements.is_empty() =>
Ok(ValidationResult::Invalid(
Some(" 🤔 You entered an empty statement".to_string()),
)),
- Ok(statements) if statements.len() > 1 =>
Ok(ValidationResult::Invalid(
- Some(" 🤔 You entered more than one
statement".to_string()),
- )),
Ok(_statements) => Ok(ValidationResult::Valid(None)),
Err(err) => Ok(ValidationResult::Invalid(Some(format!(
" 🤔 Invalid statement: {err}",
diff --git a/datafusion-cli/src/print_options.rs
b/datafusion-cli/src/print_options.rs
index 5e3792634a..33ba7ef086 100644
--- a/datafusion-cli/src/print_options.rs
+++ b/datafusion-cli/src/print_options.rs
@@ -28,7 +28,7 @@ pub struct PrintOptions {
fn print_timing_info(row_count: usize, now: Instant) {
println!(
- "{} {} in set. Query took {:.3} seconds.",
+ "{} {} in set. Query took {:.3} seconds.\n",
row_count,
if row_count == 1 { "row" } else { "rows" },
now.elapsed().as_secs_f64()
diff --git a/datafusion-cli/tests/cli_integration.rs
b/datafusion-cli/tests/cli_integration.rs
index c6bee274e9..28344ffa94 100644
--- a/datafusion-cli/tests/cli_integration.rs
+++ b/datafusion-cli/tests/cli_integration.rs
@@ -33,6 +33,10 @@ fn init() {
["--command", "select 1", "--format", "json", "-q"],
"[{\"Int64(1)\":1}]\n"
)]
+#[case::exec_multiple_statements(
+ ["--command", "select 1; select 2;", "--format", "json", "-q"],
+ "[{\"Int64(1)\":1}]\n[{\"Int64(2)\":2}]\n"
+)]
#[case::exec_from_files(
["--file", "tests/data/sql.txt", "--format", "json", "-q"],
"[{\"Int64(1)\":1}]\n"