Skip to content

Commit ac016bd

Browse files
authored
Add logical plan creation from SHOW OBJECTS AST (#202)
1 parent 9eb1d6c commit ac016bd

File tree

2 files changed

+54
-7
lines changed

2 files changed

+54
-7
lines changed

crates/runtime/src/datafusion/execution.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,12 @@ impl SqlExecutor {
8787
// statement = self.update_statement_references(statement, warehouse_name);
8888
// query = statement.to_string();
8989

90+
// TODO: Code should be organized in a better way
91+
// 1. Single place to parse SQL strings into AST
92+
// 2. Single place to update AST
93+
// 3. Single place to construct Logical plan from this AST
94+
// 4. Single place to rewrite-optimize-adjust logical plan
95+
// etc
9096
if let DFStatement::Statement(s) = statement {
9197
match *s {
9298
Statement::CreateTable { .. } => {
@@ -122,6 +128,7 @@ impl SqlExecutor {
122128
| Statement::Insert { .. }
123129
| Statement::ShowSchemas { .. }
124130
| Statement::ShowVariable { .. }
131+
| Statement::ShowObjects { .. }
125132
| Statement::Update { .. } => {
126133
return Box::pin(self.execute_with_custom_plan(&query, warehouse_name)).await;
127134
}

crates/runtime/src/datafusion/planner.rs

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,6 @@ where
6262
}
6363
}
6464

65-
pub fn statement_to_plan(&self, statement: DFStatement) -> Result<LogicalPlan> {
66-
match statement {
67-
DFStatement::Statement(s) => self.sql_statement_to_plan(*s),
68-
_ => self.inner.statement_to_plan(statement),
69-
}
70-
}
71-
7265
/// Custom implementation of `sql_statement_to_plan`
7366
pub fn sql_statement_to_plan(&self, statement: Statement) -> Result<LogicalPlan> {
7467
// Check for a custom statement type
@@ -85,6 +78,7 @@ where
8578
}
8679

8780
/// Handle custom statements not supported by the original `SqlToRel`
81+
#[allow(clippy::too_many_lines)]
8882
fn handle_custom_statement(&self, statement: Statement) -> Result<LogicalPlan> {
8983
let planner_context: &mut PlannerContext = &mut PlannerContext::new();
9084
// Example: Custom handling for a specific statement
@@ -95,6 +89,18 @@ where
9589
| Statement::Update { .. } => Ok(LogicalPlan::default()),
9690
Statement::ShowSchemas { .. } => self.show_variable_to_plan(&["schemas".into()]),
9791
Statement::ShowVariable { variable } => self.show_variable_to_plan(&variable),
92+
Statement::ShowObjects {
93+
terse: _,
94+
show_options,
95+
} => {
96+
let Some(show_in) = show_options.show_in else {
97+
return plan_err!("Unsupported show statement: missing show_in");
98+
};
99+
let Some(parent_name) = show_in.parent_name else {
100+
return plan_err!("Unsupported show statement: missing parent_name");
101+
};
102+
self.show_objects_to_plan(&parent_name)
103+
}
98104
Statement::Drop {
99105
object_type,
100106
if_exists,
@@ -232,6 +238,40 @@ where
232238
}
233239
}
234240

241+
fn show_objects_to_plan(&self, parent: &ObjectName) -> Result<LogicalPlan> {
242+
// Only support listing objects in schema for now
243+
match parent.0.len() {
244+
2 => {
245+
let (catalog, schema) = (parent.0[0].value.clone(), parent.0[1].value.clone());
246+
247+
// Create query to list objects in schema
248+
let columns = [
249+
"table_catalog as 'database_name'",
250+
"table_schema as 'schema_name'",
251+
"table_name as 'name'",
252+
"case when table_type='BASE TABLE' then 'TABLE' else table_type end as 'kind'",
253+
"null as 'comment'",
254+
]
255+
.join(", ");
256+
// TODO: views?
257+
// TODO: Return programmatically constructed plan
258+
let query = format!("SELECT {columns} FROM information_schema.tables where table_schema = '{schema}' and table_catalog = '{catalog}'");
259+
let mut statements = DFParser::parse_sql(query.as_str())?;
260+
statements.pop_front().map_or_else(
261+
|| plan_err!("Failed to parse SQL statement"),
262+
|statement| {
263+
if let DFStatement::Statement(s) = statement {
264+
self.sql_statement_to_plan(*s)
265+
} else {
266+
plan_err!("Failed to parse SQL statement")
267+
}
268+
},
269+
)
270+
}
271+
_ => plan_err!("Unsupported show objects: {:?}", parent),
272+
}
273+
}
274+
235275
fn show_variable_to_plan(&self, variable: &[Ident]) -> Result<LogicalPlan> {
236276
//println!("SHOW variable: {:?}", variable);
237277
if !self.inner.has_table("information_schema", "df_settings") {

0 commit comments

Comments
 (0)