mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-05-25 01:10:37 +00:00
refactor: datanode starts frontend (#471)
* refactor: dependency, from frontend depends on datanode to datanode depends on frontend * wip: start frontend in datanode * wip: migrate create database to frontend * wip: impl alter table * fix: CR comments
This commit is contained in:
@@ -5,6 +5,7 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
api = { path = "../api" }
|
||||
catalog = { path = "../catalog" }
|
||||
common-catalog = { path = "../common/catalog" }
|
||||
common-error = { path = "../common/error" }
|
||||
|
||||
@@ -92,6 +92,24 @@ pub enum Error {
|
||||
#[snafu(backtrace)]
|
||||
source: datatypes::error::Error,
|
||||
},
|
||||
|
||||
#[snafu(display("Unsupported ALTER TABLE statement: {}", msg))]
|
||||
UnsupportedAlterTableStatement { msg: String, backtrace: Backtrace },
|
||||
|
||||
#[snafu(display("Failed to serialize column default constraint, source: {}", source))]
|
||||
SerializeColumnDefaultConstraint {
|
||||
#[snafu(backtrace)]
|
||||
source: datatypes::error::Error,
|
||||
},
|
||||
|
||||
#[snafu(display(
|
||||
"Failed to convert data type to gRPC data type defined in proto, source: {}",
|
||||
source
|
||||
))]
|
||||
ConvertToGrpcDataType {
|
||||
#[snafu(backtrace)]
|
||||
source: api::error::Error,
|
||||
},
|
||||
}
|
||||
|
||||
impl ErrorExt for Error {
|
||||
@@ -112,6 +130,9 @@ impl ErrorExt for Error {
|
||||
InvalidDatabaseName { .. } | ColumnTypeMismatch { .. } | InvalidTableName { .. } => {
|
||||
StatusCode::InvalidArguments
|
||||
}
|
||||
UnsupportedAlterTableStatement { .. } => StatusCode::InvalidSyntax,
|
||||
SerializeColumnDefaultConstraint { source, .. } => source.status_code(),
|
||||
ConvertToGrpcDataType { source, .. } => source.status_code(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ pub mod statement;
|
||||
|
||||
use std::str::FromStr;
|
||||
|
||||
use api::helper::ColumnDataTypeWrapper;
|
||||
use common_catalog::consts::{DEFAULT_CATALOG_NAME, DEFAULT_SCHEMA_NAME};
|
||||
use common_time::Timestamp;
|
||||
use datatypes::prelude::ConcreteDataType;
|
||||
@@ -20,7 +21,8 @@ use crate::ast::{
|
||||
Value as SqlValue,
|
||||
};
|
||||
use crate::error::{
|
||||
self, ColumnTypeMismatchSnafu, ParseSqlValueSnafu, Result, UnsupportedDefaultValueSnafu,
|
||||
self, ColumnTypeMismatchSnafu, ConvertToGrpcDataTypeSnafu, ParseSqlValueSnafu, Result,
|
||||
SerializeColumnDefaultConstraintSnafu, UnsupportedDefaultValueSnafu,
|
||||
};
|
||||
|
||||
/// Converts maybe fully-qualified table name (`<catalog>.<schema>.<table>` or `<table>` when
|
||||
@@ -239,6 +241,31 @@ pub fn column_def_to_schema(column_def: &ColumnDef, is_time_index: bool) -> Resu
|
||||
})
|
||||
}
|
||||
|
||||
/// Convert `ColumnDef` in sqlparser to `ColumnDef` in gRPC proto.
|
||||
fn sql_column_def_to_grpc_column_def(col: ColumnDef) -> Result<api::v1::ColumnDef> {
|
||||
let name = col.name.value.clone();
|
||||
let data_type = sql_data_type_to_concrete_data_type(&col.data_type)?;
|
||||
let nullable = col
|
||||
.options
|
||||
.iter()
|
||||
.any(|o| matches!(o.option, ColumnOption::Null));
|
||||
|
||||
let default_constraint = parse_column_default_constraint(&name, &data_type, &col.options)?
|
||||
.map(ColumnDefaultConstraint::try_into) // serialize default constraint to bytes
|
||||
.transpose()
|
||||
.context(SerializeColumnDefaultConstraintSnafu)?;
|
||||
|
||||
let data_type = ColumnDataTypeWrapper::try_from(data_type)
|
||||
.context(ConvertToGrpcDataTypeSnafu)?
|
||||
.datatype() as i32;
|
||||
Ok(api::v1::ColumnDef {
|
||||
name,
|
||||
datatype: data_type,
|
||||
is_nullable: nullable,
|
||||
default_constraint,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn sql_data_type_to_concrete_data_type(data_type: &SqlDataType) -> Result<ConcreteDataType> {
|
||||
match data_type {
|
||||
SqlDataType::BigInt(_) => Ok(ConcreteDataType::int64_datatype()),
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
use api::v1::{alter_expr, AlterExpr};
|
||||
use sqlparser::ast::{ColumnDef, ObjectName, TableConstraint};
|
||||
|
||||
use crate::error::UnsupportedAlterTableStatementSnafu;
|
||||
use crate::statements::{sql_column_def_to_grpc_column_def, table_idents_to_full_name};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct AlterTable {
|
||||
table_name: ObjectName,
|
||||
@@ -29,4 +33,36 @@ pub enum AlterTableOperation {
|
||||
AddConstraint(TableConstraint),
|
||||
/// `ADD [ COLUMN ] <column_def>`
|
||||
AddColumn { column_def: ColumnDef },
|
||||
// TODO(hl): support remove column
|
||||
}
|
||||
|
||||
/// Convert `AlterTable` statement to `AlterExpr` for gRPC
|
||||
impl TryFrom<AlterTable> for AlterExpr {
|
||||
type Error = crate::error::Error;
|
||||
|
||||
fn try_from(value: AlterTable) -> Result<Self, Self::Error> {
|
||||
let (catalog, schema, table) = table_idents_to_full_name(&value.table_name)?;
|
||||
|
||||
let kind = match value.alter_operation {
|
||||
AlterTableOperation::AddConstraint(_) => {
|
||||
return UnsupportedAlterTableStatementSnafu {
|
||||
msg: "ADD CONSTRAINT not supported yet.",
|
||||
}
|
||||
.fail();
|
||||
}
|
||||
AlterTableOperation::AddColumn { column_def } => {
|
||||
alter_expr::Kind::AddColumn(api::v1::AddColumn {
|
||||
column_def: Some(sql_column_def_to_grpc_column_def(column_def)?),
|
||||
})
|
||||
}
|
||||
};
|
||||
let expr = AlterExpr {
|
||||
catalog_name: Some(catalog),
|
||||
schema_name: Some(schema),
|
||||
table_name: table,
|
||||
kind: Some(kind),
|
||||
};
|
||||
|
||||
Ok(expr)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user