feat: implement v1/sql/parse endpoint to parse GreptimeDB's SQL dialect (#5144)

* derive ser/de

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>

* impl method

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>

* fix typo

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>

* remove deserialize

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>

---------

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
This commit is contained in:
Ruihang Xia
2024-12-11 21:33:54 +08:00
committed by GitHub
parent 9da2e17d0e
commit 60f8dbf7f0
24 changed files with 128 additions and 58 deletions

2
Cargo.lock generated
View File

@@ -11295,6 +11295,7 @@ dependencies = [
"jsonb",
"lazy_static",
"regex",
"serde",
"serde_json",
"snafu 0.8.5",
"sqlparser 0.45.0 (git+https://github.com/GreptimeTeam/sqlparser-rs.git?rev=54a267ac89c09b11c0c88934690530807185d3e7)",
@@ -11371,6 +11372,7 @@ dependencies = [
"lazy_static",
"log",
"regex",
"serde",
"sqlparser 0.45.0 (registry+https://github.com/rust-lang/crates.io-index)",
"sqlparser_derive 0.2.2 (git+https://github.com/GreptimeTeam/sqlparser-rs.git?rev=54a267ac89c09b11c0c88934690530807185d3e7)",
]

View File

@@ -180,6 +180,7 @@ sysinfo = "0.30"
# on branch v0.44.x
sqlparser = { git = "https://github.com/GreptimeTeam/sqlparser-rs.git", rev = "54a267ac89c09b11c0c88934690530807185d3e7", features = [
"visitor",
"serde",
] }
strum = { version = "0.25", features = ["derive"] }
tempfile = "3"

View File

@@ -189,6 +189,13 @@ pub enum Error {
location: Location,
},
#[snafu(display("Failed to parse query"))]
FailedToParseQuery {
#[snafu(implicit)]
location: Location,
source: sql::error::Error,
},
#[snafu(display("Failed to parse InfluxDB line protocol"))]
InfluxdbLineProtocol {
#[snafu(implicit)]
@@ -651,7 +658,8 @@ impl ErrorExt for Error {
| OpenTelemetryLog { .. }
| UnsupportedJsonDataTypeForTag { .. }
| InvalidTableName { .. }
| PrepareStatementNotFound { .. } => StatusCode::InvalidArguments,
| PrepareStatementNotFound { .. }
| FailedToParseQuery { .. } => StatusCode::InvalidArguments,
Catalog { source, .. } => source.status_code(),
RowWriter { source, .. } => source.status_code(),

View File

@@ -755,6 +755,10 @@ impl HttpServer {
fn route_sql<S>(api_state: ApiState) -> Router<S> {
Router::new()
.route("/sql", routing::get(handler::sql).post(handler::sql))
.route(
"/sql/parse",
routing::get(handler::sql_parse).post(handler::sql_parse),
)
.route(
"/promql",
routing::get(handler::promql).post(handler::promql),

View File

@@ -30,8 +30,13 @@ use query::parser::{PromQuery, DEFAULT_LOOKBACK_STRING};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use session::context::{Channel, QueryContext, QueryContextRef};
use snafu::ResultExt;
use sql::dialect::GreptimeDbDialect;
use sql::parser::{ParseOptions, ParserContext};
use sql::statements::statement::Statement;
use super::header::collect_plan_metrics;
use crate::error::{FailedToParseQuerySnafu, InvalidQuerySnafu, Result};
use crate::http::result::arrow_result::ArrowResponse;
use crate::http::result::csv_result::CsvResponse;
use crate::http::result::error_result::ErrorResponse;
@@ -146,10 +151,31 @@ pub async fn sql(
resp.with_execution_time(start.elapsed().as_millis() as u64)
}
/// Handler to parse sql
#[axum_macros::debug_handler]
#[tracing::instrument(skip_all, fields(protocol = "http", request_type = "sql"))]
pub async fn sql_parse(
Query(query_params): Query<SqlQuery>,
Form(form_params): Form<SqlQuery>,
) -> Result<Json<Vec<Statement>>> {
let Some(sql) = query_params.sql.or(form_params.sql) else {
return InvalidQuerySnafu {
reason: "sql parameter is required.",
}
.fail();
};
let stmts =
ParserContext::create_with_dialect(&sql, &GreptimeDbDialect {}, ParseOptions::default())
.context(FailedToParseQuerySnafu)?;
Ok(stmts.into())
}
/// Create a response from query result
pub async fn from_output(
outputs: Vec<crate::error::Result<Output>>,
) -> Result<(Vec<GreptimeQueryOutput>, HashMap<String, Value>), ErrorResponse> {
) -> std::result::Result<(Vec<GreptimeQueryOutput>, HashMap<String, Value>), ErrorResponse> {
// TODO(sunng87): this api response structure cannot represent error well.
// It hides successful execution results from error response
let mut results = Vec::with_capacity(outputs.len());

View File

@@ -30,6 +30,7 @@ itertools.workspace = true
jsonb.workspace = true
lazy_static.workspace = true
regex.workspace = true
serde.workspace = true
serde_json.workspace = true
snafu.workspace = true
sqlparser.workspace = true

View File

@@ -14,12 +14,13 @@
use std::fmt::Display;
use serde::Serialize;
use sqlparser_derive::{Visit, VisitMut};
use crate::ast::Function;
/// `ADMIN` statement to execute some administration commands.
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub enum Admin {
/// Run a admin function.
Func(Function),

View File

@@ -18,10 +18,11 @@ use api::v1;
use common_query::AddColumnLocation;
use datatypes::schema::FulltextOptions;
use itertools::Itertools;
use serde::Serialize;
use sqlparser::ast::{ColumnDef, DataType, Ident, ObjectName, TableConstraint};
use sqlparser_derive::{Visit, VisitMut};
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct AlterTable {
pub table_name: ObjectName,
pub alter_operation: AlterTableOperation,
@@ -56,7 +57,7 @@ impl Display for AlterTable {
}
}
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub enum AlterTableOperation {
/// `ADD <table_constraint>`
AddConstraint(TableConstraint),
@@ -151,7 +152,7 @@ impl Display for AlterTableOperation {
}
}
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct KeyValueOption {
pub key: String,
pub value: String,
@@ -166,7 +167,7 @@ impl From<KeyValueOption> for v1::Option {
}
}
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct AlterDatabase {
pub database_name: ObjectName,
pub alter_operation: AlterDatabaseOperation,
@@ -197,7 +198,7 @@ impl Display for AlterDatabase {
}
}
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub enum AlterDatabaseOperation {
SetDatabaseOption { options: Vec<KeyValueOption> },
UnsetDatabaseOption { keys: Vec<String> },

View File

@@ -14,12 +14,13 @@
use std::fmt::Display;
use serde::Serialize;
use sqlparser::ast::ObjectName;
use sqlparser_derive::{Visit, VisitMut};
use crate::statements::OptionMap;
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub enum Copy {
CopyTable(CopyTable),
CopyDatabase(CopyDatabase),
@@ -34,7 +35,7 @@ impl Display for Copy {
}
}
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub enum CopyTable {
To(CopyTableArgument),
From(CopyTableArgument),
@@ -65,7 +66,7 @@ impl Display for CopyTable {
}
}
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub enum CopyDatabase {
To(CopyDatabaseArgument),
From(CopyDatabaseArgument),
@@ -96,7 +97,7 @@ impl Display for CopyDatabase {
}
}
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct CopyDatabaseArgument {
pub database_name: ObjectName,
pub with: OptionMap,
@@ -104,7 +105,7 @@ pub struct CopyDatabaseArgument {
pub location: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct CopyTableArgument {
pub table_name: ObjectName,
pub with: OptionMap,

View File

@@ -18,6 +18,7 @@ use std::fmt::{Display, Formatter};
use common_catalog::consts::FILE_ENGINE;
use datatypes::schema::FulltextOptions;
use itertools::Itertools;
use serde::Serialize;
use snafu::ResultExt;
use sqlparser::ast::{ColumnOptionDef, DataType, Expr, Query};
use sqlparser_derive::{Visit, VisitMut};
@@ -58,7 +59,7 @@ fn format_table_constraint(constraints: &[TableConstraint]) -> String {
}
/// Table constraint for create table statement.
#[derive(Debug, PartialEq, Eq, Clone, Visit, VisitMut)]
#[derive(Debug, PartialEq, Eq, Clone, Visit, VisitMut, Serialize)]
pub enum TableConstraint {
/// Primary key constraint.
PrimaryKey { columns: Vec<Ident> },
@@ -84,7 +85,7 @@ impl Display for TableConstraint {
}
}
#[derive(Debug, PartialEq, Eq, Clone, Visit, VisitMut)]
#[derive(Debug, PartialEq, Eq, Clone, Visit, VisitMut, Serialize)]
pub struct CreateTable {
/// Create if not exists
pub if_not_exists: bool,
@@ -100,7 +101,7 @@ pub struct CreateTable {
}
/// Column definition in `CREATE TABLE` statement.
#[derive(Debug, PartialEq, Eq, Clone, Visit, VisitMut)]
#[derive(Debug, PartialEq, Eq, Clone, Visit, VisitMut, Serialize)]
pub struct Column {
/// `ColumnDef` from `sqlparser::ast`
pub column_def: ColumnDef,
@@ -109,7 +110,7 @@ pub struct Column {
}
/// Column extensions for greptimedb dialect.
#[derive(Debug, PartialEq, Eq, Clone, Visit, VisitMut, Default)]
#[derive(Debug, PartialEq, Eq, Clone, Visit, VisitMut, Default, Serialize)]
pub struct ColumnExtensions {
/// Fulltext options.
pub fulltext_options: Option<OptionMap>,
@@ -172,7 +173,7 @@ impl ColumnExtensions {
}
}
#[derive(Debug, PartialEq, Eq, Clone, Visit, VisitMut)]
#[derive(Debug, PartialEq, Eq, Clone, Visit, VisitMut, Serialize)]
pub struct Partitions {
pub column_list: Vec<Ident>,
pub exprs: Vec<Expr>,
@@ -244,7 +245,7 @@ impl Display for CreateTable {
}
}
#[derive(Debug, PartialEq, Eq, Clone, Visit, VisitMut)]
#[derive(Debug, PartialEq, Eq, Clone, Visit, VisitMut, Serialize)]
pub struct CreateDatabase {
pub name: ObjectName,
/// Create if not exists
@@ -278,7 +279,7 @@ impl Display for CreateDatabase {
}
}
#[derive(Debug, PartialEq, Eq, Clone, Visit, VisitMut)]
#[derive(Debug, PartialEq, Eq, Clone, Visit, VisitMut, Serialize)]
pub struct CreateExternalTable {
/// Table name
pub name: ObjectName,
@@ -309,7 +310,7 @@ impl Display for CreateExternalTable {
}
}
#[derive(Debug, PartialEq, Eq, Clone, Visit, VisitMut)]
#[derive(Debug, PartialEq, Eq, Clone, Visit, VisitMut, Serialize)]
pub struct CreateTableLike {
/// Table name
pub table_name: ObjectName,
@@ -325,7 +326,7 @@ impl Display for CreateTableLike {
}
}
#[derive(Debug, PartialEq, Eq, Clone, Visit, VisitMut)]
#[derive(Debug, PartialEq, Eq, Clone, Visit, VisitMut, Serialize)]
pub struct CreateFlow {
/// Flow name
pub flow_name: ObjectName,
@@ -367,7 +368,7 @@ impl Display for CreateFlow {
}
/// Create SQL view statement.
#[derive(Debug, PartialEq, Eq, Clone, Visit, VisitMut)]
#[derive(Debug, PartialEq, Eq, Clone, Visit, VisitMut, Serialize)]
pub struct CreateView {
/// View name
pub name: ObjectName,

View File

@@ -14,6 +14,7 @@
use std::fmt::Display;
use serde::Serialize;
use sqlparser::ast::ObjectName;
use sqlparser_derive::{Visit, VisitMut};
@@ -22,7 +23,7 @@ use super::query::Query;
/// Represents a DECLARE CURSOR statement
///
/// This statement will carry a SQL query
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct DeclareCursor {
pub cursor_name: ObjectName,
pub query: Box<Query>,
@@ -35,7 +36,7 @@ impl Display for DeclareCursor {
}
/// Represents a FETCH FROM cursor statement
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct FetchCursor {
pub cursor_name: ObjectName,
pub fetch_size: u64,
@@ -48,7 +49,7 @@ impl Display for FetchCursor {
}
/// Represents a CLOSE cursor statement
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct CloseCursor {
pub cursor_name: ObjectName,
}

View File

@@ -12,10 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use serde::Serialize;
use sqlparser::ast::Statement;
use sqlparser_derive::{Visit, VisitMut};
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct Delete {
pub inner: Statement,
}

View File

@@ -14,11 +14,12 @@
use std::fmt::Display;
use serde::Serialize;
use sqlparser::ast::ObjectName;
use sqlparser_derive::{Visit, VisitMut};
/// SQL structure for `DESCRIBE TABLE`.
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct DescribeTable {
name: ObjectName,
}

View File

@@ -14,11 +14,12 @@
use std::fmt::Display;
use serde::Serialize;
use sqlparser::ast::ObjectName;
use sqlparser_derive::{Visit, VisitMut};
/// DROP TABLE statement.
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct DropTable {
table_names: Vec<ObjectName>,
@@ -62,7 +63,7 @@ impl Display for DropTable {
}
/// DROP DATABASE statement.
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct DropDatabase {
name: ObjectName,
/// drop table if exists
@@ -99,7 +100,7 @@ impl Display for DropDatabase {
}
/// DROP FLOW statement.
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct DropFlow {
flow_name: ObjectName,
/// drop flow if exists
@@ -138,7 +139,7 @@ impl Display for DropFlow {
}
/// `DROP VIEW` statement.
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct DropView {
// The view name
pub view_name: ObjectName,

View File

@@ -14,13 +14,14 @@
use std::fmt::{Display, Formatter};
use serde::Serialize;
use sqlparser::ast::Statement as SpStatement;
use sqlparser_derive::{Visit, VisitMut};
use crate::error::Error;
/// Explain statement.
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct Explain {
pub inner: SpStatement,
}

View File

@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use serde::Serialize;
use sqlparser::ast::{ObjectName, Query, SetExpr, Statement, UnaryOperator, Values};
use sqlparser::parser::ParserError;
use sqlparser_derive::{Visit, VisitMut};
@@ -20,7 +21,7 @@ use crate::ast::{Expr, Value};
use crate::error::Result;
use crate::statements::query::Query as GtQuery;
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct Insert {
// Can only be sqlparser::ast::Statement::Insert variant
pub inner: Statement,

View File

@@ -16,14 +16,16 @@ use std::collections::{BTreeMap, HashMap};
use std::ops::ControlFlow;
use common_base::secrets::{ExposeSecret, ExposeSecretMut, SecretString};
use serde::Serialize;
use sqlparser::ast::{Visit, VisitMut, Visitor, VisitorMut};
const REDACTED_OPTIONS: [&str; 2] = ["access_key_id", "secret_access_key"];
/// Options hashmap.
#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, Serialize)]
pub struct OptionMap {
options: BTreeMap<String, String>,
#[serde(skip_serializing)]
secrets: BTreeMap<String, SecretString>,
}

View File

@@ -14,13 +14,14 @@
use std::fmt;
use serde::Serialize;
use sqlparser::ast::Query as SpQuery;
use sqlparser_derive::{Visit, VisitMut};
use crate::error::Error;
/// Query statement instance.
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct Query {
pub inner: SpQuery,
}

View File

@@ -14,11 +14,12 @@
use std::fmt::Display;
use serde::Serialize;
use sqlparser::ast::{Expr, ObjectName};
use sqlparser_derive::{Visit, VisitMut};
/// SET variables statement.
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct SetVariables {
pub variable: ObjectName,
pub value: Vec<Expr>,

View File

@@ -14,12 +14,13 @@
use std::fmt::{self, Display};
use serde::Serialize;
use sqlparser_derive::{Visit, VisitMut};
use crate::ast::{Expr, Ident, ObjectName};
/// Show kind for SQL expressions like `SHOW DATABASE` or `SHOW TABLE`
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub enum ShowKind {
All,
Like(Ident),
@@ -46,14 +47,14 @@ macro_rules! format_kind {
}
/// SQL structure for `SHOW DATABASES`.
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct ShowDatabases {
pub kind: ShowKind,
pub full: bool,
}
/// The SQL `SHOW COLUMNS` statement
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct ShowColumns {
pub kind: ShowKind,
pub table: String,
@@ -77,7 +78,7 @@ impl Display for ShowColumns {
}
/// The SQL `SHOW INDEX` statement
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct ShowIndex {
pub kind: ShowKind,
pub table: String,
@@ -118,7 +119,7 @@ impl Display for ShowDatabases {
}
/// SQL structure for `SHOW TABLES`.
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct ShowTables {
pub kind: ShowKind,
pub database: Option<String>,
@@ -142,7 +143,7 @@ impl Display for ShowTables {
}
/// SQL structure for `SHOW TABLE STATUS`.
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct ShowTableStatus {
pub kind: ShowKind,
pub database: Option<String>,
@@ -162,7 +163,7 @@ impl Display for ShowTableStatus {
}
/// SQL structure for `SHOW CREATE DATABASE`.
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct ShowCreateDatabase {
pub database_name: ObjectName,
}
@@ -175,7 +176,7 @@ impl Display for ShowCreateDatabase {
}
/// SQL structure for `SHOW CREATE TABLE`.
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct ShowCreateTable {
pub table_name: ObjectName,
}
@@ -188,7 +189,7 @@ impl Display for ShowCreateTable {
}
/// SQL structure for `SHOW CREATE FLOW`.
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct ShowCreateFlow {
pub flow_name: ObjectName,
}
@@ -201,7 +202,7 @@ impl Display for ShowCreateFlow {
}
/// SQL structure for `SHOW FLOWS`.
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct ShowFlows {
pub kind: ShowKind,
pub database: Option<String>,
@@ -220,7 +221,7 @@ impl Display for ShowFlows {
}
/// SQL structure for `SHOW CREATE VIEW`.
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct ShowCreateView {
pub view_name: ObjectName,
}
@@ -233,7 +234,7 @@ impl Display for ShowCreateView {
}
/// SQL structure for `SHOW VIEWS`.
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct ShowViews {
pub kind: ShowKind,
pub database: Option<String>,
@@ -252,7 +253,7 @@ impl Display for ShowViews {
}
/// SQL structure for `SHOW VARIABLES xxx`.
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct ShowVariables {
pub variable: ObjectName,
}
@@ -265,7 +266,7 @@ impl Display for ShowVariables {
}
/// SQL structure for "SHOW STATUS"
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct ShowStatus {}
impl Display for ShowStatus {

View File

@@ -15,12 +15,14 @@
use std::fmt::Display;
use datafusion_sql::parser::Statement as DfStatement;
use serde::Serialize;
use sqlparser::ast::Statement as SpStatement;
use sqlparser_derive::{Visit, VisitMut};
use crate::error::{ConvertToDfStatementSnafu, Error};
use crate::statements::admin::Admin;
use crate::statements::alter::{AlterDatabase, AlterTable};
use crate::statements::copy::Copy;
use crate::statements::create::{
CreateDatabase, CreateExternalTable, CreateFlow, CreateTable, CreateTableLike, CreateView,
};
@@ -42,7 +44,7 @@ use crate::statements::truncate::TruncateTable;
/// Tokens parsed by `DFParser` are converted into these values.
#[allow(clippy::large_enum_variant)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub enum Statement {
// Query
Query(Box<Query>),
@@ -107,7 +109,8 @@ pub enum Statement {
// EXPLAIN QUERY
Explain(Explain),
// COPY
Copy(crate::statements::copy::Copy),
Copy(Copy),
// Telemetry Query Language
Tql(Tql),
// TRUNCATE TABLE
TruncateTable(TruncateTable),

View File

@@ -14,9 +14,10 @@
use std::fmt::Display;
use serde::Serialize;
use sqlparser_derive::{Visit, VisitMut};
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub enum Tql {
Eval(TqlEval),
Explain(TqlExplain),
@@ -49,7 +50,7 @@ fn format_tql(
}
/// TQL EVAL (<start>, <end>, <step>, [lookback]) <promql>
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct TqlEval {
pub start: String,
pub end: String,
@@ -74,7 +75,7 @@ impl Display for TqlEval {
/// TQL EXPLAIN [VERBOSE] [<start>, <end>, <step>, [lookback]] <promql>
/// doesn't execute the query but tells how the query would be executed (similar to SQL EXPLAIN).
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct TqlExplain {
pub start: String,
pub end: String,
@@ -103,7 +104,7 @@ impl Display for TqlExplain {
/// TQL ANALYZE [VERBOSE] (<start>, <end>, <step>, [lookback]) <promql>
/// executes the plan and tells the detailed per-step execution time (similar to SQL ANALYZE).
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct TqlAnalyze {
pub start: String,
pub end: String,

View File

@@ -14,11 +14,12 @@
use std::fmt::Display;
use serde::Serialize;
use sqlparser::ast::ObjectName;
use sqlparser_derive::{Visit, VisitMut};
/// TRUNCATE TABLE statement.
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
pub struct TruncateTable {
table_name: ObjectName,
}

View File

@@ -361,6 +361,14 @@ pub async fn test_sql_api(store_type: StorageType) {
let body = serde_json::from_str::<ErrorResponse>(&res.text().await).unwrap();
assert_eq!(body.code(), ErrorCode::DatabaseNotFound as u32);
// test parse method
let res = client.get("/v1/sql/parse?sql=desc table t").send().await;
assert_eq!(res.status(), StatusCode::OK);
assert_eq!(
res.text().await,
"[{\"DescribeTable\":{\"name\":[{\"value\":\"t\",\"quote_style\":null}]}}]"
);
// test timezone header
let res = client
.get("/v1/sql?&sql=show variables system_time_zone")