From 484c912816dbb0536ebc13647834b2badccba098 Mon Sep 17 00:00:00 2001 From: MohamedAbdeen21 Date: Thu, 15 May 2025 20:59:04 +0100 Subject: [PATCH 1/6] Mysql: Add `SRID` column option Add support for Mysql geometric `SRID {int}` column def in create table statements. --- src/ast/ddl.rs | 10 ++++++++++ src/ast/spans.rs | 1 + src/keywords.rs | 1 + src/parser/mod.rs | 18 ++++++++++++++++++ 4 files changed, 30 insertions(+) diff --git a/src/ast/ddl.rs b/src/ast/ddl.rs index 270897130..5af586743 100644 --- a/src/ast/ddl.rs +++ b/src/ast/ddl.rs @@ -1758,6 +1758,13 @@ pub enum ColumnOption { /// ``` /// [Snowflake]: https://docs.snowflake.com/en/sql-reference/sql/create-table Tags(TagsColumnOption), + /// MySQL specific: Spatial reference identifier + /// Syntax: + /// ```sql + /// CREATE TABLE geom (g GEOMETRY NOT NULL SRID 4326); + /// ``` + /// [MySQL]: https://dev.mysql.com/doc/refman/8.4/en/creating-spatial-indexes.html + Srid(Expr), } impl fmt::Display for ColumnOption { @@ -1873,6 +1880,9 @@ impl fmt::Display for ColumnOption { Tags(tags) => { write!(f, "{tags}") } + Srid(srid) => { + write!(f, "SRID {srid}") + } } } } diff --git a/src/ast/spans.rs b/src/ast/spans.rs index bffd11722..1c28b62cc 100644 --- a/src/ast/spans.rs +++ b/src/ast/spans.rs @@ -871,6 +871,7 @@ impl Spanned for ColumnOption { ColumnOption::OnConflict(..) => Span::empty(), ColumnOption::Policy(..) => Span::empty(), ColumnOption::Tags(..) => Span::empty(), + ColumnOption::Srid(..) => Span::empty(), } } } diff --git a/src/keywords.rs b/src/keywords.rs index aaa2e167f..f5c5e567e 100644 --- a/src/keywords.rs +++ b/src/keywords.rs @@ -844,6 +844,7 @@ define_keywords!( SQLSTATE, SQLWARNING, SQRT, + SRID, STABLE, STAGE, START, diff --git a/src/parser/mod.rs b/src/parser/mod.rs index f6a45adad..808d18098 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -7754,6 +7754,10 @@ impl<'a> Parser<'a> { && dialect_of!(self is MySqlDialect | SQLiteDialect | DuckDbDialect | GenericDialect) { self.parse_optional_column_option_as() + } else if self.parse_keyword(Keyword::SRID) + && dialect_of!(self is MySqlDialect | GenericDialect) + { + Ok(Some(ColumnOption::Srid(self.parse_expr()?))) } else if self.parse_keyword(Keyword::IDENTITY) && dialect_of!(self is MsSqlDialect | GenericDialect) { @@ -16577,6 +16581,20 @@ mod tests { } } + #[test] + fn test_mysql_srid_create_table() { + let sql = r#"CREATE TABLE t (a geometry SRID 4326)"#; + let ast: Vec = Parser::parse_sql(&MySqlDialect {}, sql).unwrap(); + + assert_eq!(ast.len(), 1); + if let Statement::CreateTable(v) = &ast[0] { + assert_eq!( + v.columns[0].options[0].option, + ColumnOption::Srid(Expr::value(Value::Number("4326".to_string(), false))) + ); + } + } + #[test] fn test_replace_into_placeholders() { let sql = "REPLACE INTO t (a) VALUES (&a)"; From 415497594cd3c2c25c339d0104bc68b8c85159da Mon Sep 17 00:00:00 2001 From: MohamedAbdeen21 Date: Thu, 15 May 2025 21:08:57 +0100 Subject: [PATCH 2/6] Fix static numeric value in test --- src/parser/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 808d18098..6f384e3f0 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -16590,7 +16590,7 @@ mod tests { if let Statement::CreateTable(v) = &ast[0] { assert_eq!( v.columns[0].options[0].option, - ColumnOption::Srid(Expr::value(Value::Number("4326".to_string(), false))) + ColumnOption::Srid(Expr::value(Value::Number("4326".parse().unwrap(), false))) ); } } From eaa09d32f71248618e925ffee849c1c4874b8adf Mon Sep 17 00:00:00 2001 From: MohamedAbdeen21 Date: Thu, 15 May 2025 21:19:47 +0100 Subject: [PATCH 3/6] Box Expr to avoid large variant clippy warning --- src/ast/ddl.rs | 2 +- src/parser/mod.rs | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/ast/ddl.rs b/src/ast/ddl.rs index 5af586743..a8a1fdbae 100644 --- a/src/ast/ddl.rs +++ b/src/ast/ddl.rs @@ -1764,7 +1764,7 @@ pub enum ColumnOption { /// CREATE TABLE geom (g GEOMETRY NOT NULL SRID 4326); /// ``` /// [MySQL]: https://dev.mysql.com/doc/refman/8.4/en/creating-spatial-indexes.html - Srid(Expr), + Srid(Box), } impl fmt::Display for ColumnOption { diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 6f384e3f0..85b653894 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -7757,7 +7757,7 @@ impl<'a> Parser<'a> { } else if self.parse_keyword(Keyword::SRID) && dialect_of!(self is MySqlDialect | GenericDialect) { - Ok(Some(ColumnOption::Srid(self.parse_expr()?))) + Ok(Some(ColumnOption::Srid(Box::new(self.parse_expr()?)))) } else if self.parse_keyword(Keyword::IDENTITY) && dialect_of!(self is MsSqlDialect | GenericDialect) { @@ -16590,7 +16590,10 @@ mod tests { if let Statement::CreateTable(v) = &ast[0] { assert_eq!( v.columns[0].options[0].option, - ColumnOption::Srid(Expr::value(Value::Number("4326".parse().unwrap(), false))) + ColumnOption::Srid(Box::new(Expr::value(Value::Number( + "4326".parse().unwrap(), + false + )))) ); } } From 60f5468b9b57c68cff4df182b0414434cb3a13b7 Mon Sep 17 00:00:00 2001 From: MohamedAbdeen21 Date: Thu, 15 May 2025 21:27:23 +0100 Subject: [PATCH 4/6] trying to fix clippy warning --- src/parser/mod.rs | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 85b653894..47b321d9c 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -16581,23 +16581,6 @@ mod tests { } } - #[test] - fn test_mysql_srid_create_table() { - let sql = r#"CREATE TABLE t (a geometry SRID 4326)"#; - let ast: Vec = Parser::parse_sql(&MySqlDialect {}, sql).unwrap(); - - assert_eq!(ast.len(), 1); - if let Statement::CreateTable(v) = &ast[0] { - assert_eq!( - v.columns[0].options[0].option, - ColumnOption::Srid(Box::new(Expr::value(Value::Number( - "4326".parse().unwrap(), - false - )))) - ); - } - } - #[test] fn test_replace_into_placeholders() { let sql = "REPLACE INTO t (a) VALUES (&a)"; From 0890aee7c56d6efe5eb912f38d641255baeba795 Mon Sep 17 00:00:00 2001 From: MohamedAbdeen21 Date: Thu, 15 May 2025 21:29:38 +0100 Subject: [PATCH 5/6] revert last change --- src/parser/mod.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 47b321d9c..85b653894 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -16581,6 +16581,23 @@ mod tests { } } + #[test] + fn test_mysql_srid_create_table() { + let sql = r#"CREATE TABLE t (a geometry SRID 4326)"#; + let ast: Vec = Parser::parse_sql(&MySqlDialect {}, sql).unwrap(); + + assert_eq!(ast.len(), 1); + if let Statement::CreateTable(v) = &ast[0] { + assert_eq!( + v.columns[0].options[0].option, + ColumnOption::Srid(Box::new(Expr::value(Value::Number( + "4326".parse().unwrap(), + false + )))) + ); + } + } + #[test] fn test_replace_into_placeholders() { let sql = "REPLACE INTO t (a) VALUES (&a)"; From 78bc1be6ae25e2761b318995f52c6d1c3a537abe Mon Sep 17 00:00:00 2001 From: MohamedAbdeen21 Date: Wed, 21 May 2025 21:53:49 +0100 Subject: [PATCH 6/6] move test to mysql tests file --- src/parser/mod.rs | 17 ----------------- tests/sqlparser_mysql.rs | 5 +++++ 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 85b653894..47b321d9c 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -16581,23 +16581,6 @@ mod tests { } } - #[test] - fn test_mysql_srid_create_table() { - let sql = r#"CREATE TABLE t (a geometry SRID 4326)"#; - let ast: Vec = Parser::parse_sql(&MySqlDialect {}, sql).unwrap(); - - assert_eq!(ast.len(), 1); - if let Statement::CreateTable(v) = &ast[0] { - assert_eq!( - v.columns[0].options[0].option, - ColumnOption::Srid(Box::new(Expr::value(Value::Number( - "4326".parse().unwrap(), - false - )))) - ); - } - } - #[test] fn test_replace_into_placeholders() { let sql = "REPLACE INTO t (a) VALUES (&a)"; diff --git a/tests/sqlparser_mysql.rs b/tests/sqlparser_mysql.rs index dd279894a..bcde14ee5 100644 --- a/tests/sqlparser_mysql.rs +++ b/tests/sqlparser_mysql.rs @@ -3745,6 +3745,11 @@ fn parse_begin_without_transaction() { mysql().verified_stmt("BEGIN"); } +#[test] +fn parse_geometric_types_srid_option() { + mysql_and_generic().verified_stmt("CREATE TABLE t (a geometry SRID 4326)"); +} + #[test] fn parse_double_precision() { mysql().verified_stmt("CREATE TABLE foo (bar DOUBLE)");