Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 42f8ab1

Browse files
Add statement helper command to cli (apache#1285)
* Setting up function helpers * Add func helpers to cli * Rename funcs and update descriptions * Added more functions * Add drop table * Better handle bad inputs * Code and formatting improvements * Update description Co-authored-by: Jiayu Liu <[email protected]> Co-authored-by: Jiayu Liu <[email protected]>
1 parent b64d2c6 commit 42f8ab1

3 files changed

Lines changed: 220 additions & 1 deletion

File tree

datafusion-cli/src/command.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
//! Command within CLI
1919
2020
use crate::context::Context;
21+
use crate::functions::{display_all_functions, Function};
2122
use crate::print_options::PrintOptions;
2223
use datafusion::arrow::array::{ArrayRef, StringArray};
2324
use datafusion::arrow::datatypes::{DataType, Field, Schema};
@@ -34,6 +35,8 @@ pub enum Command {
3435
Help,
3536
ListTables,
3637
DescribeTable(String),
38+
ListFunctions,
39+
SearchFunctions(String),
3740
}
3841

3942
impl Command {
@@ -64,6 +67,17 @@ impl Command {
6467
Self::Quit => Err(DataFusionError::Execution(
6568
"Unexpected quit, this should be handled outside".into(),
6669
)),
70+
Self::ListFunctions => display_all_functions(),
71+
Self::SearchFunctions(function) => {
72+
if let Ok(func) = function.parse::<Function>() {
73+
let details = func.function_details()?;
74+
println!("{}", details);
75+
Ok(())
76+
} else {
77+
let msg = format!("{} is not a supported function", function);
78+
Err(DataFusionError::Execution(msg))
79+
}
80+
}
6781
}
6882
}
6983

@@ -73,15 +87,19 @@ impl Command {
7387
Self::ListTables => ("\\d", "list tables"),
7488
Self::DescribeTable(_) => ("\\d name", "describe table"),
7589
Self::Help => ("\\?", "help"),
90+
Self::ListFunctions => ("\\h", "function list"),
91+
Self::SearchFunctions(_) => ("\\h function", "search function"),
7692
}
7793
}
7894
}
7995

80-
const ALL_COMMANDS: [Command; 4] = [
96+
const ALL_COMMANDS: [Command; 6] = [
8197
Command::ListTables,
8298
Command::DescribeTable(String::new()),
8399
Command::Quit,
84100
Command::Help,
101+
Command::ListFunctions,
102+
Command::SearchFunctions(String::new()),
85103
];
86104

87105
fn all_commands_info() -> RecordBatch {
@@ -117,6 +135,8 @@ impl FromStr for Command {
117135
("d", None) => Self::ListTables,
118136
("d", Some(name)) => Self::DescribeTable(name.into()),
119137
("?", None) => Self::Help,
138+
("h", None) => Self::ListFunctions,
139+
("h", Some(function)) => Self::SearchFunctions(function.into()),
120140
_ => return Err(()),
121141
})
122142
}

