Skip to content

Commit

Permalink
feat: implement DESCRIBE TABLE (GreptimeTeam#558)
Browse files Browse the repository at this point in the history
Also need to support describe table in other catalog/schema
  • Loading branch information
morigs authored Nov 18, 2022
1 parent 6d762aa commit e1f3262
Showing 15 changed files with 620 additions and 7 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/datanode/src/instance/sql.rs
Original file line number Diff line number Diff line change
@@ -115,6 +115,11 @@ impl Instance {
Statement::ShowTables(stmt) => {
self.sql_handler.execute(SqlRequest::ShowTables(stmt)).await
}
Statement::DescribeTable(stmt) => {
self.sql_handler
.execute(SqlRequest::DescribeTable(stmt))
.await
}
Statement::ShowCreateTable(_stmt) => {
unimplemented!("SHOW CREATE TABLE is unimplemented yet");
}
7 changes: 6 additions & 1 deletion src/datanode/src/sql.rs
Original file line number Diff line number Diff line change
@@ -16,8 +16,9 @@
use catalog::CatalogManagerRef;
use common_query::Output;
use query::sql::{show_databases, show_tables};
use query::sql::{describe_table, show_databases, show_tables};
use snafu::{OptionExt, ResultExt};
use sql::statements::describe::DescribeTable;
use sql::statements::show::{ShowDatabases, ShowTables};
use table::engine::{EngineContext, TableEngineRef, TableReference};
use table::requests::*;
@@ -37,6 +38,7 @@ pub enum SqlRequest {
Alter(AlterTableRequest),
ShowDatabases(ShowDatabases),
ShowTables(ShowTables),
DescribeTable(DescribeTable),
}

// Handler to execute SQL except query
@@ -65,6 +67,9 @@ impl SqlHandler {
SqlRequest::ShowTables(stmt) => {
show_tables(stmt, self.catalog_manager.clone()).context(error::ExecuteSqlSnafu)
}
SqlRequest::DescribeTable(stmt) => {
describe_table(stmt, self.catalog_manager.clone()).context(error::ExecuteSqlSnafu)
}
}
}

10 changes: 10 additions & 0 deletions src/datatypes/src/schema/constraint.rs
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use std::fmt::{Display, Formatter};
use std::sync::Arc;

use common_time::util;
@@ -53,6 +54,15 @@ impl TryFrom<ColumnDefaultConstraint> for Vec<u8> {
}
}

impl Display for ColumnDefaultConstraint {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
ColumnDefaultConstraint::Function(expr) => write!(f, "{}", expr),
ColumnDefaultConstraint::Value(v) => write!(f, "{}", v),
}
}
}

impl ColumnDefaultConstraint {
/// Returns a default null constraint.
pub fn null_value() -> ColumnDefaultConstraint {
92 changes: 91 additions & 1 deletion src/datatypes/src/value.rs
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@
// limitations under the License.

use std::cmp::Ordering;
use std::fmt::{Display, Formatter};

use common_base::bytes::{Bytes, StringBytes};
use common_time::date::Date;
@@ -62,6 +63,47 @@ pub enum Value {
List(ListValue),
}

impl Display for Value {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Value::Null => write!(f, "{}", self.data_type().name()),
Value::Boolean(v) => write!(f, "{}", v),
Value::UInt8(v) => write!(f, "{}", v),
Value::UInt16(v) => write!(f, "{}", v),
Value::UInt32(v) => write!(f, "{}", v),
Value::UInt64(v) => write!(f, "{}", v),
Value::Int8(v) => write!(f, "{}", v),
Value::Int16(v) => write!(f, "{}", v),
Value::Int32(v) => write!(f, "{}", v),
Value::Int64(v) => write!(f, "{}", v),
Value::Float32(v) => write!(f, "{}", v),
Value::Float64(v) => write!(f, "{}", v),
Value::String(v) => write!(f, "{}", v.as_utf8()),
Value::Binary(v) => {
let hex = v
.iter()
.map(|b| format!("{:02x}", b))
.collect::<Vec<String>>()
.join("");
write!(f, "{}", hex)
}
Value::Date(v) => write!(f, "{}", v),
Value::DateTime(v) => write!(f, "{}", v),
Value::Timestamp(v) => write!(f, "{}", v.to_iso8601_string()),
Value::List(v) => {
let default = Box::new(vec![]);
let items = v.items().as_ref().unwrap_or(&default);
let items = items
.iter()
.map(|i| i.to_string())
.collect::<Vec<String>>()
.join(", ");
write!(f, "{}[{}]", v.datatype.name(), items)
}
}
}
}

