Skip to content

Commit 5873b05

Browse files
committed
[clickhouse] Add support for Engine parameters parsing
1 parent ef69d8a commit 5873b05

File tree

5 files changed

+45
-9
lines changed

5 files changed

+45
-9
lines changed

src/ast/helpers/stmt_create_table.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ use serde::{Deserialize, Serialize};
88
use sqlparser_derive::{Visit, VisitMut};
99

1010
use crate::ast::{
11-
ColumnDef, FileFormat, HiveDistributionStyle, HiveFormat, Ident, ObjectName, OnCommit, Query,
12-
SqlOption, Statement, TableConstraint,
11+
ColumnDef, EngineSpec, FileFormat, HiveDistributionStyle, HiveFormat, Ident, ObjectName,
12+
OnCommit, Query, SqlOption, Statement, TableConstraint,
1313
};
1414
use crate::parser::ParserError;
1515

@@ -64,7 +64,7 @@ pub struct CreateTableBuilder {
6464
pub without_rowid: bool,
6565
pub like: Option<ObjectName>,
6666
pub clone: Option<ObjectName>,
67-
pub engine: Option<String>,
67+
pub engine: Option<EngineSpec>,
6868
pub comment: Option<String>,
6969
pub auto_increment_offset: Option<u32>,
7070
pub default_charset: Option<String>,
@@ -196,7 +196,7 @@ impl CreateTableBuilder {
196196
self
197197
}
198198

199-
pub fn engine(mut self, engine: Option<String>) -> Self {
199+
pub fn engine(mut self, engine: Option<EngineSpec>) -> Self {
200200
self.engine = engine;
201201
self
202202
}

src/ast/mod.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,24 @@ impl fmt::Display for ObjectName {
174174
}
175175
}
176176

177+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
178+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
179+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
180+
pub struct EngineSpec {
181+
pub name: String,
182+
pub options: Option<Vec<Expr>>,
183+
}
184+
185+
impl fmt::Display for EngineSpec {
186+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
187+
if let Some(opts) = &self.options {
188+
write!(f, "{}({})", self.name, display_comma_separated(&opts))
189+
} else {
190+
write!(f, "{}", self.name)
191+
}
192+
}
193+
}
194+
177195
/// Represents an Array Expression, either
178196
/// `ARRAY[..]`, or `[..]`
179197
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
@@ -1373,7 +1391,7 @@ pub enum Statement {
13731391
without_rowid: bool,
13741392
like: Option<ObjectName>,
13751393
clone: Option<ObjectName>,
1376-
engine: Option<String>,
1394+
engine: Option<EngineSpec>,
13771395
comment: Option<String>,
13781396
auto_increment_offset: Option<u32>,
13791397
default_charset: Option<String>,

src/parser/mod.rs

+18-3
Original file line numberDiff line numberDiff line change
@@ -3669,10 +3669,25 @@ impl<'a> Parser<'a> {
36693669
let engine = if self.parse_keyword(Keyword::ENGINE) {
36703670
self.expect_token(&Token::Eq)?;
36713671
let next_token = self.next_token();
3672-
match next_token.token {
3673-
Token::Word(w) => Some(w.value),
3672+
let engine_name = match next_token.token {
3673+
Token::Word(w) => w.value,
36743674
_ => self.expected("identifier", next_token)?,
3675-
}
3675+
};
3676+
let engine_options = if self.consume_token(&Token::LParen) {
3677+
let columns = if self.peek_token() != Token::RParen {
3678+
self.parse_comma_separated(|p| p.parse_expr())?
3679+
} else {
3680+
vec![]
3681+
};
3682+
self.expect_token(&Token::RParen)?;
3683+
Some(columns)
3684+
} else {
3685+
None
3686+
};
3687+
Some(EngineSpec {
3688+
name: engine_name,
3689+
options: engine_options,
3690+
})
36763691
} else {
36773692
None
36783693
};

tests/sqlparser_clickhouse.rs

+3
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,9 @@ fn parse_create_table() {
344344
clickhouse().verified_stmt(
345345
r#"CREATE TABLE "x" ("a" Nullable(DateTime64(8))) ENGINE=MergeTree ORDER BY ("x") AS SELECT * FROM "t" WHERE true"#,
346346
);
347+
clickhouse().verified_stmt(
348+
r#"CREATE TABLE default.runs_buffer (`workspace` LowCardinality(String), `id` String, `assets` Array(String), `asset_types` Array(Int32), `target` Array(String), `target_type` Array(Int32), `extra_references` Array(String) DEFAULT [], `extra_reference_types` Array(Int32) DEFAULT [], `run_type` Int32, `run_status` Int32, `message` String, `created_at` DateTime64(8,'UTC'), `started_at` DateTime64(8,'UTC'), `finished_at` DateTime64(8,'UTC'), `meta` String, `exclude_status_update` Bool, `ingested_at` DateTime64(8,'UTC'), `parent_ids` Array(String), `skipped` Bool DEFAULT false) ENGINE=Buffer('default', 'runs', 4, 2, 5, 10000, 1000000, 2500000, 10000000)"#,
349+
);
347350
}
348351

349352
#[test]

tests/sqlparser_mysql.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ fn parse_create_table_engine_default_charset() {
443443
},],
444444
columns
445445
);
446-
assert_eq!(engine, Some("InnoDB".to_string()));
446+
assert_eq!(engine.unwrap().name, "InnoDB".to_string());
447447
assert_eq!(default_charset, Some("utf8mb3".to_string()));
448448
}
449449
_ => unreachable!(),

0 commit comments

Comments
 (0)