ClickHouse: support of create table query with primary key and parametrised table engine (#1289)

This commit is contained in:
Aleksei Piianin 2024-06-07 14:19:32 +02:00 committed by GitHub
parent 4b60866bc7
commit 3c33ac15bd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 168 additions and 25 deletions

View file

@ -211,12 +211,9 @@ fn parse_delimited_identifiers() {
#[test]
fn parse_create_table() {
clickhouse().verified_stmt(r#"CREATE TABLE "x" ("a" "int") ENGINE=MergeTree ORDER BY ("x")"#);
clickhouse().one_statement_parses_to(
r#"CREATE TABLE "x" ("a" "int") ENGINE=MergeTree ORDER BY "x""#,
r#"CREATE TABLE "x" ("a" "int") ENGINE=MergeTree ORDER BY ("x")"#,
);
clickhouse().verified_stmt(r#"CREATE TABLE "x" ("a" "int") ENGINE=MergeTree ORDER BY "x""#);
clickhouse().verified_stmt(
r#"CREATE TABLE "x" ("a" "int") ENGINE=MergeTree ORDER BY ("x") AS SELECT * FROM "t" WHERE true"#,
r#"CREATE TABLE "x" ("a" "int") ENGINE=MergeTree ORDER BY "x" AS SELECT * FROM "t" WHERE true"#,
);
}
@ -248,7 +245,7 @@ fn parse_clickhouse_data_types() {
.replace(" Float64", " FLOAT64");
match clickhouse_and_generic().one_statement_parses_to(sql, &canonical_sql) {
Statement::CreateTable { name, columns, .. } => {
Statement::CreateTable(CreateTable { name, columns, .. }) => {
assert_eq!(name, ObjectName(vec!["table".into()]));
assert_eq!(
columns,
@ -289,7 +286,7 @@ fn parse_create_table_with_nullable() {
let canonical_sql = sql.replace("String", "STRING");
match clickhouse_and_generic().one_statement_parses_to(sql, &canonical_sql) {
Statement::CreateTable { name, columns, .. } => {
Statement::CreateTable(CreateTable { name, columns, .. }) => {
assert_eq!(name, ObjectName(vec!["table".into()]));
assert_eq!(
columns,
@ -338,7 +335,7 @@ fn parse_create_table_with_nested_data_types() {
);
match clickhouse().one_statement_parses_to(sql, "") {
Statement::CreateTable { name, columns, .. } => {
Statement::CreateTable(CreateTable { name, columns, .. }) => {
assert_eq!(name, ObjectName(vec!["table".into()]));
assert_eq!(
columns,
@ -410,6 +407,88 @@ fn parse_create_table_with_nested_data_types() {
}
}
#[test]
fn parse_create_table_with_primary_key() {
match clickhouse_and_generic().verified_stmt(concat!(
r#"CREATE TABLE db.table (`i` INT, `k` INT)"#,
" ENGINE=SharedMergeTree('/clickhouse/tables/{uuid}/{shard}', '{replica}')",
" PRIMARY KEY tuple(i)",
" ORDER BY tuple(i)",
)) {
Statement::CreateTable(CreateTable {
name,
columns,
engine,
primary_key,
order_by,
..
}) => {
assert_eq!(name.to_string(), "db.table");
assert_eq!(
vec![
ColumnDef {
name: Ident::with_quote('`', "i"),
data_type: DataType::Int(None),
collation: None,
options: vec![],
},
ColumnDef {
name: Ident::with_quote('`', "k"),
data_type: DataType::Int(None),
collation: None,
options: vec![],
},
],
columns
);
assert_eq!(
engine,
Some(TableEngine {
name: "SharedMergeTree".to_string(),
parameters: Some(vec![
Ident::with_quote('\'', "/clickhouse/tables/{uuid}/{shard}"),
Ident::with_quote('\'', "{replica}"),
]),
})
);
fn assert_function(actual: &Function, name: &str, arg: &str) -> bool {
assert_eq!(actual.name, ObjectName(vec![Ident::new(name)]));
assert_eq!(
actual.args,
FunctionArguments::List(FunctionArgumentList {
args: vec![FunctionArg::Unnamed(FunctionArgExpr::Expr(Identifier(
Ident::new(arg)
)),)],
duplicate_treatment: None,
clauses: vec![],
})
);
true
}
match primary_key.unwrap().as_ref() {
Expr::Function(primary_key) => {
assert!(assert_function(primary_key, "tuple", "i"));
}
_ => panic!("unexpected primary key type"),
}
match order_by {
Some(OneOrManyWithParens::One(Expr::Function(order_by))) => {
assert!(assert_function(&order_by, "tuple", "i"));
}
_ => panic!("unexpected order by type"),
};
}
_ => unreachable!(),
}
clickhouse_and_generic()
.parse_sql_statements(concat!(
r#"CREATE TABLE db.table (`i` Int, `k` Int)"#,
" ORDER BY tuple(i), tuple(k)",
))
.expect_err("ORDER BY supports one expression with tuple");
}
#[test]
fn parse_create_view_with_fields_data_types() {
match clickhouse().verified_stmt(r#"CREATE VIEW v (i "int", f "String") AS SELECT * FROM t"#) {