From d0dc632433addaf344dd0bb4623e4d04b57e8b4e Mon Sep 17 00:00:00 2001 From: Yan Yan Date: Tue, 28 Apr 2026 22:10:40 +0000 Subject: [PATCH 1/2] [SPARK-XXXXX][SQL] Always emit RELY/NORELY in DESCRIBE EXTENDED constraint output ### What changes were proposed in this pull request? `BaseConstraint.toDescription()` now always emits `RELY|NORELY`, matching `toDDL()` used by SHOW CREATE TABLE. Previously, `toDescription()` skipped the `NORELY` token when `rely=false`, so the same constraint rendered differently across the two surfaces. After this change, the invariant holds: `toDDL` is `"CONSTRAINT " + name + " " + toDescription`. ### Why are the changes needed? After SPARK-52141 (DESCRIBE EXTENDED) and SPARK-52142 (SHOW CREATE TABLE) landed, the two surfaces render the same constraint asymmetrically: | State | DESCRIBE EXTENDED (before) | SHOW CREATE TABLE | |--------------|-----------------------------------|-------------------------------------| | PK default | PRIMARY KEY (a) NOT ENFORCED | PRIMARY KEY (a) NOT ENFORCED NORELY | | CHECK default| CHECK (...) ENFORCED | CHECK (...) ENFORCED NORELY | The original review on PR #51577 considered skipping both `NOT ENFORCED` and `NORELY` when default, but only `NORELY` was skipped because `ENFORCED`'s default is per-subclass and not visible to `BaseConstraint`. The result is a confusing experience: SHOW CREATE TABLE reports the rely state explicitly while DESCRIBE EXTENDED hides it for the default value. ### Does this PR introduce any user-facing change? Yes. DESCRIBE EXTENDED now emits `NORELY` for constraints whose `rely` value is the default. PRIMARY KEY / UNIQUE / FOREIGN KEY / CHECK constraints all show the full `ENFORCED|NOT ENFORCED RELY|NORELY` suffix, matching SHOW CREATE TABLE. ### How was this patch tested? Updated golden strings in the v2 `DescribeTableSuite` "desc table constraints" test. Ran: build/sbt 'sql/testOnly \ org.apache.spark.sql.execution.command.v2.DescribeTableSuite \ org.apache.spark.sql.execution.command.v2.ShowCreateTableSuite' 41 tests pass. ### Was this patch authored or co-authored using generative AI tooling? No. --- .../catalog/constraints/BaseConstraint.java | 12 +++++------- .../execution/command/v2/DescribeTableSuite.scala | 15 +++++++-------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/sql/catalyst/src/main/java/org/apache/spark/sql/connector/catalog/constraints/BaseConstraint.java b/sql/catalyst/src/main/java/org/apache/spark/sql/connector/catalog/constraints/BaseConstraint.java index f93d716a27842..1e718ad106b3a 100644 --- a/sql/catalyst/src/main/java/org/apache/spark/sql/connector/catalog/constraints/BaseConstraint.java +++ b/sql/catalyst/src/main/java/org/apache/spark/sql/connector/catalog/constraints/BaseConstraint.java @@ -74,13 +74,11 @@ public String toDDL() { } public String toDescription() { - StringJoiner joiner = new StringJoiner(" "); - joiner.add(definition()); - joiner.add(enforced ? "ENFORCED" : "NOT ENFORCED"); - if (rely) { - joiner.add("RELY"); - } - return joiner.toString(); + return String.format( + "%s %s %s", + definition(), + enforced ? "ENFORCED" : "NOT ENFORCED", + rely ? "RELY" : "NORELY"); } @Override diff --git a/sql/core/src/test/scala/org/apache/spark/sql/execution/command/v2/DescribeTableSuite.scala b/sql/core/src/test/scala/org/apache/spark/sql/execution/command/v2/DescribeTableSuite.scala index 1bd6df5cf928a..c3f055cc33224 100644 --- a/sql/core/src/test/scala/org/apache/spark/sql/execution/command/v2/DescribeTableSuite.scala +++ b/sql/core/src/test/scala/org/apache/spark/sql/execution/command/v2/DescribeTableSuite.scala @@ -360,21 +360,20 @@ class DescribeTableSuite extends command.DescribeTableSuiteBase |$defaultUsing """.stripMargin) - // Skipped showing NORELY since it is the default value. + // ENFORCED/NOT ENFORCED and RELY/NORELY are always emitted to match SHOW CREATE TABLE. var expectedConstraintsDdl = Array( "# Constraints,,", - "pk_table_pk,PRIMARY KEY (id) NOT ENFORCED,", + "pk_table_pk,PRIMARY KEY (id) NOT ENFORCED NORELY,", s"fk_a,FOREIGN KEY (a) REFERENCES $fkTable (id) NOT ENFORCED RELY,", - "uk_b,UNIQUE (b) NOT ENFORCED,", - "uk_a_c,UNIQUE (a, c) NOT ENFORCED,", - "c1,CHECK (c IS NOT NULL) ENFORCED,", - "c2,CHECK (id > 0) ENFORCED," + "uk_b,UNIQUE (b) NOT ENFORCED NORELY,", + "uk_a_c,UNIQUE (a, c) NOT ENFORCED NORELY,", + "c1,CHECK (c IS NOT NULL) ENFORCED NORELY,", + "c2,CHECK (id > 0) ENFORCED NORELY," ) var descDdL = sql(s"DESCRIBE EXTENDED $tbl").collect().map(_.mkString(",")) .dropWhile(_ != "# Constraints,,") assert(descDdL === expectedConstraintsDdl) - // Show non-default value for RELY. sql(s"ALTER TABLE $tbl ADD CONSTRAINT c3 CHECK (b IS NOT NULL) RELY") descDdL = sql(s"DESCRIBE EXTENDED $tbl").collect().map(_.mkString(",")) .dropWhile(_ != "# Constraints,,") @@ -386,7 +385,7 @@ class DescribeTableSuite extends command.DescribeTableSuiteBase descDdL = sql(s"DESCRIBE EXTENDED $tbl").collect().map(_.mkString(",")) .dropWhile(_ != "# Constraints,,") assert(descDdL === expectedConstraintsDdl - .filter(_ != "c1,CHECK (c IS NOT NULL) ENFORCED,")) + .filter(_ != "c1,CHECK (c IS NOT NULL) ENFORCED NORELY,")) } } } From 1e3e911252b2c89b0eaaa968a6c8a67ef26af4d3 Mon Sep 17 00:00:00 2001 From: Yan Yan Date: Wed, 29 Apr 2026 00:29:21 +0000 Subject: [PATCH 2/2] Address review: simplify toDDL to delegate to toDescription Per Gengliang's review on PR #55590, encode the invariant `toDDL == "CONSTRAINT " + name + " " + toDescription` structurally so the two methods can't drift apart. Removes the duplicated String.format template in toDDL. Behavior is unchanged; existing golden strings in ConstraintSuite, v2/ShowCreateTableSuite, and v2/DescribeTableSuite still hold. --- .../sql/connector/catalog/constraints/BaseConstraint.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/sql/catalyst/src/main/java/org/apache/spark/sql/connector/catalog/constraints/BaseConstraint.java b/sql/catalyst/src/main/java/org/apache/spark/sql/connector/catalog/constraints/BaseConstraint.java index 1e718ad106b3a..186d2b5dedade 100644 --- a/sql/catalyst/src/main/java/org/apache/spark/sql/connector/catalog/constraints/BaseConstraint.java +++ b/sql/catalyst/src/main/java/org/apache/spark/sql/connector/catalog/constraints/BaseConstraint.java @@ -65,12 +65,7 @@ public boolean rely() { public String toDDL() { // The validation status is not included in the DDL output as it's not part of // the Spark SQL syntax for constraints. - return String.format( - "CONSTRAINT %s %s %s %s", - name, - definition(), - enforced ? "ENFORCED" : "NOT ENFORCED", - rely ? "RELY" : "NORELY"); + return "CONSTRAINT " + name + " " + toDescription(); } public String toDescription() {