mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-04 14:28:22 +00:00
Add all missing table options to be handled in any order (#1747)
Co-authored-by: Tomer Shani <tomer.shani@satoricyber.com>
This commit is contained in:
parent
a464f8e8d7
commit
728645fb31
17 changed files with 767 additions and 382 deletions
|
@ -484,7 +484,7 @@ fn parse_create_table_with_options() {
|
|||
columns,
|
||||
partition_by,
|
||||
cluster_by,
|
||||
options,
|
||||
table_options,
|
||||
..
|
||||
}) => {
|
||||
assert_eq!(
|
||||
|
@ -539,7 +539,7 @@ fn parse_create_table_with_options() {
|
|||
Ident::new("userid"),
|
||||
Ident::new("age"),
|
||||
])),
|
||||
Some(vec![
|
||||
CreateTableOptions::Options(vec![
|
||||
SqlOption::KeyValue {
|
||||
key: Ident::new("partition_expiration_days"),
|
||||
value: Expr::Value(
|
||||
|
@ -561,7 +561,7 @@ fn parse_create_table_with_options() {
|
|||
},
|
||||
])
|
||||
),
|
||||
(partition_by, cluster_by, options)
|
||||
(partition_by, cluster_by, table_options)
|
||||
)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
|
|
|
@ -219,10 +219,10 @@ fn parse_delimited_identifiers() {
|
|||
|
||||
#[test]
|
||||
fn parse_create_table() {
|
||||
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""#);
|
||||
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""#);
|
||||
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"#,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -589,7 +589,7 @@ fn parse_clickhouse_data_types() {
|
|||
|
||||
#[test]
|
||||
fn parse_create_table_with_nullable() {
|
||||
let sql = r#"CREATE TABLE table (k UInt8, `a` Nullable(String), `b` Nullable(DateTime64(9, 'UTC')), c Nullable(DateTime64(9)), d Date32 NULL) ENGINE=MergeTree ORDER BY (`k`)"#;
|
||||
let sql = r#"CREATE TABLE table (k UInt8, `a` Nullable(String), `b` Nullable(DateTime64(9, 'UTC')), c Nullable(DateTime64(9)), d Date32 NULL) ENGINE = MergeTree ORDER BY (`k`)"#;
|
||||
// ClickHouse has a case-sensitive definition of data type, but canonical representation is not
|
||||
let canonical_sql = sql.replace("String", "STRING");
|
||||
|
||||
|
@ -714,14 +714,14 @@ fn parse_create_table_with_nested_data_types() {
|
|||
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}')",
|
||||
" ENGINE = SharedMergeTree('/clickhouse/tables/{uuid}/{shard}', '{replica}')",
|
||||
" PRIMARY KEY tuple(i)",
|
||||
" ORDER BY tuple(i)",
|
||||
)) {
|
||||
Statement::CreateTable(CreateTable {
|
||||
name,
|
||||
columns,
|
||||
engine,
|
||||
table_options,
|
||||
primary_key,
|
||||
order_by,
|
||||
..
|
||||
|
@ -742,16 +742,23 @@ fn parse_create_table_with_primary_key() {
|
|||
],
|
||||
columns
|
||||
);
|
||||
assert_eq!(
|
||||
engine,
|
||||
Some(TableEngine {
|
||||
name: "SharedMergeTree".to_string(),
|
||||
parameters: Some(vec![
|
||||
|
||||
let plain_options = match table_options {
|
||||
CreateTableOptions::Plain(options) => options,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
assert!(plain_options.contains(&SqlOption::NamedParenthesizedList(
|
||||
NamedParenthesizedList {
|
||||
key: Ident::new("ENGINE"),
|
||||
name: Some(Ident::new("SharedMergeTree")),
|
||||
values: 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::from(vec![Ident::new(name)]));
|
||||
assert_eq!(
|
||||
|
@ -798,7 +805,7 @@ fn parse_create_table_with_variant_default_expressions() {
|
|||
" b DATETIME EPHEMERAL now(),",
|
||||
" c DATETIME EPHEMERAL,",
|
||||
" d STRING ALIAS toString(c)",
|
||||
") ENGINE=MergeTree"
|
||||
") ENGINE = MergeTree"
|
||||
);
|
||||
match clickhouse_and_generic().verified_stmt(sql) {
|
||||
Statement::CreateTable(CreateTable { columns, .. }) => {
|
||||
|
|
|
@ -3657,7 +3657,7 @@ fn parse_create_table() {
|
|||
name,
|
||||
columns,
|
||||
constraints,
|
||||
with_options,
|
||||
table_options,
|
||||
if_not_exists: false,
|
||||
external: false,
|
||||
file_format: None,
|
||||
|
@ -3795,7 +3795,7 @@ fn parse_create_table() {
|
|||
},
|
||||
]
|
||||
);
|
||||
assert_eq!(with_options, vec![]);
|
||||
assert_eq!(table_options, CreateTableOptions::None);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
@ -3840,7 +3840,7 @@ fn parse_create_table_with_constraint_characteristics() {
|
|||
name,
|
||||
columns,
|
||||
constraints,
|
||||
with_options,
|
||||
table_options,
|
||||
if_not_exists: false,
|
||||
external: false,
|
||||
file_format: None,
|
||||
|
@ -3934,7 +3934,7 @@ fn parse_create_table_with_constraint_characteristics() {
|
|||
},
|
||||
]
|
||||
);
|
||||
assert_eq!(with_options, vec![]);
|
||||
assert_eq!(table_options, CreateTableOptions::None);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
@ -4421,7 +4421,11 @@ fn parse_create_table_with_options() {
|
|||
|
||||
let sql = "CREATE TABLE t (c INT) WITH (foo = 'bar', a = 123)";
|
||||
match generic.verified_stmt(sql) {
|
||||
Statement::CreateTable(CreateTable { with_options, .. }) => {
|
||||
Statement::CreateTable(CreateTable { table_options, .. }) => {
|
||||
let with_options = match table_options {
|
||||
CreateTableOptions::With(options) => options,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
assert_eq!(
|
||||
vec![
|
||||
SqlOption::KeyValue {
|
||||
|
@ -4482,7 +4486,7 @@ fn parse_create_external_table() {
|
|||
name,
|
||||
columns,
|
||||
constraints,
|
||||
with_options,
|
||||
table_options,
|
||||
if_not_exists,
|
||||
external,
|
||||
file_format,
|
||||
|
@ -4525,7 +4529,7 @@ fn parse_create_external_table() {
|
|||
assert_eq!(FileFormat::TEXTFILE, file_format.unwrap());
|
||||
assert_eq!("/tmp/example.csv", location.unwrap());
|
||||
|
||||
assert_eq!(with_options, vec![]);
|
||||
assert_eq!(table_options, CreateTableOptions::None);
|
||||
assert!(!if_not_exists);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
|
@ -4550,7 +4554,7 @@ fn parse_create_or_replace_external_table() {
|
|||
name,
|
||||
columns,
|
||||
constraints,
|
||||
with_options,
|
||||
table_options,
|
||||
if_not_exists,
|
||||
external,
|
||||
file_format,
|
||||
|
@ -4579,7 +4583,7 @@ fn parse_create_or_replace_external_table() {
|
|||
assert_eq!(FileFormat::TEXTFILE, file_format.unwrap());
|
||||
assert_eq!("/tmp/example.csv", location.unwrap());
|
||||
|
||||
assert_eq!(with_options, vec![]);
|
||||
assert_eq!(table_options, CreateTableOptions::None);
|
||||
assert!(!if_not_exists);
|
||||
assert!(or_replace);
|
||||
}
|
||||
|
@ -11420,7 +11424,9 @@ fn test_parse_inline_comment() {
|
|||
// [Hive](https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL#LanguageManualDDL-CreateTable)
|
||||
match all_dialects_except(|d| d.is::<HiveDialect>()).verified_stmt(sql) {
|
||||
Statement::CreateTable(CreateTable {
|
||||
columns, comment, ..
|
||||
columns,
|
||||
table_options,
|
||||
..
|
||||
}) => {
|
||||
assert_eq!(
|
||||
columns,
|
||||
|
@ -11434,8 +11440,10 @@ fn test_parse_inline_comment() {
|
|||
}]
|
||||
);
|
||||
assert_eq!(
|
||||
comment.unwrap(),
|
||||
CommentDef::WithEq("comment with equal".to_string())
|
||||
table_options,
|
||||
CreateTableOptions::Plain(vec![SqlOption::Comment(CommentDef::WithEq(
|
||||
"comment with equal".to_string()
|
||||
))])
|
||||
);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
|
@ -12460,21 +12468,6 @@ fn parse_select_wildcard_with_except() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_auto_increment_too_large() {
|
||||
let dialect = GenericDialect {};
|
||||
let u64_max = u64::MAX;
|
||||
let sql =
|
||||
format!("CREATE TABLE foo (bar INT NOT NULL AUTO_INCREMENT) AUTO_INCREMENT=1{u64_max}");
|
||||
|
||||
let res = Parser::new(&dialect)
|
||||
.try_with_sql(&sql)
|
||||
.expect("tokenize to work")
|
||||
.parse_statements();
|
||||
|
||||
assert!(res.is_err(), "{res:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_group_by_nothing() {
|
||||
let Select { group_by, .. } = all_dialects_where(|d| d.supports_group_by_expr())
|
||||
|
|
|
@ -735,19 +735,13 @@ fn test_duckdb_union_datatype() {
|
|||
storage: Default::default(),
|
||||
location: Default::default()
|
||||
}),
|
||||
table_properties: Default::default(),
|
||||
with_options: Default::default(),
|
||||
file_format: Default::default(),
|
||||
location: Default::default(),
|
||||
query: Default::default(),
|
||||
without_rowid: Default::default(),
|
||||
like: Default::default(),
|
||||
clone: Default::default(),
|
||||
engine: Default::default(),
|
||||
comment: Default::default(),
|
||||
auto_increment_offset: Default::default(),
|
||||
default_charset: Default::default(),
|
||||
collation: Default::default(),
|
||||
on_commit: Default::default(),
|
||||
on_cluster: Default::default(),
|
||||
primary_key: Default::default(),
|
||||
|
@ -755,7 +749,6 @@ fn test_duckdb_union_datatype() {
|
|||
partition_by: Default::default(),
|
||||
cluster_by: Default::default(),
|
||||
clustered_by: Default::default(),
|
||||
options: Default::default(),
|
||||
inherits: Default::default(),
|
||||
strict: Default::default(),
|
||||
copy_grants: Default::default(),
|
||||
|
@ -772,6 +765,7 @@ fn test_duckdb_union_datatype() {
|
|||
catalog: Default::default(),
|
||||
catalog_sync: Default::default(),
|
||||
storage_serialization_policy: Default::default(),
|
||||
table_options: CreateTableOptions::None
|
||||
}),
|
||||
stmt
|
||||
);
|
||||
|
|
|
@ -133,9 +133,7 @@ fn create_table_with_comment() {
|
|||
Statement::CreateTable(CreateTable { comment, .. }) => {
|
||||
assert_eq!(
|
||||
comment,
|
||||
Some(CommentDef::AfterColumnDefsWithoutEq(
|
||||
"table comment".to_string()
|
||||
))
|
||||
Some(CommentDef::WithoutEq("table comment".to_string()))
|
||||
)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
|
|
|
@ -1725,7 +1725,6 @@ fn parse_create_table_with_valid_options() {
|
|||
span: Span::empty(),
|
||||
},
|
||||
data_type: Int(None,),
|
||||
|
||||
options: vec![],
|
||||
},
|
||||
ColumnDef {
|
||||
|
@ -1735,7 +1734,6 @@ fn parse_create_table_with_valid_options() {
|
|||
span: Span::empty(),
|
||||
},
|
||||
data_type: Int(None,),
|
||||
|
||||
options: vec![],
|
||||
},
|
||||
],
|
||||
|
@ -1747,19 +1745,13 @@ fn parse_create_table_with_valid_options() {
|
|||
storage: None,
|
||||
location: None,
|
||||
},),
|
||||
table_properties: vec![],
|
||||
with_options,
|
||||
file_format: None,
|
||||
location: None,
|
||||
query: None,
|
||||
without_rowid: false,
|
||||
like: None,
|
||||
clone: None,
|
||||
engine: None,
|
||||
comment: None,
|
||||
auto_increment_offset: None,
|
||||
default_charset: None,
|
||||
collation: None,
|
||||
on_commit: None,
|
||||
on_cluster: None,
|
||||
primary_key: None,
|
||||
|
@ -1767,7 +1759,6 @@ fn parse_create_table_with_valid_options() {
|
|||
partition_by: None,
|
||||
cluster_by: None,
|
||||
clustered_by: None,
|
||||
options: None,
|
||||
inherits: None,
|
||||
strict: false,
|
||||
iceberg: false,
|
||||
|
@ -1785,6 +1776,7 @@ fn parse_create_table_with_valid_options() {
|
|||
catalog: None,
|
||||
catalog_sync: None,
|
||||
storage_serialization_policy: None,
|
||||
table_options: CreateTableOptions::With(with_options)
|
||||
})
|
||||
);
|
||||
}
|
||||
|
@ -1918,19 +1910,13 @@ fn parse_create_table_with_identity_column() {
|
|||
storage: None,
|
||||
location: None,
|
||||
},),
|
||||
table_properties: vec![],
|
||||
with_options: vec![],
|
||||
file_format: None,
|
||||
location: None,
|
||||
query: None,
|
||||
without_rowid: false,
|
||||
like: None,
|
||||
clone: None,
|
||||
engine: None,
|
||||
comment: None,
|
||||
auto_increment_offset: None,
|
||||
default_charset: None,
|
||||
collation: None,
|
||||
on_commit: None,
|
||||
on_cluster: None,
|
||||
primary_key: None,
|
||||
|
@ -1938,7 +1924,6 @@ fn parse_create_table_with_identity_column() {
|
|||
partition_by: None,
|
||||
cluster_by: None,
|
||||
clustered_by: None,
|
||||
options: None,
|
||||
inherits: None,
|
||||
strict: false,
|
||||
copy_grants: false,
|
||||
|
@ -1955,6 +1940,7 @@ fn parse_create_table_with_identity_column() {
|
|||
catalog: None,
|
||||
catalog_sync: None,
|
||||
storage_serialization_policy: None,
|
||||
table_options: CreateTableOptions::None
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -848,9 +848,23 @@ fn parse_create_table_comment() {
|
|||
|
||||
for sql in [without_equal, with_equal] {
|
||||
match mysql().verified_stmt(sql) {
|
||||
Statement::CreateTable(CreateTable { name, comment, .. }) => {
|
||||
Statement::CreateTable(CreateTable {
|
||||
name,
|
||||
table_options,
|
||||
..
|
||||
}) => {
|
||||
assert_eq!(name.to_string(), "foo");
|
||||
assert_eq!(comment.expect("Should exist").to_string(), "baz");
|
||||
|
||||
let plain_options = match table_options {
|
||||
CreateTableOptions::Plain(options) => options,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let comment = match plain_options.first().unwrap() {
|
||||
SqlOption::Comment(CommentDef::WithEq(c))
|
||||
| SqlOption::Comment(CommentDef::WithoutEq(c)) => c,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
assert_eq!(comment, "baz");
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
@ -859,29 +873,226 @@ fn parse_create_table_comment() {
|
|||
|
||||
#[test]
|
||||
fn parse_create_table_auto_increment_offset() {
|
||||
let canonical =
|
||||
"CREATE TABLE foo (bar INT NOT NULL AUTO_INCREMENT) ENGINE=InnoDB AUTO_INCREMENT 123";
|
||||
let with_equal =
|
||||
"CREATE TABLE foo (bar INT NOT NULL AUTO_INCREMENT) ENGINE=InnoDB AUTO_INCREMENT=123";
|
||||
let sql =
|
||||
"CREATE TABLE foo (bar INT NOT NULL AUTO_INCREMENT) ENGINE = InnoDB AUTO_INCREMENT = 123";
|
||||
|
||||
for sql in [canonical, with_equal] {
|
||||
match mysql().one_statement_parses_to(sql, canonical) {
|
||||
match mysql().verified_stmt(sql) {
|
||||
Statement::CreateTable(CreateTable {
|
||||
name,
|
||||
table_options,
|
||||
..
|
||||
}) => {
|
||||
assert_eq!(name.to_string(), "foo");
|
||||
|
||||
let plain_options = match table_options {
|
||||
CreateTableOptions::Plain(options) => options,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
assert!(plain_options.contains(&SqlOption::KeyValue {
|
||||
key: Ident::new("AUTO_INCREMENT"),
|
||||
value: Expr::Value(test_utils::number("123").with_empty_span())
|
||||
}));
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_create_table_multiple_options_order_independent() {
|
||||
let sql1 = "CREATE TABLE mytable (id INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=8 COMMENT='abc'";
|
||||
let sql2 = "CREATE TABLE mytable (id INT) KEY_BLOCK_SIZE=8 COMMENT='abc' ENGINE=InnoDB ROW_FORMAT=DYNAMIC";
|
||||
let sql3 = "CREATE TABLE mytable (id INT) ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=8 COMMENT='abc' ENGINE=InnoDB";
|
||||
|
||||
for sql in [sql1, sql2, sql3] {
|
||||
match mysql().parse_sql_statements(sql).unwrap().pop().unwrap() {
|
||||
Statement::CreateTable(CreateTable {
|
||||
name,
|
||||
auto_increment_offset,
|
||||
table_options,
|
||||
..
|
||||
}) => {
|
||||
assert_eq!(name.to_string(), "foo");
|
||||
assert_eq!(
|
||||
auto_increment_offset.expect("Should exist").to_string(),
|
||||
"123"
|
||||
);
|
||||
assert_eq!(name.to_string(), "mytable");
|
||||
|
||||
let plain_options = match table_options {
|
||||
CreateTableOptions::Plain(options) => options,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
assert!(plain_options.contains(&SqlOption::NamedParenthesizedList(
|
||||
NamedParenthesizedList {
|
||||
key: Ident::new("ENGINE"),
|
||||
name: Some(Ident::new("InnoDB")),
|
||||
values: vec![]
|
||||
}
|
||||
)));
|
||||
|
||||
assert!(plain_options.contains(&SqlOption::KeyValue {
|
||||
key: Ident::new("KEY_BLOCK_SIZE"),
|
||||
value: Expr::Value(test_utils::number("8").with_empty_span())
|
||||
}));
|
||||
|
||||
assert!(plain_options
|
||||
.contains(&SqlOption::Comment(CommentDef::WithEq("abc".to_owned()))));
|
||||
|
||||
assert!(plain_options.contains(&SqlOption::KeyValue {
|
||||
key: Ident::new("ROW_FORMAT"),
|
||||
value: Expr::Identifier(Ident::new("DYNAMIC".to_owned()))
|
||||
}));
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_create_table_with_all_table_options() {
|
||||
let sql =
|
||||
"CREATE TABLE foo (bar INT NOT NULL AUTO_INCREMENT) ENGINE = InnoDB AUTO_INCREMENT = 123 DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci INSERT_METHOD = FIRST KEY_BLOCK_SIZE = 8 ROW_FORMAT = DYNAMIC DATA DIRECTORY = '/var/lib/mysql/data' INDEX DIRECTORY = '/var/lib/mysql/index' PACK_KEYS = 1 STATS_AUTO_RECALC = 1 STATS_PERSISTENT = 0 STATS_SAMPLE_PAGES = 128 DELAY_KEY_WRITE = 1 COMPRESSION = 'ZLIB' ENCRYPTION = 'Y' MAX_ROWS = 10000 MIN_ROWS = 10 AUTOEXTEND_SIZE = 64 AVG_ROW_LENGTH = 128 CHECKSUM = 1 CONNECTION = 'mysql://localhost' ENGINE_ATTRIBUTE = 'primary' PASSWORD = 'secure_password' SECONDARY_ENGINE_ATTRIBUTE = 'secondary_attr' START TRANSACTION TABLESPACE my_tablespace STORAGE DISK UNION = (table1, table2, table3)";
|
||||
|
||||
match mysql().verified_stmt(sql) {
|
||||
Statement::CreateTable(CreateTable {
|
||||
name,
|
||||
table_options,
|
||||
..
|
||||
}) => {
|
||||
assert_eq!(name, vec![Ident::new("foo".to_owned())].into());
|
||||
|
||||
let plain_options = match table_options {
|
||||
CreateTableOptions::Plain(options) => options,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
assert!(plain_options.contains(&SqlOption::NamedParenthesizedList(
|
||||
NamedParenthesizedList {
|
||||
key: Ident::new("ENGINE"),
|
||||
name: Some(Ident::new("InnoDB")),
|
||||
values: vec![]
|
||||
}
|
||||
)));
|
||||
|
||||
assert!(plain_options.contains(&SqlOption::KeyValue {
|
||||
key: Ident::new("COLLATE"),
|
||||
value: Expr::Identifier(Ident::new("utf8mb4_0900_ai_ci".to_owned()))
|
||||
}));
|
||||
assert!(plain_options.contains(&SqlOption::KeyValue {
|
||||
key: Ident::new("DEFAULT CHARSET"),
|
||||
value: Expr::Identifier(Ident::new("utf8mb4".to_owned()))
|
||||
}));
|
||||
assert!(plain_options.contains(&SqlOption::KeyValue {
|
||||
key: Ident::new("AUTO_INCREMENT"),
|
||||
value: Expr::value(test_utils::number("123"))
|
||||
}));
|
||||
assert!(plain_options.contains(&SqlOption::KeyValue {
|
||||
key: Ident::new("KEY_BLOCK_SIZE"),
|
||||
value: Expr::value(test_utils::number("8"))
|
||||
}));
|
||||
assert!(plain_options.contains(&SqlOption::KeyValue {
|
||||
key: Ident::new("ROW_FORMAT"),
|
||||
value: Expr::Identifier(Ident::new("DYNAMIC".to_owned()))
|
||||
}));
|
||||
assert!(plain_options.contains(&SqlOption::KeyValue {
|
||||
key: Ident::new("PACK_KEYS"),
|
||||
value: Expr::value(test_utils::number("1"))
|
||||
}));
|
||||
assert!(plain_options.contains(&SqlOption::KeyValue {
|
||||
key: Ident::new("STATS_AUTO_RECALC"),
|
||||
value: Expr::value(test_utils::number("1"))
|
||||
}));
|
||||
assert!(plain_options.contains(&SqlOption::KeyValue {
|
||||
key: Ident::new("STATS_PERSISTENT"),
|
||||
value: Expr::value(test_utils::number("0"))
|
||||
}));
|
||||
assert!(plain_options.contains(&SqlOption::KeyValue {
|
||||
key: Ident::new("STATS_SAMPLE_PAGES"),
|
||||
value: Expr::value(test_utils::number("128"))
|
||||
}));
|
||||
assert!(plain_options.contains(&SqlOption::KeyValue {
|
||||
key: Ident::new("STATS_SAMPLE_PAGES"),
|
||||
value: Expr::value(test_utils::number("128"))
|
||||
}));
|
||||
assert!(plain_options.contains(&SqlOption::KeyValue {
|
||||
key: Ident::new("INSERT_METHOD"),
|
||||
value: Expr::Identifier(Ident::new("FIRST".to_owned()))
|
||||
}));
|
||||
assert!(plain_options.contains(&SqlOption::KeyValue {
|
||||
key: Ident::new("COMPRESSION"),
|
||||
value: Expr::value(Value::SingleQuotedString("ZLIB".to_owned()))
|
||||
}));
|
||||
assert!(plain_options.contains(&SqlOption::KeyValue {
|
||||
key: Ident::new("ENCRYPTION"),
|
||||
value: Expr::value(Value::SingleQuotedString("Y".to_owned()))
|
||||
}));
|
||||
assert!(plain_options.contains(&SqlOption::KeyValue {
|
||||
key: Ident::new("MAX_ROWS"),
|
||||
value: Expr::value(test_utils::number("10000"))
|
||||
}));
|
||||
assert!(plain_options.contains(&SqlOption::KeyValue {
|
||||
key: Ident::new("MIN_ROWS"),
|
||||
value: Expr::value(test_utils::number("10"))
|
||||
}));
|
||||
assert!(plain_options.contains(&SqlOption::KeyValue {
|
||||
key: Ident::new("AUTOEXTEND_SIZE"),
|
||||
value: Expr::value(test_utils::number("64"))
|
||||
}));
|
||||
assert!(plain_options.contains(&SqlOption::KeyValue {
|
||||
key: Ident::new("AVG_ROW_LENGTH"),
|
||||
value: Expr::value(test_utils::number("128"))
|
||||
}));
|
||||
assert!(plain_options.contains(&SqlOption::KeyValue {
|
||||
key: Ident::new("CHECKSUM"),
|
||||
value: Expr::value(test_utils::number("1"))
|
||||
}));
|
||||
assert!(plain_options.contains(&SqlOption::KeyValue {
|
||||
key: Ident::new("CONNECTION"),
|
||||
value: Expr::value(Value::SingleQuotedString("mysql://localhost".to_owned()))
|
||||
}));
|
||||
assert!(plain_options.contains(&SqlOption::KeyValue {
|
||||
key: Ident::new("ENGINE_ATTRIBUTE"),
|
||||
value: Expr::value(Value::SingleQuotedString("primary".to_owned()))
|
||||
}));
|
||||
assert!(plain_options.contains(&SqlOption::KeyValue {
|
||||
key: Ident::new("PASSWORD"),
|
||||
value: Expr::value(Value::SingleQuotedString("secure_password".to_owned()))
|
||||
}));
|
||||
assert!(plain_options.contains(&SqlOption::KeyValue {
|
||||
key: Ident::new("SECONDARY_ENGINE_ATTRIBUTE"),
|
||||
value: Expr::value(Value::SingleQuotedString("secondary_attr".to_owned()))
|
||||
}));
|
||||
assert!(plain_options.contains(&SqlOption::Ident(Ident::new(
|
||||
"START TRANSACTION".to_owned()
|
||||
))));
|
||||
assert!(
|
||||
plain_options.contains(&SqlOption::TableSpace(TablespaceOption {
|
||||
name: "my_tablespace".to_string(),
|
||||
storage: Some(StorageType::Disk),
|
||||
}))
|
||||
);
|
||||
|
||||
assert!(plain_options.contains(&SqlOption::NamedParenthesizedList(
|
||||
NamedParenthesizedList {
|
||||
key: Ident::new("UNION"),
|
||||
name: None,
|
||||
values: vec![
|
||||
Ident::new("table1".to_string()),
|
||||
Ident::new("table2".to_string()),
|
||||
Ident::new("table3".to_string())
|
||||
]
|
||||
}
|
||||
)));
|
||||
|
||||
assert!(plain_options.contains(&SqlOption::KeyValue {
|
||||
key: Ident::new("DATA DIRECTORY"),
|
||||
value: Expr::value(Value::SingleQuotedString("/var/lib/mysql/data".to_owned()))
|
||||
}));
|
||||
assert!(plain_options.contains(&SqlOption::KeyValue {
|
||||
key: Ident::new("INDEX DIRECTORY"),
|
||||
value: Expr::value(Value::SingleQuotedString("/var/lib/mysql/index".to_owned()))
|
||||
}));
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_create_table_set_enum() {
|
||||
let sql = "CREATE TABLE foo (bar SET('a', 'b'), baz ENUM('a', 'b'))";
|
||||
|
@ -916,13 +1127,12 @@ fn parse_create_table_set_enum() {
|
|||
|
||||
#[test]
|
||||
fn parse_create_table_engine_default_charset() {
|
||||
let sql = "CREATE TABLE foo (id INT(11)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3";
|
||||
let sql = "CREATE TABLE foo (id INT(11)) ENGINE = InnoDB DEFAULT CHARSET = utf8mb3";
|
||||
match mysql().verified_stmt(sql) {
|
||||
Statement::CreateTable(CreateTable {
|
||||
name,
|
||||
columns,
|
||||
engine,
|
||||
default_charset,
|
||||
table_options,
|
||||
..
|
||||
}) => {
|
||||
assert_eq!(name.to_string(), "foo");
|
||||
|
@ -934,14 +1144,24 @@ fn parse_create_table_engine_default_charset() {
|
|||
},],
|
||||
columns
|
||||
);
|
||||
assert_eq!(
|
||||
engine,
|
||||
Some(TableEngine {
|
||||
name: "InnoDB".to_string(),
|
||||
parameters: None
|
||||
})
|
||||
);
|
||||
assert_eq!(default_charset, Some("utf8mb3".to_string()));
|
||||
|
||||
let plain_options = match table_options {
|
||||
CreateTableOptions::Plain(options) => options,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
assert!(plain_options.contains(&SqlOption::KeyValue {
|
||||
key: Ident::new("DEFAULT CHARSET"),
|
||||
value: Expr::Identifier(Ident::new("utf8mb3".to_owned()))
|
||||
}));
|
||||
|
||||
assert!(plain_options.contains(&SqlOption::NamedParenthesizedList(
|
||||
NamedParenthesizedList {
|
||||
key: Ident::new("ENGINE"),
|
||||
name: Some(Ident::new("InnoDB")),
|
||||
values: vec![]
|
||||
}
|
||||
)));
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
@ -949,12 +1169,12 @@ fn parse_create_table_engine_default_charset() {
|
|||
|
||||
#[test]
|
||||
fn parse_create_table_collate() {
|
||||
let sql = "CREATE TABLE foo (id INT(11)) COLLATE=utf8mb4_0900_ai_ci";
|
||||
let sql = "CREATE TABLE foo (id INT(11)) COLLATE = utf8mb4_0900_ai_ci";
|
||||
match mysql().verified_stmt(sql) {
|
||||
Statement::CreateTable(CreateTable {
|
||||
name,
|
||||
columns,
|
||||
collation,
|
||||
table_options,
|
||||
..
|
||||
}) => {
|
||||
assert_eq!(name.to_string(), "foo");
|
||||
|
@ -966,7 +1186,16 @@ fn parse_create_table_collate() {
|
|||
},],
|
||||
columns
|
||||
);
|
||||
assert_eq!(collation, Some("utf8mb4_0900_ai_ci".to_string()));
|
||||
|
||||
let plain_options = match table_options {
|
||||
CreateTableOptions::Plain(options) => options,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
assert!(plain_options.contains(&SqlOption::KeyValue {
|
||||
key: Ident::new("COLLATE"),
|
||||
value: Expr::Identifier(Ident::new("utf8mb4_0900_ai_ci".to_owned()))
|
||||
}));
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
@ -974,16 +1203,26 @@ fn parse_create_table_collate() {
|
|||
|
||||
#[test]
|
||||
fn parse_create_table_both_options_and_as_query() {
|
||||
let sql = "CREATE TABLE foo (id INT(11)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb4_0900_ai_ci AS SELECT 1";
|
||||
let sql = "CREATE TABLE foo (id INT(11)) ENGINE = InnoDB DEFAULT CHARSET = utf8mb3 COLLATE = utf8mb4_0900_ai_ci AS SELECT 1";
|
||||
match mysql_and_generic().verified_stmt(sql) {
|
||||
Statement::CreateTable(CreateTable {
|
||||
name,
|
||||
collation,
|
||||
query,
|
||||
table_options,
|
||||
..
|
||||
}) => {
|
||||
assert_eq!(name.to_string(), "foo");
|
||||
assert_eq!(collation, Some("utf8mb4_0900_ai_ci".to_string()));
|
||||
|
||||
let plain_options = match table_options {
|
||||
CreateTableOptions::Plain(options) => options,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
assert!(plain_options.contains(&SqlOption::KeyValue {
|
||||
key: Ident::new("COLLATE"),
|
||||
value: Expr::Identifier(Ident::new("utf8mb4_0900_ai_ci".to_owned()))
|
||||
}));
|
||||
|
||||
assert_eq!(
|
||||
query.unwrap().body.as_select().unwrap().projection,
|
||||
vec![SelectItem::UnnamedExpr(Expr::Value(
|
||||
|
@ -994,7 +1233,8 @@ fn parse_create_table_both_options_and_as_query() {
|
|||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
let sql = r"CREATE TABLE foo (id INT(11)) ENGINE=InnoDB AS SELECT 1 DEFAULT CHARSET=utf8mb3";
|
||||
let sql =
|
||||
r"CREATE TABLE foo (id INT(11)) ENGINE = InnoDB AS SELECT 1 DEFAULT CHARSET = utf8mb3";
|
||||
assert!(matches!(
|
||||
mysql_and_generic().parse_sql_statements(sql),
|
||||
Err(ParserError::ParserError(_))
|
||||
|
|
|
@ -348,7 +348,7 @@ fn parse_create_table_with_defaults() {
|
|||
name,
|
||||
columns,
|
||||
constraints,
|
||||
with_options,
|
||||
table_options,
|
||||
if_not_exists: false,
|
||||
external: false,
|
||||
file_format: None,
|
||||
|
@ -485,6 +485,11 @@ fn parse_create_table_with_defaults() {
|
|||
]
|
||||
);
|
||||
assert!(constraints.is_empty());
|
||||
|
||||
let with_options = match table_options {
|
||||
CreateTableOptions::With(options) => options,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
assert_eq!(
|
||||
with_options,
|
||||
vec![
|
||||
|
@ -4668,7 +4673,6 @@ fn parse_create_table_with_alias() {
|
|||
name,
|
||||
columns,
|
||||
constraints,
|
||||
with_options: _with_options,
|
||||
if_not_exists: false,
|
||||
external: false,
|
||||
file_format: None,
|
||||
|
@ -5078,7 +5082,11 @@ fn parse_at_time_zone() {
|
|||
fn parse_create_table_with_options() {
|
||||
let sql = "CREATE TABLE t (c INT) WITH (foo = 'bar', a = 123)";
|
||||
match pg().verified_stmt(sql) {
|
||||
Statement::CreateTable(CreateTable { with_options, .. }) => {
|
||||
Statement::CreateTable(CreateTable { table_options, .. }) => {
|
||||
let with_options = match table_options {
|
||||
CreateTableOptions::With(options) => options,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
assert_eq!(
|
||||
vec![
|
||||
SqlOption::KeyValue {
|
||||
|
@ -5506,19 +5514,13 @@ fn parse_trigger_related_functions() {
|
|||
storage: None,
|
||||
location: None
|
||||
}),
|
||||
table_properties: vec![],
|
||||
with_options: vec![],
|
||||
file_format: None,
|
||||
location: None,
|
||||
query: None,
|
||||
without_rowid: false,
|
||||
like: None,
|
||||
clone: None,
|
||||
engine: None,
|
||||
comment: None,
|
||||
auto_increment_offset: None,
|
||||
default_charset: None,
|
||||
collation: None,
|
||||
on_commit: None,
|
||||
on_cluster: None,
|
||||
primary_key: None,
|
||||
|
@ -5526,7 +5528,6 @@ fn parse_trigger_related_functions() {
|
|||
partition_by: None,
|
||||
cluster_by: None,
|
||||
clustered_by: None,
|
||||
options: None,
|
||||
inherits: None,
|
||||
strict: false,
|
||||
copy_grants: false,
|
||||
|
@ -5543,6 +5544,7 @@ fn parse_trigger_related_functions() {
|
|||
catalog: None,
|
||||
catalog_sync: None,
|
||||
storage_serialization_policy: None,
|
||||
table_options: CreateTableOptions::None
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -470,9 +470,22 @@ fn test_snowflake_create_table_cluster_by() {
|
|||
#[test]
|
||||
fn test_snowflake_create_table_comment() {
|
||||
match snowflake().verified_stmt("CREATE TABLE my_table (a INT) COMMENT = 'some comment'") {
|
||||
Statement::CreateTable(CreateTable { name, comment, .. }) => {
|
||||
Statement::CreateTable(CreateTable {
|
||||
name,
|
||||
table_options,
|
||||
..
|
||||
}) => {
|
||||
assert_eq!("my_table", name.to_string());
|
||||
assert_eq!("some comment", comment.unwrap().to_string());
|
||||
let plain_options = match table_options {
|
||||
CreateTableOptions::Plain(options) => options,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let comment = match plain_options.first().unwrap() {
|
||||
SqlOption::Comment(CommentDef::WithEq(c))
|
||||
| SqlOption::Comment(CommentDef::WithoutEq(c)) => c,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
assert_eq!("some comment", comment);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue