Skip to content

Commit 9c7d91b

Browse files
Add TABLESPACE coverage for MySQL and PostgreSQL
1 parent c4b604e commit 9c7d91b

2 files changed

Lines changed: 232 additions & 1 deletion

File tree

tests/sqlparser_mysql.rs

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4900,3 +4900,107 @@ fn parse_adjacent_string_literal_concatenation() {
49004900
let sql = r#"SELECT 'M' "y" 'S' "q" 'l'"#;
49014901
mysql().one_statement_parses_to(sql, r"SELECT 'MySql'");
49024902
}
4903+
4904+
#[test]
4905+
fn parse_mysql_create_tablespace() {
4906+
let sql =
4907+
"CREATE TABLESPACE ts ADD DATAFILE 'ts.ibd' FILE_BLOCK_SIZE = 4096 ENCRYPTION = 'Y' ENGINE = InnoDB ENGINE_ATTRIBUTE = 'ndb_general'";
4908+
let stmt = mysql_and_generic().verified_stmt(sql);
4909+
4910+
let Statement::CreateTablespace(CreateTablespace { name, definition }) = stmt else {
4911+
panic!("Expected CREATE TABLESPACE");
4912+
};
4913+
assert_eq!(name.value, "ts");
4914+
4915+
let CreateTablespaceDefinition::MySql { undo, options } = definition else {
4916+
panic!("Expected MySQL CREATE TABLESPACE definition");
4917+
};
4918+
assert!(!undo);
4919+
assert_eq!(
4920+
options[0],
4921+
MySqlCreateTablespaceOption::AddDatafile("ts.ibd".to_string())
4922+
);
4923+
assert_eq!(options[1].to_string(), "FILE_BLOCK_SIZE = 4096");
4924+
assert_eq!(options[2].to_string(), "ENCRYPTION = 'Y'");
4925+
assert_eq!(options[3].to_string(), "ENGINE = InnoDB");
4926+
assert_eq!(options[4].to_string(), "ENGINE_ATTRIBUTE = 'ndb_general'");
4927+
}
4928+
4929+
#[test]
4930+
fn parse_mysql_create_tablespace_without_add_datafile() {
4931+
mysql_and_generic().one_statement_parses_to(
4932+
"CREATE TABLESPACE ts ENGINE InnoDB",
4933+
"CREATE TABLESPACE ts ENGINE = InnoDB",
4934+
);
4935+
}
4936+
4937+
#[test]
4938+
fn parse_mysql_create_undo_tablespace() {
4939+
mysql_and_generic().one_statement_parses_to(
4940+
"CREATE UNDO TABLESPACE undo_ts ADD DATAFILE 'undo_001.ibu' ENGINE InnoDB",
4941+
"CREATE UNDO TABLESPACE undo_ts ADD DATAFILE 'undo_001.ibu' ENGINE = InnoDB",
4942+
);
4943+
}
4944+
4945+
#[test]
4946+
fn parse_mysql_alter_tablespace() {
4947+
let stmt = mysql_and_generic().verified_stmt(
4948+
"ALTER TABLESPACE ts ADD DATAFILE 'ts2.ibd' INITIAL_SIZE = 16 AUTOEXTEND_SIZE = 32 WAIT ENGINE = InnoDB ENGINE_ATTRIBUTE = 'ndb_general'",
4949+
);
4950+
let Statement::AlterTablespace(AlterTablespace {
4951+
name,
4952+
operation: AlterTablespaceOperation::MySql { undo, options },
4953+
}) = stmt
4954+
else {
4955+
panic!("Expected MySQL ALTER TABLESPACE ADD DATAFILE");
4956+
};
4957+
4958+
assert_eq!(name.value, "ts");
4959+
assert!(!undo);
4960+
assert_eq!(
4961+
options
4962+
.iter()
4963+
.map(ToString::to_string)
4964+
.collect::<Vec<String>>(),
4965+
vec![
4966+
"ADD DATAFILE 'ts2.ibd'",
4967+
"INITIAL_SIZE = 16",
4968+
"AUTOEXTEND_SIZE = 32",
4969+
"WAIT",
4970+
"ENGINE = InnoDB",
4971+
"ENGINE_ATTRIBUTE = 'ndb_general'",
4972+
]
4973+
);
4974+
4975+
mysql_and_generic().one_statement_parses_to(
4976+
"ALTER UNDO TABLESPACE undo_ts SET ACTIVE",
4977+
"ALTER UNDO TABLESPACE undo_ts SET ACTIVE",
4978+
);
4979+
}
4980+
4981+
#[test]
4982+
fn parse_mysql_drop_tablespace() {
4983+
let stmt = mysql_and_generic().one_statement_parses_to(
4984+
"DROP UNDO TABLESPACE undo_ts ENGINE InnoDB",
4985+
"DROP UNDO TABLESPACE undo_ts ENGINE = InnoDB",
4986+
);
4987+
let Statement::DropTablespace(DropTablespace {
4988+
if_exists,
4989+
undo,
4990+
name,
4991+
engine,
4992+
}) = stmt
4993+
else {
4994+
panic!("Expected DROP TABLESPACE");
4995+
};
4996+
4997+
assert!(!if_exists);
4998+
assert!(undo);
4999+
assert_eq!(name.value, "undo_ts");
5000+
assert_eq!(engine.as_ref().map(|i| i.value.as_str()), Some("InnoDB"));
5001+
5002+
mysql_and_generic().one_statement_parses_to(
5003+
"DROP TABLESPACE ts ENGINE InnoDB",
5004+
"DROP TABLESPACE ts ENGINE = InnoDB",
5005+
);
5006+
}

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::*;
@@ -9221,3 +9221,130 @@ fn parse_lock_table() {
92219221
}
92229222
}
92239223
}
9224+
9225+
#[test]
9226+
fn parse_tablespace_and_reindex_regression_cases() {
9227+
for sql in [
9228+
"CREATE TABLESPACE regress_tblspace LOCATION 'relative'",
9229+
"CREATE TABLESPACE regress_tblspace LOCATION ''",
9230+
"CREATE TABLESPACE regress_tblspacewith LOCATION '' WITH (some_nonexistent_parameter = true)",
9231+
"CREATE TABLESPACE regress_tblspacewith LOCATION '' WITH (random_page_cost = 3.0)",
9232+
"DROP TABLESPACE regress_tblspacewith",
9233+
"ALTER TABLESPACE regress_tblspace SET (random_page_cost = 1.0, seq_page_cost = 1.1)",
9234+
"ALTER TABLESPACE regress_tblspace SET (some_nonexistent_parameter = true)",
9235+
"ALTER TABLESPACE regress_tblspace RESET (random_page_cost = 2.0)",
9236+
"ALTER TABLESPACE regress_tblspace RESET (random_page_cost, effective_io_concurrency)",
9237+
"REINDEX (TABLESPACE regress_tblspace) TABLE pg_am",
9238+
"REINDEX (TABLESPACE regress_tblspace) TABLE CONCURRENTLY pg_am",
9239+
"REINDEX (TABLESPACE regress_tblspace) TABLE pg_authid",
9240+
"REINDEX (TABLESPACE regress_tblspace) TABLE CONCURRENTLY pg_authid",
9241+
"REINDEX (TABLESPACE regress_tblspace) INDEX pg_toast.pg_toast_1262_index",
9242+
"REINDEX (TABLESPACE regress_tblspace) INDEX CONCURRENTLY pg_toast.pg_toast_1262_index",
9243+
"REINDEX (TABLESPACE regress_tblspace) TABLE pg_toast.pg_toast_1262",
9244+
"REINDEX (TABLESPACE regress_tblspace) TABLE CONCURRENTLY pg_toast.pg_toast_1262",
9245+
"REINDEX (TABLESPACE pg_global) TABLE pg_authid",
9246+
"REINDEX (TABLESPACE pg_global) TABLE CONCURRENTLY pg_authid",
9247+
"REINDEX (TABLESPACE pg_global) INDEX regress_tblspace_test_tbl_idx",
9248+
"REINDEX (TABLESPACE pg_global) INDEX CONCURRENTLY regress_tblspace_test_tbl_idx",
9249+
"REINDEX (TABLESPACE regress_tblspace) INDEX regress_tblspace_test_tbl_idx",
9250+
"REINDEX (TABLESPACE regress_tblspace) TABLE regress_tblspace_test_tbl",
9251+
] {
9252+
pg_and_generic().verified_stmt(sql);
9253+
}
9254+
}
9255+
9256+
#[test]
9257+
fn parse_alter_tablespace_reset_assignment_option() {
9258+
let stmt = pg_and_generic()
9259+
.verified_stmt("ALTER TABLESPACE regress_tblspace RESET (random_page_cost = 2.0)");
9260+
let Statement::AlterTablespace(AlterTablespace {
9261+
name,
9262+
operation: AlterTablespaceOperation::Reset { options },
9263+
}) = stmt
9264+
else {
9265+
panic!("Expected ALTER TABLESPACE RESET statement");
9266+
};
9267+
9268+
assert_eq!(name.value, "regress_tblspace");
9269+
assert_eq!(options.len(), 1);
9270+
let TablespaceResetOption::Assign { key, value } = &options[0] else {
9271+
panic!("Expected assignment form in RESET option list");
9272+
};
9273+
assert_eq!(key.value, "random_page_cost");
9274+
assert_eq!(value.to_string(), "2.0");
9275+
}
9276+
9277+
#[test]
9278+
fn parse_reindex_with_tablespace_utility_option() {
9279+
let stmt = pg_and_generic()
9280+
.verified_stmt("REINDEX (TABLESPACE regress_tblspace) TABLE CONCURRENTLY pg_am");
9281+
let Statement::Reindex(ReindexStatement {
9282+
options,
9283+
object_type,
9284+
concurrently,
9285+
name,
9286+
}) = stmt
9287+
else {
9288+
panic!("Expected REINDEX statement");
9289+
};
9290+
9291+
assert_eq!(object_type, ReindexObjectType::Table);
9292+
assert!(concurrently);
9293+
assert_eq!(name.to_string(), "pg_am");
9294+
9295+
let options = options.expect("Expected utility options");
9296+
assert_eq!(options.len(), 1);
9297+
assert_eq!(options[0].name.value, "TABLESPACE");
9298+
assert_eq!(
9299+
options[0].arg.as_ref().map(ToString::to_string),
9300+
Some("regress_tblspace".to_string())
9301+
);
9302+
}
9303+
9304+
#[test]
9305+
fn reject_postgres_tablespace_forms_in_mysql_dialect() {
9306+
let mysql = TestedDialects::new(vec![Box::new(MySqlDialect {})]);
9307+
assert!(mysql
9308+
.parse_sql_statements("CREATE TABLESPACE t LOCATION ''")
9309+
.is_err());
9310+
assert!(mysql
9311+
.parse_sql_statements("ALTER TABLESPACE t SET (random_page_cost = 1.0)")
9312+
.is_err());
9313+
assert!(mysql
9314+
.parse_sql_statements("DROP TABLESPACE IF EXISTS t")
9315+
.is_err());
9316+
assert!(mysql
9317+
.parse_sql_statements("REINDEX (TABLESPACE t) TABLE pg_am")
9318+
.is_err());
9319+
}
9320+
9321+
#[test]
9322+
fn parse_drop_tablespace_in_postgres() {
9323+
let stmt = pg_and_generic().verified_stmt("DROP TABLESPACE IF EXISTS regress_tblspace");
9324+
let Statement::DropTablespace(DropTablespace {
9325+
if_exists,
9326+
undo,
9327+
name,
9328+
engine,
9329+
}) = stmt
9330+
else {
9331+
panic!("Expected DROP TABLESPACE statement");
9332+
};
9333+
9334+
assert!(if_exists);
9335+
assert!(!undo);
9336+
assert_eq!(name.value, "regress_tblspace");
9337+
assert!(engine.is_none());
9338+
}
9339+
9340+
#[test]
9341+
fn reject_drop_tablespace_cascade_in_postgres() {
9342+
let err = pg()
9343+
.parse_sql_statements("DROP TABLESPACE regress_tblspace CASCADE")
9344+
.unwrap_err()
9345+
.to_string();
9346+
assert!(
9347+
err.contains("Expected: end of DROP TABLESPACE statement"),
9348+
"unexpected error: {err}"
9349+
);
9350+
}

0 commit comments

Comments
 (0)