This is an automated email from the ASF dual-hosted git repository.
alamb pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion-sqlparser-rs.git
The following commit(s) were added to refs/heads/main by this push:
new 2bb81444 Add support for MYSQL's `CREATE TABLE SELECT` expr (#1515)
2bb81444 is described below
commit 2bb81444bd94d2c02f7336c6b9941bd79769fb7f
Author: wugeer <[email protected]>
AuthorDate: Thu Nov 14 01:36:13 2024 +0800
Add support for MYSQL's `CREATE TABLE SELECT` expr (#1515)
---
src/dialect/mod.rs | 5 +++++
src/dialect/mysql.rs | 5 +++++
src/parser/mod.rs | 5 +++++
tests/sqlparser_common.rs | 33 ++++++++++++++++++++++++++++++++-
4 files changed, 47 insertions(+), 1 deletion(-)
diff --git a/src/dialect/mod.rs b/src/dialect/mod.rs
index d95d7c70..a732aa5a 100644
--- a/src/dialect/mod.rs
+++ b/src/dialect/mod.rs
@@ -633,6 +633,11 @@ pub trait Dialect: Debug + Any {
fn supports_comment_on(&self) -> bool {
false
}
+
+ /// Returns true if the dialect supports the `CREATE TABLE SELECT`
statement
+ fn supports_create_table_select(&self) -> bool {
+ false
+ }
}
/// This represents the operators for which precedence must be defined
diff --git a/src/dialect/mysql.rs b/src/dialect/mysql.rs
index d1bf3334..197ce48d 100644
--- a/src/dialect/mysql.rs
+++ b/src/dialect/mysql.rs
@@ -97,6 +97,11 @@ impl Dialect for MySqlDialect {
fn supports_limit_comma(&self) -> bool {
true
}
+
+ /// see <https://dev.mysql.com/doc/refman/8.4/en/create-table-select.html>
+ fn supports_create_table_select(&self) -> bool {
+ true
+ }
}
/// `LOCK TABLES`
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index 756f4d68..4115bbc9 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -5990,6 +5990,11 @@ impl<'a> Parser<'a> {
// Parse optional `AS ( query )`
let query = if self.parse_keyword(Keyword::AS) {
Some(self.parse_query()?)
+ } else if self.dialect.supports_create_table_select() &&
self.parse_keyword(Keyword::SELECT)
+ {
+ // rewind the SELECT keyword
+ self.prev_token();
+ Some(self.parse_query()?)
} else {
None
};
diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs
index 25bf306a..daf65edf 100644
--- a/tests/sqlparser_common.rs
+++ b/tests/sqlparser_common.rs
@@ -6501,7 +6501,17 @@ fn parse_multiple_statements() {
);
test_with("DELETE FROM foo", "SELECT", " bar");
test_with("INSERT INTO foo VALUES (1)", "SELECT", " bar");
- test_with("CREATE TABLE foo (baz INT)", "SELECT", " bar");
+ // Since MySQL supports the `CREATE TABLE SELECT` syntax, this needs to be
handled separately
+ let res = parse_sql_statements("CREATE TABLE foo (baz INT); SELECT bar");
+ assert_eq!(
+ vec![
+ one_statement_parses_to("CREATE TABLE foo (baz INT)", ""),
+ one_statement_parses_to("SELECT bar", ""),
+ ],
+ res.unwrap()
+ );
+ // Check that extra semicolon at the end is stripped by normalization:
+ one_statement_parses_to("CREATE TABLE foo (baz INT);", "CREATE TABLE foo
(baz INT)");
// Make sure that empty statements do not cause an error:
let res = parse_sql_statements(";;");
assert_eq!(0, res.unwrap().len());
@@ -11717,3 +11727,24 @@ fn parse_comments() {
ParserError::ParserError("Expected: comment object_type, found:
UNKNOWN".to_string())
);
}
+
+#[test]
+fn parse_create_table_select() {
+ let dialects = all_dialects_where(|d| d.supports_create_table_select());
+ let sql_1 = r#"CREATE TABLE foo (baz INT) SELECT bar"#;
+ let expected = r#"CREATE TABLE foo (baz INT) AS SELECT bar"#;
+ let _ = dialects.one_statement_parses_to(sql_1, expected);
+
+ let sql_2 = r#"CREATE TABLE foo (baz INT, name STRING) SELECT bar,
oth_name FROM test.table_a"#;
+ let expected =
+ r#"CREATE TABLE foo (baz INT, name STRING) AS SELECT bar, oth_name
FROM test.table_a"#;
+ let _ = dialects.one_statement_parses_to(sql_2, expected);
+
+ let dialects = all_dialects_where(|d| !d.supports_create_table_select());
+ for sql in [sql_1, sql_2] {
+ assert_eq!(
+ dialects.parse_sql_statements(sql).unwrap_err(),
+ ParserError::ParserError("Expected: end of statement, found:
SELECT".to_string())
+ );
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]