Skip to content

Commit 58b7719

Browse files
Add TABLESPACE coverage for MySQL and PostgreSQL
1 parent 665ba46 commit 58b7719

File tree

2 files changed

+232
-1
lines changed

2 files changed

+232
-1
lines changed

tests/sqlparser_mysql.rs

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4773,3 +4773,107 @@ fn parse_create_database_with_charset_option_ordering() {
47734773
"CREATE DATABASE mydb DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_unicode_ci",
47744774
);
47754775
}
4776+
4777+
#[test]
4778+
fn parse_mysql_create_tablespace() {
4779+
let sql =
4780+
"CREATE TABLESPACE ts ADD DATAFILE 'ts.ibd' FILE_BLOCK_SIZE = 4096 ENCRYPTION = 'Y' ENGINE = InnoDB ENGINE_ATTRIBUTE = 'ndb_general'";
4781+
let stmt = mysql_and_generic().verified_stmt(sql);
4782+
4783+
let Statement::CreateTablespace(CreateTablespace { name, definition }) = stmt else {
4784+
panic!("Expected CREATE TABLESPACE");
4785+
};
4786+
assert_eq!(name.value, "ts");
4787+
4788+
let CreateTablespaceDefinition::MySql { undo, options } = definition else {
4789+
panic!("Expected MySQL CREATE TABLESPACE definition");
4790+
};
4791+
assert!(!undo);
4792+
assert_eq!(
4793+
options[0],
4794+
MySqlCreateTablespaceOption::AddDatafile("ts.ibd".to_string())
4795+
);
4796+
assert_eq!(options[1].to_string(), "FILE_BLOCK_SIZE = 4096");
4797+
assert_eq!(options[2].to_string(), "ENCRYPTION = 'Y'");
4798+
assert_eq!(options[3].to_string(), "ENGINE = InnoDB");
4799+
assert_eq!(options[4].to_string(), "ENGINE_ATTRIBUTE = 'ndb_general'");
4800+
}
4801+
4802+
#[test]
4803+
fn parse_mysql_create_tablespace_without_add_datafile() {
4804+
mysql_and_generic().one_statement_parses_to(
4805+
"CREATE TABLESPACE ts ENGINE InnoDB",
4806+
"CREATE TABLESPACE ts ENGINE = InnoDB",
4807+
);
4808+
}
4809+
4810+
#[test]
4811+
fn parse_mysql_create_undo_tablespace() {
4812+
mysql_and_generic().one_statement_parses_to(
4813+
"CREATE UNDO TABLESPACE undo_ts ADD DATAFILE 'undo_001.ibu' ENGINE InnoDB",
4814+
"CREATE UNDO TABLESPACE undo_ts ADD DATAFILE 'undo_001.ibu' ENGINE = InnoDB",
4815+
);
4816+
}
4817+
4818+
#[test]
4819+
fn parse_mysql_alter_tablespace() {
4820+
let stmt = mysql_and_generic().verified_stmt(
4821+
"ALTER TABLESPACE ts ADD DATAFILE 'ts2.ibd' INITIAL_SIZE = 16 AUTOEXTEND_SIZE = 32 WAIT ENGINE = InnoDB ENGINE_ATTRIBUTE = 'ndb_general'",
4822+
);
4823+
let Statement::AlterTablespace(AlterTablespace {
4824+
name,
4825+
operation: AlterTablespaceOperation::MySql { undo, options },
4826+
}) = stmt
4827+
else {
4828+
panic!("Expected MySQL ALTER TABLESPACE ADD DATAFILE");
4829+
};
4830+
4831+
assert_eq!(name.value, "ts");
4832+
assert!(!undo);
4833+
assert_eq!(
4834+
options
4835+
.iter()
4836+
.map(ToString::to_string)
4837+
.collect::<Vec<String>>(),
4838+
vec![
4839+
"ADD DATAFILE 'ts2.ibd'",
4840+
"INITIAL_SIZE = 16",
4841+
"AUTOEXTEND_SIZE = 32",
4842+
"WAIT",
4843+
"ENGINE = InnoDB",
4844+
"ENGINE_ATTRIBUTE = 'ndb_general'",
4845+
]
4846+
);
4847+
4848+
mysql_and_generic().one_statement_parses_to(
4849+
"ALTER UNDO TABLESPACE undo_ts SET ACTIVE",
4850+
"ALTER UNDO TABLESPACE undo_ts SET ACTIVE",
4851+
);
4852+
}
4853+
4854+
#[test]
4855+
fn parse_mysql_drop_tablespace() {
4856+
let stmt = mysql_and_generic().one_statement_parses_to(
4857+
"DROP UNDO TABLESPACE undo_ts ENGINE InnoDB",
4858+
"DROP UNDO TABLESPACE undo_ts ENGINE = InnoDB",
4859+
);
4860+
let Statement::DropTablespace(DropTablespace {
4861+
if_exists,
4862+
undo,
4863+
name,
4864+
engine,
4865+
}) = stmt
4866+
else {
4867+
panic!("Expected DROP TABLESPACE");
4868+
};
4869+
4870+
assert!(!if_exists);
4871+
assert!(undo);
4872+
assert_eq!(name.value, "undo_ts");
4873+
assert_eq!(engine.as_ref().map(|i| i.value.as_str()), Some("InnoDB"));
4874+
4875+
mysql_and_generic().one_statement_parses_to(
4876+
"DROP TABLESPACE ts ENGINE InnoDB",
4877+
"DROP TABLESPACE ts ENGINE = InnoDB",
4878+
);
4879+
}