impl Value {
/// Returns data type of the value.
///
@@ -624,6 +666,7 @@ impl<'a> PartialOrd for ListValueRef<'a> {
#[cfg(test)]
mod tests {
use arrow::datatypes::DataType as ArrowDataType;
use num_traits::Float;

use super::*;

@@ -1033,7 +1076,7 @@ mod tests {
);
assert_eq!(
serde_json::Value::Number(5000i32.into()),
to_json(Value::Date(common_time::date::Date::new(5000)))
to_json(Value::Date(Date::new(5000)))
);
assert_eq!(
serde_json::Value::Number(5000i64.into()),
@@ -1217,4 +1260,51 @@ mod tests {
);
assert_eq!(ValueRef::String(hello), ValueRef::from(hello));
}

#[test]
fn test_display() {
assert_eq!(Value::Null.to_string(), "Null");
assert_eq!(Value::UInt8(8).to_string(), "8");
assert_eq!(Value::UInt16(16).to_string(), "16");
assert_eq!(Value::UInt32(32).to_string(), "32");
assert_eq!(Value::UInt64(64).to_string(), "64");
assert_eq!(Value::Int8(-8).to_string(), "-8");
assert_eq!(Value::Int16(-16).to_string(), "-16");
assert_eq!(Value::Int32(-32).to_string(), "-32");
assert_eq!(Value::Int64(-64).to_string(), "-64");
assert_eq!(Value::Float32((-32.123).into()).to_string(), "-32.123");
assert_eq!(Value::Float64((-64.123).into()).to_string(), "-64.123");
assert_eq!(Value::Float64(OrderedF64::infinity()).to_string(), "inf");
assert_eq!(Value::Float64(OrderedF64::nan()).to_string(), "NaN");
assert_eq!(Value::String(StringBytes::from("123")).to_string(), "123");
assert_eq!(
Value::Binary(Bytes::from(vec![1, 2, 3])).to_string(),
"010203"
);
assert_eq!(Value::Date(Date::new(0)).to_string(), "1970-01-01");
assert_eq!(
Value::DateTime(DateTime::new(0)).to_string(),
"1970-01-01 00:00:00"
);
assert_eq!(
Value::Timestamp(Timestamp::new(1000, TimeUnit::Millisecond)).to_string(),
"1970-01-01 00:00:01+0000"
);
assert_eq!(
Value::List(ListValue::new(
Some(Box::new(vec![Value::Int8(1), Value::Int8(2)])),
ConcreteDataType::int8_datatype(),
))
.to_string(),
"Int8[1, 2]"
);
assert_eq!(
Value::List(ListValue::new(
Some(Box::new(vec![])),
ConcreteDataType::timestamp_datatype(TimeUnit::Millisecond),
))
.to_string(),
"Timestamp[]"
);
}
}
4 changes: 3 additions & 1 deletion src/frontend/src/instance.rs
Original file line number Diff line number Diff line change
@@ -608,7 +608,9 @@ impl SqlQueryHandler for Instance {
.context(server_error::ExecuteQuerySnafu { query })
}

Statement::ShowDatabases(_) | Statement::ShowTables(_) => self
Statement::ShowDatabases(_)
| Statement::ShowTables(_)
| Statement::DescribeTable(_) => self
.handle_select(Select::Sql(query.to_string()), stmt)
.await
.map_err(BoxedError::new)
4 changes: 3 additions & 1 deletion src/frontend/src/instance/distributed.rs
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@ use meta_client::rpc::{
CreateRequest as MetaCreateRequest, Partition as MetaPartition, PutRequest, RouteResponse,
TableName, TableRoute,
};
use query::sql::{show_databases, show_tables};
use query::sql::{describe_table, show_databases, show_tables};
use query::{QueryEngineFactory, QueryEngineRef};
use snafu::{ensure, OptionExt, ResultExt};
use sql::statements::create::Partitions;
@@ -141,6 +141,8 @@ impl DistInstance {
.context(error::ExecuteSqlSnafu { sql }),
Statement::ShowTables(stmt) => show_tables(stmt, self.catalog_manager.clone())
.context(error::ExecuteSqlSnafu { sql }),
Statement::DescribeTable(stmt) => describe_table(stmt, self.catalog_manager.clone())
.context(error::ExecuteSqlSnafu { sql }),
_ => unreachable!(),
}
}
1 change: 1 addition & 0 deletions src/query/Cargo.toml
Original file line number Diff line number Diff line change
@@ -24,6 +24,7 @@ datatypes = { path = "../datatypes" }
futures = "0.3"
futures-util = "0.3"
metrics = "0.20"
once_cell = "1.10"
serde = "1.0"
serde_json = "1.0"
snafu = { version = "0.7", features = ["backtraces"] }
1 change: 1 addition & 0 deletions src/query/src/datafusion/planner.rs
Original file line number Diff line number Diff line change
@@ -66,6 +66,7 @@ where
Statement::ShowTables(_)
| Statement::ShowDatabases(_)
| Statement::ShowCreateTable(_)
| Statement::DescribeTable(_)
| Statement::CreateTable(_)
| Statement::CreateDatabase(_)
| Statement::Alter(_)
10 changes: 7 additions & 3 deletions src/query/src/error.rs
Original file line number Diff line number Diff line change
@@ -44,6 +44,9 @@ pub enum InnerError {
backtrace: Backtrace,
},

#[snafu(display("Table not found: {}", table))]
TableNotFound { table: String, backtrace: Backtrace },

#[snafu(display("Failed to do vector computation, source: {}", source))]
VectorComputation {
#[snafu(backtrace)]
@@ -62,9 +65,10 @@ impl ErrorExt for InnerError {
use InnerError::*;

match self {
UnsupportedExpr { .. } | CatalogNotFound { .. } | SchemaNotFound { .. } => {
StatusCode::InvalidArguments
}
UnsupportedExpr { .. }
| CatalogNotFound { .. }
| SchemaNotFound { .. }
| TableNotFound { .. } => StatusCode::InvalidArguments,
Catalog { source } => source.status_code(),
VectorComputation { source } => source.status_code(),
CreateRecordBatch { source } => source.status_code(),
Loading

0 comments on commit e1f3262

Please sign in to comment.