MySQL: [[NOT] ENFORCED] in CHECK constraint (#1870)

This commit is contained in:
Mohamed Abdeen 2025-06-07 05:48:40 +01:00 committed by GitHub
parent ff29dd25b2
commit 84c3a1b325
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 46 additions and 7 deletions

View file

@ -1029,10 +1029,13 @@ pub enum TableConstraint {
on_update: Option<ReferentialAction>, on_update: Option<ReferentialAction>,
characteristics: Option<ConstraintCharacteristics>, characteristics: Option<ConstraintCharacteristics>,
}, },
/// `[ CONSTRAINT <name> ] CHECK (<expr>)` /// `[ CONSTRAINT <name> ] CHECK (<expr>) [[NOT] ENFORCED]`
Check { Check {
name: Option<Ident>, name: Option<Ident>,
expr: Box<Expr>, expr: Box<Expr>,
/// MySQL-specific syntax
/// <https://dev.mysql.com/doc/refman/8.4/en/create-table.html>
enforced: Option<bool>,
}, },
/// MySQLs [index definition][1] for index creation. Not present on ANSI so, for now, the usage /// MySQLs [index definition][1] for index creation. Not present on ANSI so, for now, the usage
/// is restricted to MySQL, as no other dialects that support this syntax were found. /// is restricted to MySQL, as no other dialects that support this syntax were found.
@ -1162,8 +1165,17 @@ impl fmt::Display for TableConstraint {
} }
Ok(()) Ok(())
} }
TableConstraint::Check { name, expr } => { TableConstraint::Check {
write!(f, "{}CHECK ({})", display_constraint_name(name), expr) name,
expr,
enforced,
} => {
write!(f, "{}CHECK ({})", display_constraint_name(name), expr)?;
if let Some(b) = enforced {
write!(f, " {}", if *b { "ENFORCED" } else { "NOT ENFORCED" })
} else {
Ok(())
}
} }
TableConstraint::Index { TableConstraint::Index {
display_as_key, display_as_key,

View file

@ -687,9 +687,11 @@ impl Spanned for TableConstraint {
.chain(on_update.iter().map(|i| i.span())) .chain(on_update.iter().map(|i| i.span()))
.chain(characteristics.iter().map(|i| i.span())), .chain(characteristics.iter().map(|i| i.span())),
), ),
TableConstraint::Check { name, expr } => { TableConstraint::Check {
expr.span().union_opt(&name.as_ref().map(|i| i.span)) name,
} expr,
enforced: _,
} => expr.span().union_opt(&name.as_ref().map(|i| i.span)),
TableConstraint::Index { TableConstraint::Index {
display_as_key: _, display_as_key: _,
name, name,

View file

@ -8139,7 +8139,20 @@ impl<'a> Parser<'a> {
self.expect_token(&Token::LParen)?; self.expect_token(&Token::LParen)?;
let expr = Box::new(self.parse_expr()?); let expr = Box::new(self.parse_expr()?);
self.expect_token(&Token::RParen)?; self.expect_token(&Token::RParen)?;
Ok(Some(TableConstraint::Check { name, expr }))
let enforced = if self.parse_keyword(Keyword::ENFORCED) {
Some(true)
} else if self.parse_keywords(&[Keyword::NOT, Keyword::ENFORCED]) {
Some(false)
} else {
None
};
Ok(Some(TableConstraint::Check {
name,
expr,
enforced,
}))
} }
Token::Word(w) Token::Word(w)
if (w.keyword == Keyword::INDEX || w.keyword == Keyword::KEY) if (w.keyword == Keyword::INDEX || w.keyword == Keyword::KEY)

View file

@ -15336,3 +15336,10 @@ fn parse_truncate_only() {
truncate truncate
); );
} }
#[test]
fn check_enforced() {
all_dialects().verified_stmt(
"CREATE TABLE t (a INT, b INT, c INT, CHECK (a > 0) NOT ENFORCED, CHECK (b > 0) ENFORCED, CHECK (c > 0))",
);
}

View file

@ -5378,6 +5378,7 @@ fn parse_create_domain() {
op: BinaryOperator::Gt, op: BinaryOperator::Gt,
right: Box::new(Expr::Value(test_utils::number("0").into())), right: Box::new(Expr::Value(test_utils::number("0").into())),
}), }),
enforced: None,
}], }],
}); });
@ -5396,6 +5397,7 @@ fn parse_create_domain() {
op: BinaryOperator::Gt, op: BinaryOperator::Gt,
right: Box::new(Expr::Value(test_utils::number("0").into())), right: Box::new(Expr::Value(test_utils::number("0").into())),
}), }),
enforced: None,
}], }],
}); });
@ -5414,6 +5416,7 @@ fn parse_create_domain() {
op: BinaryOperator::Gt, op: BinaryOperator::Gt,
right: Box::new(Expr::Value(test_utils::number("0").into())), right: Box::new(Expr::Value(test_utils::number("0").into())),
}), }),
enforced: None,
}], }],
}); });
@ -5432,6 +5435,7 @@ fn parse_create_domain() {
op: BinaryOperator::Gt, op: BinaryOperator::Gt,
right: Box::new(Expr::Value(test_utils::number("0").into())), right: Box::new(Expr::Value(test_utils::number("0").into())),
}), }),
enforced: None,
}], }],
}); });
@ -5450,6 +5454,7 @@ fn parse_create_domain() {
op: BinaryOperator::Gt, op: BinaryOperator::Gt,
right: Box::new(Expr::Value(test_utils::number("0").into())), right: Box::new(Expr::Value(test_utils::number("0").into())),
}), }),
enforced: None,
}], }],
}); });