Skip to content

Commit 9d88719

Browse files
Add TABLESPACE coverage for MySQL and PostgreSQL
1 parent 126929a commit 9d88719

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

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

0 commit comments

Comments
 (0)