tests/sqlparser_postgres.rs

Lines changed: 128 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ mod test_utils;
2424

2525
use helpers::attached_token::AttachedToken;
2626
use sqlparser::ast::*;
27-
use sqlparser::dialect::{GenericDialect, PostgreSqlDialect};
27+
use sqlparser::dialect::{GenericDialect, MySqlDialect, PostgreSqlDialect};
2828
use sqlparser::parser::ParserError;
2929
use sqlparser::tokenizer::Span;
3030
use test_utils::*;
@@ -8602,3 +8602,130 @@ fn parse_pg_analyze() {
86028602
_ => panic!("Expected Analyze, got: {stmt:?}"),
86038603
}
86048604
}
8605+
8606+
#[test]
8607+
fn parse_tablespace_and_reindex_regression_cases() {
8608+
for sql in [
8609+
"CREATE TABLESPACE regress_tblspace LOCATION 'relative'",
8610+
"CREATE TABLESPACE regress_tblspace LOCATION ''",
8611+
"CREATE TABLESPACE regress_tblspacewith LOCATION '' WITH (some_nonexistent_parameter = true)",
8612+
"CREATE TABLESPACE regress_tblspacewith LOCATION '' WITH (random_page_cost = 3.0)",
8613+
"DROP TABLESPACE regress_tblspacewith",
8614+
"ALTER TABLESPACE regress_tblspace SET (random_page_cost = 1.0, seq_page_cost = 1.1)",
8615+
"ALTER TABLESPACE regress_tblspace SET (some_nonexistent_parameter = true)",
8616+
"ALTER TABLESPACE regress_tblspace RESET (random_page_cost = 2.0)",
8617+
"ALTER TABLESPACE regress_tblspace RESET (random_page_cost, effective_io_concurrency)",
8618+
"REINDEX (TABLESPACE regress_tblspace) TABLE pg_am",
8619+
"REINDEX (TABLESPACE regress_tblspace) TABLE CONCURRENTLY pg_am",
8620+
"REINDEX (TABLESPACE regress_tblspace) TABLE pg_authid",
8621+
"REINDEX (TABLESPACE regress_tblspace) TABLE CONCURRENTLY pg_authid",
8622+
"REINDEX (TABLESPACE regress_tblspace) INDEX pg_toast.pg_toast_1262_index",
8623+
"REINDEX (TABLESPACE regress_tblspace) INDEX CONCURRENTLY pg_toast.pg_toast_1262_index",
8624+
"REINDEX (TABLESPACE regress_tblspace) TABLE pg_toast.pg_toast_1262",
8625+
"REINDEX (TABLESPACE regress_tblspace) TABLE CONCURRENTLY pg_toast.pg_toast_1262",
8626+
"REINDEX (TABLESPACE pg_global) TABLE pg_authid",
8627+
"REINDEX (TABLESPACE pg_global) TABLE CONCURRENTLY pg_authid",
8628+
"REINDEX (TABLESPACE pg_global) INDEX regress_tblspace_test_tbl_idx",
8629+
"REINDEX (TABLESPACE pg_global) INDEX CONCURRENTLY regress_tblspace_test_tbl_idx",
8630+
"REINDEX (TABLESPACE regress_tblspace) INDEX regress_tblspace_test_tbl_idx",
8631+
"REINDEX (TABLESPACE regress_tblspace) TABLE regress_tblspace_test_tbl",
8632+
] {
8633+
pg_and_generic().verified_stmt(sql);
8634+
}
8635+
}
8636+
8637+
#[test]
8638+
fn parse_alter_tablespace_reset_assignment_option() {
8639+
let stmt = pg_and_generic()
8640+
.verified_stmt("ALTER TABLESPACE regress_tblspace RESET (random_page_cost = 2.0)");
8641+
let Statement::AlterTablespace(AlterTablespace {
8642+
name,
8643+
operation: AlterTablespaceOperation::Reset { options },
8644+
}) = stmt
8645+
else {
8646+
panic!("Expected ALTER TABLESPACE RESET statement");
8647+
};
8648+
8649+
assert_eq!(name.value, "regress_tblspace");
8650+
assert_eq!(options.len(), 1);
8651+
let TablespaceResetOption::Assign { key, value } = &options[0] else {
8652+
panic!("Expected assignment form in RESET option list");
8653+
};
8654+
assert_eq!(key.value, "random_page_cost");
8655+
assert_eq!(value.to_string(), "2.0");
8656+
}
8657+
8658+
#[test]
8659+
fn parse_reindex_with_tablespace_utility_option() {
8660+
let stmt = pg_and_generic()
8661+
.verified_stmt("REINDEX (TABLESPACE regress_tblspace) TABLE CONCURRENTLY pg_am");
8662+
let Statement::Reindex(ReindexStatement {
8663+
options,
8664+
object_type,
8665+
concurrently,
8666+
name,
8667+
}) = stmt
8668+
else {
8669+
panic!("Expected REINDEX statement");
8670+
};
8671+
8672+
assert_eq!(object_type, ReindexObjectType::Table);
8673+
assert!(concurrently);
8674+
assert_eq!(name.to_string(), "pg_am");
8675+
8676+
let options = options.expect("Expected utility options");
8677+
assert_eq!(options.len(), 1);
8678+
assert_eq!(options[0].name.value, "TABLESPACE");
8679+
assert_eq!(
8680+
options[0].arg.as_ref().map(ToString::to_string),
8681+
Some("regress_tblspace".to_string())
8682+
);
8683+
}
8684+
8685+
#[test]
8686+
fn reject_postgres_tablespace_forms_in_mysql_dialect() {
8687+
let mysql = TestedDialects::new(vec![Box::new(MySqlDialect {})]);
8688+
assert!(mysql
8689+
.parse_sql_statements("CREATE TABLESPACE t LOCATION ''")
8690+
.is_err());
8691+
assert!(mysql
8692+
.parse_sql_statements("ALTER TABLESPACE t SET (random_page_cost = 1.0)")
8693+
.is_err());
8694+
assert!(mysql
8695+
.parse_sql_statements("DROP TABLESPACE IF EXISTS t")
8696+
.is_err());
8697+
assert!(mysql
8698+
.parse_sql_statements("REINDEX (TABLESPACE t) TABLE pg_am")
8699+
.is_err());
8700+
}
8701+
8702+
#[test]
8703+
fn parse_drop_tablespace_in_postgres() {
8704+
let stmt = pg_and_generic().verified_stmt("DROP TABLESPACE IF EXISTS regress_tblspace");
8705+
let Statement::DropTablespace(DropTablespace {
8706+
if_exists,
8707+
undo,
8708+
name,
8709+
engine,
8710+
}) = stmt
8711+
else {
8712+
panic!("Expected DROP TABLESPACE statement");
8713+
};
8714+
8715+
assert!(if_exists);
8716+
assert!(!undo);
8717+
assert_eq!(name.value, "regress_tblspace");
8718+
assert!(engine.is_none());
8719+
}
8720+
8721+
#[test]
8722+
fn reject_drop_tablespace_cascade_in_postgres() {
8723+
let err = pg()
8724+
.parse_sql_statements("DROP TABLESPACE regress_tblspace CASCADE")
8725+
.unwrap_err()
8726+
.to_string();
8727+
assert!(
8728+
err.contains("Expected: end of DROP TABLESPACE statement"),
8729+
"unexpected error: {err}"
8730+
);
8731+
}

0 commit comments

Comments
 (0)