This is an automated email from the ASF dual-hosted git repository.
github-bot 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 7461d8bd MySQL: `CREATE INDEX`: allow `USING` clause before `ON`
(#2029)
7461d8bd is described below
commit 7461d8bd02701de55960851c531c1b5326a737c9
Author: Mohamed Abdeen <[email protected]>
AuthorDate: Fri Sep 26 11:46:18 2025 +0100
MySQL: `CREATE INDEX`: allow `USING` clause before `ON` (#2029)
---
src/ast/ddl.rs | 2 ++
src/parser/mod.rs | 15 ++++++++++-----
tests/sqlparser_common.rs | 43 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 55 insertions(+), 5 deletions(-)
diff --git a/src/ast/ddl.rs b/src/ast/ddl.rs
index 4c145f91..c4f76967 100644
--- a/src/ast/ddl.rs
+++ b/src/ast/ddl.rs
@@ -2361,6 +2361,8 @@ pub struct CreateIndex {
pub name: Option<ObjectName>,
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
pub table_name: ObjectName,
+ /// Index type used in the statement. Can also be found inside
[`CreateIndex::index_options`]
+ /// depending on the position of the option within the statement.
pub using: Option<IndexType>,
pub columns: Vec<IndexColumn>,
pub unique: bool,
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index 66089be7..d97fa1bd 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -7063,19 +7063,24 @@ impl<'a> Parser<'a> {
pub fn parse_create_index(&mut self, unique: bool) -> Result<Statement,
ParserError> {
let concurrently = self.parse_keyword(Keyword::CONCURRENTLY);
let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT,
Keyword::EXISTS]);
+
+ let mut using = None;
+
let index_name = if if_not_exists || !self.parse_keyword(Keyword::ON) {
let index_name = self.parse_object_name(false)?;
+ // MySQL allows `USING index_type` either before or after `ON
table_name`
+ using = self.parse_optional_using_then_index_type()?;
self.expect_keyword_is(Keyword::ON)?;
Some(index_name)
} else {
None
};
+
let table_name = self.parse_object_name(false)?;
- let using = if self.parse_keyword(Keyword::USING) {
- Some(self.parse_index_type()?)
- } else {
- None
- };
+
+ // MySQL allows having two `USING` clauses.
+ // In that case, the second clause overwrites the first.
+ using = self.parse_optional_using_then_index_type()?.or(using);
let columns = self.parse_parenthesized_index_column_list()?;
diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs
index b9434581..365d5469 100644
--- a/tests/sqlparser_common.rs
+++ b/tests/sqlparser_common.rs
@@ -17252,6 +17252,49 @@ fn parse_invisible_column() {
}
}
+#[test]
+fn parse_create_index_different_using_positions() {
+ let sql = "CREATE INDEX idx_name USING BTREE ON table_name (col1)";
+ let expected = "CREATE INDEX idx_name ON table_name USING BTREE (col1)";
+ match all_dialects().one_statement_parses_to(sql, expected) {
+ Statement::CreateIndex(CreateIndex {
+ name,
+ table_name,
+ using,
+ columns,
+ unique,
+ ..
+ }) => {
+ assert_eq!(name.unwrap().to_string(), "idx_name");
+ assert_eq!(table_name.to_string(), "table_name");
+ assert_eq!(using, Some(IndexType::BTree));
+ assert_eq!(columns.len(), 1);
+ assert!(!unique);
+ }
+ _ => unreachable!(),
+ }
+
+ let sql = "CREATE INDEX idx_name USING BTREE ON table_name (col1) USING
HASH";
+ let expected = "CREATE INDEX idx_name ON table_name USING BTREE (col1)
USING HASH";
+ match all_dialects().one_statement_parses_to(sql, expected) {
+ Statement::CreateIndex(CreateIndex {
+ name,
+ table_name,
+ columns,
+ index_options,
+ ..
+ }) => {
+ assert_eq!(name.unwrap().to_string(), "idx_name");
+ assert_eq!(table_name.to_string(), "table_name");
+ assert_eq!(columns.len(), 1);
+ assert!(index_options
+ .iter()
+ .any(|o| o == &IndexOption::Using(IndexType::Hash)));
+ }
+ _ => unreachable!(),
+ }
+}
+
#[test]
fn test_parse_alter_user() {
verified_stmt("ALTER USER u1");
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]