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 cb21477f MySQL: Allow optional constraint name after CONSTRAINT
keyword (#2183)
cb21477f is described below
commit cb21477fdc4527d6a09accf3da201c086782293e
Author: Michael Victor Zink <[email protected]>
AuthorDate: Fri Feb 6 03:19:53 2026 -0800
MySQL: Allow optional constraint name after CONSTRAINT keyword (#2183)
---
src/dialect/generic.rs | 4 ++++
src/dialect/mod.rs | 17 +++++++++++++++++
src/dialect/mysql.rs | 5 +++++
src/parser/mod.rs | 15 ++++++++++++++-
tests/sqlparser_mysql.rs | 21 +++++++++++++++++++++
5 files changed, 61 insertions(+), 1 deletion(-)
diff --git a/src/dialect/generic.rs b/src/dialect/generic.rs
index 345d63fe..6d25fa2b 100644
--- a/src/dialect/generic.rs
+++ b/src/dialect/generic.rs
@@ -275,4 +275,8 @@ impl Dialect for GenericDialect {
fn supports_comment_optimizer_hint(&self) -> bool {
true
}
+
+ fn supports_constraint_keyword_without_name(&self) -> bool {
+ true
+ }
}
diff --git a/src/dialect/mod.rs b/src/dialect/mod.rs
index f23eb387..15a9c2d1 100644
--- a/src/dialect/mod.rs
+++ b/src/dialect/mod.rs
@@ -1169,6 +1169,23 @@ pub trait Dialect: Debug + Any {
false
}
+ /// Returns true if the dialect supports the `CONSTRAINT` keyword without
a name
+ /// in table constraint definitions.
+ ///
+ /// Example:
+ /// ```sql
+ /// CREATE TABLE t (a INT, CONSTRAINT CHECK (a > 0))
+ /// ```
+ ///
+ /// This is a MySQL extension; the SQL standard requires a name after
`CONSTRAINT`.
+ /// When the name is omitted, the output normalizes to just the constraint
type
+ /// without the `CONSTRAINT` keyword (e.g., `CHECK (a > 0)`).
+ ///
+ /// <https://dev.mysql.com/doc/refman/8.4/en/create-table.html>
+ fn supports_constraint_keyword_without_name(&self) -> bool {
+ false
+ }
+
/// Returns true if the specified keyword is reserved and cannot be
/// used as an identifier without special handling like quoting.
fn is_reserved_for_identifier(&self, kw: Keyword) -> bool {
diff --git a/src/dialect/mysql.rs b/src/dialect/mysql.rs
index e1a68417..3adb4bc2 100644
--- a/src/dialect/mysql.rs
+++ b/src/dialect/mysql.rs
@@ -190,6 +190,11 @@ impl Dialect for MySqlDialect {
fn supports_comment_optimizer_hint(&self) -> bool {
true
}
+
+ /// See: <https://dev.mysql.com/doc/refman/8.4/en/create-table.html>
+ fn supports_constraint_keyword_without_name(&self) -> bool {
+ true
+ }
}
/// `LOCK TABLES`
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index 5b1f5990..fb150b76 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -9293,7 +9293,20 @@ impl<'a> Parser<'a> {
&mut self,
) -> Result<Option<TableConstraint>, ParserError> {
let name = if self.parse_keyword(Keyword::CONSTRAINT) {
- Some(self.parse_identifier()?)
+ if self.dialect.supports_constraint_keyword_without_name()
+ && self
+ .peek_one_of_keywords(&[
+ Keyword::CHECK,
+ Keyword::PRIMARY,
+ Keyword::UNIQUE,
+ Keyword::FOREIGN,
+ ])
+ .is_some()
+ {
+ None
+ } else {
+ Some(self.parse_identifier()?)
+ }
} else {
None
};
diff --git a/tests/sqlparser_mysql.rs b/tests/sqlparser_mysql.rs
index 601b6c4f..1b9d12f8 100644
--- a/tests/sqlparser_mysql.rs
+++ b/tests/sqlparser_mysql.rs
@@ -3469,6 +3469,27 @@ fn parse_create_table_unallow_constraint_then_index() {
assert!(mysql_and_generic().parse_sql_statements(sql).is_ok());
}
+#[test]
+fn parse_create_table_constraint_check_without_name() {
+ let dialects = all_dialects_where(|d|
d.supports_constraint_keyword_without_name());
+ dialects.one_statement_parses_to(
+ "CREATE TABLE t (x INT, CONSTRAINT PRIMARY KEY (x))",
+ "CREATE TABLE t (x INT, PRIMARY KEY (x))",
+ );
+ dialects.one_statement_parses_to(
+ "CREATE TABLE t (x INT, CONSTRAINT UNIQUE (x))",
+ "CREATE TABLE t (x INT, UNIQUE (x))",
+ );
+ dialects.one_statement_parses_to(
+ "CREATE TABLE t (x INT, CONSTRAINT FOREIGN KEY (x) REFERENCES t2(id))",
+ "CREATE TABLE t (x INT, FOREIGN KEY (x) REFERENCES t2(id))",
+ );
+ dialects.one_statement_parses_to(
+ "CREATE TABLE t (x INT, CONSTRAINT CHECK (x > 1))",
+ "CREATE TABLE t (x INT, CHECK (x > 1))",
+ );
+}
+
#[test]
fn parse_create_table_with_fulltext_definition() {
mysql_and_generic().verified_stmt("CREATE TABLE tb (id INT, FULLTEXT
(id))");
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]