datafusion-cli/src/functions.rs

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
//! Functions that are query-able and searchable via the `\h` command
19+
use arrow::array::StringArray;
20+
use arrow::datatypes::{DataType, Field, Schema};
21+
use arrow::record_batch::RecordBatch;
22+
use arrow::util::pretty::pretty_format_batches;
23+
use datafusion::error::{DataFusionError, Result};
24+
use std::fmt;
25+
use std::str::FromStr;
26+
use std::sync::Arc;
27+
28+
#[derive(Debug)]
29+
pub enum Function {
30+
Select,
31+
Explain,
32+
Show,
33+
CreateTable,
34+
CreateTableAs,
35+
Insert,
36+
DropTable,
37+
}
38+
39+
const ALL_FUNCTIONS: [Function; 7] = [
40+
Function::CreateTable,
41+
Function::CreateTableAs,
42+
Function::DropTable,
43+
Function::Explain,
44+
Function::Insert,
45+
Function::Select,
46+
Function::Show,
47+
];
48+
49+
impl Function {
50+
pub fn function_details(&self) -> Result<&str> {
51+
let details = match self {
52+
Function::Select => {
53+
r#"
54+
Command: SELECT
55+
Description: retrieve rows from a table or view
56+
Syntax:
57+
SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]
58+
[ * | expression [ [ AS ] output_name ] [, ...] ]
59+
[ FROM from_item [, ...] ]
60+
[ WHERE condition ]
61+
[ GROUP BY [ ALL | DISTINCT ] grouping_element [, ...] ]
62+
[ HAVING condition ]
63+
[ WINDOW window_name AS ( window_definition ) [, ...] ]
64+
[ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] select ]
65+
[ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ]
66+
[ LIMIT { count | ALL } ]
67+
[ OFFSET start [ ROW | ROWS ] ]
68+
69+
where from_item can be one of:
70+
71+
[ ONLY ] table_name [ * ] [ [ AS ] alias [ ( column_alias [, ...] ) ] ]
72+
[ TABLESAMPLE sampling_method ( argument [, ...] ) [ REPEATABLE ( seed ) ] ]
73+
[ LATERAL ] ( select ) [ AS ] alias [ ( column_alias [, ...] ) ]
74+
with_query_name [ [ AS ] alias [ ( column_alias [, ...] ) ] ]
75+
[ LATERAL ] function_name ( [ argument [, ...] ] )
76+
[ WITH ORDINALITY ] [ [ AS ] alias [ ( column_alias [, ...] ) ] ]
77+
[ LATERAL ] function_name ( [ argument [, ...] ] ) [ AS ] alias ( column_definition [, ...] )
78+
[ LATERAL ] function_name ( [ argument [, ...] ] ) AS ( column_definition [, ...] )
79+
[ LATERAL ] ROWS FROM( function_name ( [ argument [, ...] ] ) [ AS ( column_definition [, ...] ) ] [, ...] )
80+
[ WITH ORDINALITY ] [ [ AS ] alias [ ( column_alias [, ...] ) ] ]
81+
from_item [ NATURAL ] join_type from_item [ ON join_condition | USING ( join_column [, ...] ) [ AS join_using_alias ] ]
82+
83+
and grouping_element can be one of:
84+
85+
( )
86+
expression
87+
( expression [, ...] )
88+
89+
and with_query is:
90+
91+
with_query_name [ ( column_name [, ...] ) ] AS [ [ NOT ] MATERIALIZED ] ( select | values | insert | update | delete )
92+
93+
TABLE [ ONLY ] table_name [ * ]"#
94+
}
95+
Function::Explain => {
96+
r#"
97+
Command: EXPLAIN
98+
Description: show the execution plan of a statement
99+
Syntax:
100+
EXPLAIN [ ANALYZE ] statement
101+
"#
102+
}
103+
Function::Show => {
104+
r#"
105+
Command: SHOW
106+
Description: show the value of a run-time parameter
107+
Syntax:
108+
SHOW name
109+
"#
110+
}
111+
Function::CreateTable => {
112+
r#"
113+
Command: CREATE TABLE
114+
Description: define a new table
115+
Syntax:
116+
CREATE [ EXTERNAL ] TABLE table_name ( [
117+
{ column_name data_type }
118+
[, ... ]
119+
] )
120+
"#
121+
}
122+
Function::CreateTableAs => {
123+
r#"
124+
Command: CREATE TABLE AS
125+
Description: define a new table from the results of a query
126+
Syntax:
127+
CREATE TABLE table_name
128+
[ (column_name [, ...] ) ]
129+
AS query
130+
[ WITH [ NO ] DATA ]
131+
"#
132+
}
133+
Function::Insert => {
134+
r#"
135+
Command: INSERT
136+
Description: create new rows in a table
137+
Syntax:
138+
INSERT INTO table_name [ ( column_name [, ...] ) ]
139+
{ VALUES ( { expression } [, ...] ) [, ...] }
140+
"#
141+
}
142+
Function::DropTable => {
143+
r#"
144+
Command: DROP TABLE
145+
Description: remove a table
146+
Syntax:
147+
DROP TABLE [ IF EXISTS ] name [, ...]
148+
"#
149+
}
150+
};
151+
Ok(details)
152+
}
153+
}
154+
155+
impl FromStr for Function {
156+
type Err = ();
157+
158+
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
159+
Ok(match s.trim().to_uppercase().as_str() {
160+
"SELECT" => Self::Select,
161+
"EXPLAIN" => Self::Explain,
162+
"SHOW" => Self::Show,
163+
"CREATE TABLE" => Self::CreateTable,
164+
"CREATE TABLE AS" => Self::CreateTableAs,
165+
"INSERT" => Self::Insert,
166+
"DROP TABLE" => Self::DropTable,
167+
_ => return Err(()),
168+
})
169+
}
170+
}
171+
172+
impl fmt::Display for Function {
173+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
174+
match *self {
175+
Function::Select => write!(f, "SELECT"),
176+
Function::Explain => write!(f, "EXPLAIN"),
177+
Function::Show => write!(f, "SHOW"),
178+
Function::CreateTable => write!(f, "CREATE TABLE"),
179+
Function::CreateTableAs => write!(f, "CREATE TABLE AS"),
180+
Function::Insert => write!(f, "INSERT"),
181+
Function::DropTable => write!(f, "DROP TABLE"),
182+
}
183+
}
184+
}
185+
186+
pub fn display_all_functions() -> Result<()> {
187+
println!("Available help:");
188+
let array = StringArray::from(
189+
ALL_FUNCTIONS
190+
.iter()
191+
.map(|f| format!("{}", f))
192+
.collect::<Vec<String>>(),
193+
);
194+
let schema = Schema::new(vec![Field::new("Function", DataType::Utf8, false)]);
195+
let batch = RecordBatch::try_new(Arc::new(schema), vec![Arc::new(array)])?;
196+
println!("{}", pretty_format_batches(&[batch]).unwrap());
197+
Ok(())
198+
}

datafusion-cli/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ pub const DATAFUSION_CLI_VERSION: &str = env!("CARGO_PKG_VERSION");
2222
pub mod command;
2323
pub mod context;
2424
pub mod exec;
25+
pub mod functions;
2526
pub mod helper;
2627
pub mod print_format;
2728
pub mod print_options;

0 commit comments

Comments
 (0)