From 2a7197f42491e74ba91d1a90a8e283a8181829f3 Mon Sep 17 00:00:00 2001 From: Minjae Lee Date: Wed, 2 Sep 2026 22:38:48 +0900 Subject: [PATCH] Support MySQL CHECK constraint enforcement --- .../create/table/CheckConstraint.java | 18 +++++++++ .../net/sf/jsqlparser/parser/JSqlParserCC.jjt | 8 +++- .../MySQLCreateTableConstraintTest.java | 39 +++++++++++++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 src/test/java/net/sf/jsqlparser/statement/create/MySQLCreateTableConstraintTest.java diff --git a/src/main/java/net/sf/jsqlparser/statement/create/table/CheckConstraint.java b/src/main/java/net/sf/jsqlparser/statement/create/table/CheckConstraint.java index 254fb3d01..79d13b18c 100644 --- a/src/main/java/net/sf/jsqlparser/statement/create/table/CheckConstraint.java +++ b/src/main/java/net/sf/jsqlparser/statement/create/table/CheckConstraint.java @@ -21,6 +21,8 @@ public class CheckConstraint extends NamedConstraint { private Expression expression; + private Boolean enforced; + public Table getTable() { return table; } @@ -37,6 +39,14 @@ public void setExpression(Expression expression) { this.expression = expression; } + public Boolean getEnforced() { + return enforced; + } + + public void setEnforced(Boolean enforced) { + this.enforced = enforced; + } + @Override public String toString() { StringBuilder b = new StringBuilder(); @@ -44,6 +54,9 @@ public String toString() { b.append("CONSTRAINT ").append(getName()).append(" "); } b.append("CHECK (").append(expression).append(")"); + if (enforced != null) { + b.append(enforced ? " ENFORCED" : " NOT ENFORCED"); + } return b.toString(); } @@ -57,6 +70,11 @@ public CheckConstraint withExpression(Expression expression) { return this; } + public CheckConstraint withEnforced(Boolean enforced) { + setEnforced(enforced); + return this; + } + public E getExpression(Class type) { return type.cast(getExpression()); } diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index d52b7a9c2..660f5719e 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -11833,11 +11833,17 @@ void ReferentialActionsOnIndex(ForeignKeyIndex fkIndex): CheckConstraint CheckConstraintSpec(String constraintName): { Expression exp = null; + Boolean enforced = null; } { ( LOOKAHEAD(2) "(" exp = Expression() ")" )* + [ + [ { enforced = false; } ] + { if (enforced == null) { enforced = true; } } + ] { - return new CheckConstraint().withName(constraintName).withExpression(exp); + return new CheckConstraint().withName(constraintName).withExpression(exp) + .withEnforced(enforced); } } diff --git a/src/test/java/net/sf/jsqlparser/statement/create/MySQLCreateTableConstraintTest.java b/src/test/java/net/sf/jsqlparser/statement/create/MySQLCreateTableConstraintTest.java new file mode 100644 index 000000000..dc5b70911 --- /dev/null +++ b/src/test/java/net/sf/jsqlparser/statement/create/MySQLCreateTableConstraintTest.java @@ -0,0 +1,39 @@ +/*- + * #%L + * JSQLParser library + * %% + * Copyright (C) 2004 - 2026 JSQLParser + * %% + * Dual licensed under GNU LGPL 2.1 or Apache License 2.0 + * #L% + */ +package net.sf.jsqlparser.statement.create; + +import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import net.sf.jsqlparser.JSQLParserException; +import net.sf.jsqlparser.statement.create.table.CheckConstraint; +import net.sf.jsqlparser.statement.create.table.CreateTable; +import org.junit.jupiter.api.Test; + +/** MySQL {@code CREATE TABLE} constraint syntax verified against MySQL 8.4.11. */ +public class MySQLCreateTableConstraintTest { + + @Test + public void testCheckConstraintEnforcement() throws JSQLParserException { + String sql = "CREATE TABLE mysql_check_enforcement (score INT, " + + "CONSTRAINT chk_positive CHECK (score >= 0) ENFORCED, " + + "CONSTRAINT chk_cap CHECK (score < 100) NOT ENFORCED)"; + + CreateTable createTable = (CreateTable) assertSqlCanBeParsedAndDeparsed(sql); + + CheckConstraint positive = (CheckConstraint) createTable.getIndexes().get(0); + assertEquals(Boolean.TRUE, positive.getEnforced()); + assertEquals("chk_positive", positive.getName()); + + CheckConstraint cap = (CheckConstraint) createTable.getIndexes().get(1); + assertEquals(Boolean.FALSE, cap.getEnforced()); + assertEquals("chk_cap", cap.getName()); + } +}