You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by ji...@apache.org on 2021/11/04 01:28:34 UTC
[arrow-datafusion] branch master updated: add command to list
columns (#1231)
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 308004e add command to list columns (#1231)
308004e is described below
commit 308004eff770aea0f52e19c0c875a14bc90152e8
Author: Jiayu Liu <Ji...@users.noreply.github.com>
AuthorDate: Thu Nov 4 09:28:27 2021 +0800
add command to list columns (#1231)
---
datafusion-cli/src/command.rs | 50 +++++++++++++++++++++++++++++++++----------
datafusion-cli/src/exec.rs | 15 +++++++------
datafusion-cli/src/main.rs | 4 ++--
3 files changed, 49 insertions(+), 20 deletions(-)
diff --git a/datafusion-cli/src/command.rs b/datafusion-cli/src/command.rs
index ea9bea3..94d7ca3 100644
--- a/datafusion-cli/src/command.rs
+++ b/datafusion-cli/src/command.rs
@@ -18,13 +18,14 @@
//! Command within CLI
use crate::context::Context;
+use crate::print_options::PrintOptions;
use datafusion::arrow::array::{ArrayRef, StringArray};
use datafusion::arrow::datatypes::{DataType, Field, Schema};
use datafusion::arrow::record_batch::RecordBatch;
-use datafusion::arrow::util::pretty;
use datafusion::error::{DataFusionError, Result};
use std::str::FromStr;
use std::sync::Arc;
+use std::time::Instant;
/// Command
#[derive(Debug)]
@@ -32,17 +33,32 @@ pub enum Command {
Quit,
Help,
ListTables,
+ DescribeTable(String),
}
impl Command {
- pub async fn execute(&self, ctx: &mut Context) -> Result<()> {
+ pub async fn execute(
+ &self,
+ ctx: &mut Context,
+ print_options: &PrintOptions,
+ ) -> Result<()> {
+ let now = Instant::now();
match self {
- Self::Help => pretty::print_batches(&[all_commands_info()])
+ Self::Help => print_options
+ .print_batches(&[all_commands_info()], now)
.map_err(|e| DataFusionError::Execution(e.to_string())),
Self::ListTables => {
let df = ctx.sql("SHOW TABLES").await?;
let batches = df.collect().await?;
- pretty::print_batches(&batches)
+ print_options
+ .print_batches(&batches, now)
+ .map_err(|e| DataFusionError::Execution(e.to_string()))
+ }
+ Self::DescribeTable(name) => {
+ let df = ctx.sql(&format!("SHOW COLUMNS FROM {}", name)).await?;
+ let batches = df.collect().await?;
+ print_options
+ .print_batches(&batches, now)
.map_err(|e| DataFusionError::Execution(e.to_string()))
}
Self::Quit => Err(DataFusionError::Execution(
@@ -51,16 +67,22 @@ impl Command {
}
}
- fn get_name_and_description(&self) -> (&str, &str) {
+ fn get_name_and_description(&self) -> (&'static str, &'static str) {
match self {
Self::Quit => ("\\q", "quit datafusion-cli"),
Self::ListTables => ("\\d", "list tables"),
+ Self::DescribeTable(_) => ("\\d name", "describe table"),
Self::Help => ("\\?", "help"),
}
}
}
-const ALL_COMMANDS: [Command; 3] = [Command::ListTables, Command::Quit, Command::Help];
+const ALL_COMMANDS: [Command; 4] = [
+ Command::ListTables,
+ Command::DescribeTable(String::new()),
+ Command::Quit,
+ Command::Help,
+];
fn all_commands_info() -> RecordBatch {
let schema = Arc::new(Schema::new(vec![
@@ -68,7 +90,7 @@ fn all_commands_info() -> RecordBatch {
Field::new("Description", DataType::Utf8, false),
]));
let (names, description): (Vec<&str>, Vec<&str>) = ALL_COMMANDS
- .iter()
+ .into_iter()
.map(|c| c.get_name_and_description())
.unzip();
RecordBatch::try_new(
@@ -85,10 +107,16 @@ impl FromStr for Command {
type Err = ();
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
- Ok(match s {
- "q" => Self::Quit,
- "d" => Self::ListTables,
- "?" => Self::Help,
+ let (c, arg) = if let Some((a, b)) = s.split_once(' ') {
+ (a, Some(b))
+ } else {
+ (s, None)
+ };
+ Ok(match (c, arg) {
+ ("q", None) => Self::Quit,
+ ("d", None) => Self::ListTables,
+ ("d", Some(name)) => Self::DescribeTable(name.into()),
+ ("?", None) => Self::Help,
_ => return Err(()),
})
}
diff --git a/datafusion-cli/src/exec.rs b/datafusion-cli/src/exec.rs
index 702d288..f22e5cc 100644
--- a/datafusion-cli/src/exec.rs
+++ b/datafusion-cli/src/exec.rs
@@ -38,7 +38,7 @@ use std::time::Instant;
pub async fn exec_from_lines(
ctx: &mut Context,
reader: &mut BufReader<File>,
- print_options: PrintOptions,
+ print_options: &PrintOptions,
) {
let mut query = "".to_owned();
@@ -51,7 +51,7 @@ pub async fn exec_from_lines(
let line = line.trim_end();
query.push_str(line);
if line.ends_with(';') {
- match exec_and_print(ctx, print_options.clone(), query).await {
+ match exec_and_print(ctx, print_options, query).await {
Ok(_) => {}
Err(err) => println!("{:?}", err),
}
@@ -76,7 +76,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: &PrintOptions) {
let mut rl = Editor::<()>::new();
rl.load_history(".history").ok();
@@ -84,11 +84,12 @@ pub async fn exec_from_repl(ctx: &mut Context, print_options: PrintOptions) {
loop {
match rl.readline("> ") {
Ok(line) if line.starts_with('\\') => {
+ rl.add_history_entry(line.trim_end());
if let Ok(cmd) = &line[1..].parse::<Command>() {
match cmd {
Command::Quit => break,
- others => {
- if let Err(e) = others.execute(ctx).await {
+ _ => {
+ if let Err(e) = cmd.execute(ctx, print_options).await {
eprintln!("{}", e)
}
}
@@ -103,7 +104,7 @@ pub async fn exec_from_repl(ctx: &mut Context, print_options: PrintOptions) {
Ok(line) if line.trim_end().ends_with(';') => {
query.push_str(line.trim_end());
rl.add_history_entry(query.clone());
- match exec_and_print(ctx, print_options.clone(), query).await {
+ match exec_and_print(ctx, print_options, query).await {
Ok(_) => {}
Err(err) => eprintln!("{:?}", err),
}
@@ -124,7 +125,7 @@ pub async fn exec_from_repl(ctx: &mut Context, print_options: PrintOptions) {
async fn exec_and_print(
ctx: &mut Context,
- print_options: PrintOptions,
+ print_options: &PrintOptions,
sql: String,
) -> Result<()> {
let now = Instant::now();
diff --git a/datafusion-cli/src/main.rs b/datafusion-cli/src/main.rs
index cd4caca..2b6296a 100644
--- a/datafusion-cli/src/main.rs
+++ b/datafusion-cli/src/main.rs
@@ -145,10 +145,10 @@ pub async fn main() -> Result<()> {
.collect::<Vec<_>>();
for file in files {
let mut reader = BufReader::new(file);
- exec::exec_from_lines(&mut ctx, &mut reader, print_options.clone()).await;
+ 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, &print_options).await;
}
Ok(())