This is an automated email from the ASF dual-hosted git repository.

jiayuliu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow-datafusion.git


The following commit(s) were added to refs/heads/master by this push:
     new 124977e  Add a command to switch output format in cli (#1284)
124977e is described below

commit 124977e98c0d6ecc26ad908a5028c705cb3f827d
Author: Jason Tianyi Wang <[email protected]>
AuthorDate: Tue Nov 30 13:11:36 2021 +0900

    Add a command to switch output format in cli (#1284)
    
    * Add a command to switch output format in cli
    
    fixes #1267
    
    * Add error handling
    
    * Fix fmt
---
 datafusion-cli/src/command.rs | 53 +++++++++++++++++++++++++++++++++++++++++--
 datafusion-cli/src/exec.rs    | 23 +++++++++++++++++--
 datafusion-cli/src/main.rs    |  4 ++--
 3 files changed, 74 insertions(+), 6 deletions(-)

diff --git a/datafusion-cli/src/command.rs b/datafusion-cli/src/command.rs
index 0b7dbe4..ef6f67d 100644
--- a/datafusion-cli/src/command.rs
+++ b/datafusion-cli/src/command.rs
@@ -19,7 +19,8 @@
 
 use crate::context::Context;
 use crate::functions::{display_all_functions, Function};
-use crate::print_options::PrintOptions;
+use crate::print_format::PrintFormat;
+use crate::print_options::{self, PrintOptions};
 use datafusion::arrow::array::{ArrayRef, StringArray};
 use datafusion::arrow::datatypes::{DataType, Field, Schema};
 use datafusion::arrow::record_batch::RecordBatch;
@@ -38,6 +39,11 @@ pub enum Command {
     ListFunctions,
     SearchFunctions(String),
     QuietMode(Option<bool>),
+    OutputFormat(Option<String>),
+}
+
+pub enum OutputFormat {
+    ChangeFormat(String),
 }
 
 impl Command {
@@ -94,6 +100,9 @@ impl Command {
                     Err(DataFusionError::Execution(msg))
                 }
             }
+            Self::OutputFormat(_) => Err(DataFusionError::Execution(
+                "Unexpected change output format, this should be handled 
outside".into(),
+            )),
         }
     }
 
@@ -106,11 +115,14 @@ impl Command {
             Self::ListFunctions => ("\\h", "function list"),
             Self::SearchFunctions(_) => ("\\h function", "search function"),
             Self::QuietMode(_) => ("\\quiet (true|false)?", "print or set 
quiet mode"),
+            Self::OutputFormat(_) => {
+                ("\\pset [NAME [VALUE]]", "set table output option\n(format)")
+            }
         }
     }
 }
 
-const ALL_COMMANDS: [Command; 7] = [
+const ALL_COMMANDS: [Command; 8] = [
     Command::ListTables,
     Command::DescribeTable(String::new()),
     Command::Quit,
@@ -118,6 +130,7 @@ const ALL_COMMANDS: [Command; 7] = [
     Command::ListFunctions,
     Command::SearchFunctions(String::new()),
     Command::QuietMode(None),
+    Command::OutputFormat(None),
 ];
 
 fn all_commands_info() -> RecordBatch {
@@ -162,7 +175,43 @@ impl FromStr for Command {
                 Self::QuietMode(Some(false))
             }
             ("quiet", None) => Self::QuietMode(None),
+            ("pset", Some(subcommand)) => {
+                Self::OutputFormat(Some(subcommand.to_string()))
+            }
+            ("pset", None) => Self::OutputFormat(None),
+            _ => return Err(()),
+        })
+    }
+}
+
+impl FromStr for OutputFormat {
+    type Err = ();
+
+    fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
+        let (c, arg) = if let Some((a, b)) = s.split_once(' ') {
+            (a, Some(b))
+        } else {
+            (s, None)
+        };
+        Ok(match (c, arg) {
+            ("format", Some(format)) => Self::ChangeFormat(format.to_string()),
             _ => return Err(()),
         })
     }
 }
+
+impl OutputFormat {
+    pub async fn execute(&self, print_options: &mut PrintOptions) -> 
Result<()> {
+        match self {
+            Self::ChangeFormat(format) => {
+                if let Ok(format) = format.parse::<PrintFormat>() {
+                    print_options.format = format;
+                    println!("Output format is {}.", print_options.format);
+                    Ok(())
+                } else {
+                    Err(DataFusionError::Execution(format!("{} is not a valid 
format type [possible values: csv, tsv, table, json, ndjson]", format)))
+                }
+            }
+        }
+    }
+}
diff --git a/datafusion-cli/src/exec.rs b/datafusion-cli/src/exec.rs
index 41db7e6..45136de 100644
--- a/datafusion-cli/src/exec.rs
+++ b/datafusion-cli/src/exec.rs
@@ -18,12 +18,13 @@
 //! Execution functions
 
 use crate::{
-    command::Command,
+    command::{Command, OutputFormat},
     context::Context,
     helper::CliHelper,
     print_format::{all_print_formats, PrintFormat},
     print_options::PrintOptions,
 };
+use clap::SubCommand;
 use datafusion::arrow::record_batch::RecordBatch;
 use datafusion::arrow::util::pretty;
 use datafusion::error::{DataFusionError, Result};
@@ -79,7 +80,7 @@ pub async fn exec_from_lines(
 }
 
 /// run and execute SQL statements and commands against a context with the 
given print options
-pub async fn exec_from_repl(ctx: &mut Context, print_options: &PrintOptions) {
+pub async fn exec_from_repl(ctx: &mut Context, print_options: &mut 
PrintOptions) {
     let mut rl = Editor::<CliHelper>::new();
     rl.set_helper(Some(CliHelper::default()));
     rl.load_history(".history").ok();
@@ -93,6 +94,24 @@ pub async fn exec_from_repl(ctx: &mut Context, 
print_options: &PrintOptions) {
                 if let Ok(cmd) = &line[1..].parse::<Command>() {
                     match cmd {
                         Command::Quit => break,
+                        Command::OutputFormat(subcommand) => {
+                            if let Some(subcommand) = subcommand {
+                                if let Ok(command) = 
subcommand.parse::<OutputFormat>() {
+                                    if let Err(e) =
+                                        command.execute(&mut 
print_options).await
+                                    {
+                                        eprintln!("{}", e)
+                                    }
+                                } else {
+                                    eprintln!(
+                                        "'\\{}' is not a valid command",
+                                        &line[1..]
+                                    );
+                                }
+                            } else {
+                                println!("Output format is {}.", 
print_options.format);
+                            }
+                        }
                         _ => {
                             if let Err(e) = cmd.execute(ctx, &mut 
print_options).await {
                                 eprintln!("{}", e)
diff --git a/datafusion-cli/src/main.rs b/datafusion-cli/src/main.rs
index 2b6296a..577a311 100644
--- a/datafusion-cli/src/main.rs
+++ b/datafusion-cli/src/main.rs
@@ -137,7 +137,7 @@ pub async fn main() -> Result<()> {
         .parse::<PrintFormat>()
         .expect("Invalid format");
 
-    let print_options = PrintOptions { format, quiet };
+    let mut print_options = PrintOptions { format, quiet };
 
     if let Some(file_paths) = matches.values_of("file") {
         let files = file_paths
@@ -148,7 +148,7 @@ pub async fn main() -> Result<()> {
             exec::exec_from_lines(&mut ctx, &mut reader, &print_options).await;
         }
     } else {
-        exec::exec_from_repl(&mut ctx, &print_options).await;
+        exec::exec_from_repl(&mut ctx, &mut print_options).await;
     }
 
     Ok(())

Reply via email to