diff --git a/h2/src/docsrc/html/changelog.html b/h2/src/docsrc/html/changelog.html
index c4b9881605..618e13df7b 100644
--- a/h2/src/docsrc/html/changelog.html
+++ b/h2/src/docsrc/html/changelog.html
@@ -21,6 +21,8 @@
Change Log
Next Version (unreleased)
+- Issue #4036: NULLS NOT DISTINCT constraint changed after column dropped
+
- Issue #4033: Wrong array produced when using ARRAY_AGG() on UNNEST(ARRAY[CAST(? AS INT)]) expression
in a PreparedStatement
diff --git a/h2/src/main/org/h2/constraint/ConstraintUnique.java b/h2/src/main/org/h2/constraint/ConstraintUnique.java
index 7ec2ea2ffe..0fa08660cb 100644
--- a/h2/src/main/org/h2/constraint/ConstraintUnique.java
+++ b/h2/src/main/org/h2/constraint/ConstraintUnique.java
@@ -53,8 +53,11 @@ private String getCreateSQLForCopy(Table forTable, String quotedName, boolean in
builder.append(" COMMENT ");
StringUtils.quoteStringSQL(builder, comment);
}
- builder.append(' ').append(getConstraintType().getSqlName()).append('(');
- IndexColumn.writeColumns(builder, columns, DEFAULT_SQL_FLAGS).append(')');
+ builder.append(' ').append(getConstraintType().getSqlName());
+ if (!primaryKey) {
+ nullsDistinct.getSQL(builder.append(' '), DEFAULT_SQL_FLAGS).append(' ');
+ }
+ IndexColumn.writeColumns(builder.append('('), columns, DEFAULT_SQL_FLAGS).append(')');
if (internalIndex && indexOwner && forTable == this.table) {
builder.append(" INDEX ");
index.getSQL(builder, DEFAULT_SQL_FLAGS);
diff --git a/h2/src/test/org/h2/test/scripts/ddl/createTable.sql b/h2/src/test/org/h2/test/scripts/ddl/createTable.sql
index 0e4db7d43e..93004fa045 100644
--- a/h2/src/test/org/h2/test/scripts/ddl/createTable.sql
+++ b/h2/src/test/org/h2/test/scripts/ddl/createTable.sql
@@ -267,5 +267,17 @@ SELECT CONSTRAINT_NAME, NULLS_DISTINCT, INDEX_NAME FROM INFORMATION_SCHEMA.TABLE
> CONSTRAINT_273C NO CONSTRAINT_INDEX_273C
> rows: 4
+ALTER TABLE TEST ADD COLUMN E BIGINT;
+> ok
+
+SELECT CONSTRAINT_NAME, NULLS_DISTINCT, INDEX_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = 'TEST';
+> CONSTRAINT_NAME NULLS_DISTINCT INDEX_NAME
+> --------------- -------------- -----------------------
+> CONSTRAINT_2 YES CONSTRAINT_2_INDEX_D
+> CONSTRAINT_27 YES CONSTRAINT_27_INDEX_D
+> CONSTRAINT_273 YES CONSTRAINT_273_INDEX_D
+> CONSTRAINT_273C NO CONSTRAINT_273C_INDEX_D
+> rows: 4
+
DROP TABLE TEST;
> ok
diff --git a/h2/src/test/org/h2/test/scripts/functions/system/db_object.sql b/h2/src/test/org/h2/test/scripts/functions/system/db_object.sql
index c9aefe2e22..fae11ec345 100644
--- a/h2/src/test/org/h2/test/scripts/functions/system/db_object.sql
+++ b/h2/src/test/org/h2/test/scripts/functions/system/db_object.sql
@@ -234,7 +234,7 @@ SELECT T, ID_A <> ID_B, SQL_A, SQL_B FROM (VALUES
)) T(T, ID_A, ID_B, SQL_A, SQL_B);
> T ID_A <> ID_B SQL_A SQL_B
> ---------- ------------ ------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------
-> CONSTRAINT TRUE ALTER TABLE "PUBLIC"."T_A" ADD CONSTRAINT "PUBLIC"."C_A" UNIQUE("ID") ALTER TABLE "PUBLIC"."T_B" ADD CONSTRAINT "PUBLIC"."C_B" UNIQUE("ID")
+> CONSTRAINT TRUE ALTER TABLE "PUBLIC"."T_A" ADD CONSTRAINT "PUBLIC"."C_A" UNIQUE NULLS DISTINCT ("ID") ALTER TABLE "PUBLIC"."T_B" ADD CONSTRAINT "PUBLIC"."C_B" UNIQUE NULLS DISTINCT ("ID")
> INDEX TRUE CREATE UNIQUE NULLS DISTINCT INDEX "PUBLIC"."I_A" ON "PUBLIC"."T_A"("ID" NULLS FIRST) CREATE UNIQUE NULLS DISTINCT INDEX "PUBLIC"."I_B" ON "PUBLIC"."T_B"("ID" NULLS FIRST)
> SYNONYM TRUE CREATE SYNONYM "PUBLIC"."S_A" FOR "PUBLIC"."T_A" CREATE SYNONYM "PUBLIC"."S_B" FOR "PUBLIC"."T_B"
> TABLE TRUE CREATE MEMORY TABLE "PUBLIC"."T_A"( "ID" INTEGER ) CREATE MEMORY TABLE "PUBLIC"."T_B"( "ID" INTEGER )
diff --git a/h2/src/test/org/h2/test/scripts/testScript.sql b/h2/src/test/org/h2/test/scripts/testScript.sql
index b860d3eaa1..208507f15d 100644
--- a/h2/src/test/org/h2/test/scripts/testScript.sql
+++ b/h2/src/test/org/h2/test/scripts/testScript.sql
@@ -6266,7 +6266,7 @@ SCRIPT NOPASSWORDS NOSETTINGS NOVERSION;
> CREATE USER IF NOT EXISTS "SA" PASSWORD '' ADMIN;
> CREATE MEMORY TABLE "PUBLIC"."TEST"( "A_INT" INTEGER NOT NULL, "B_INT" INTEGER NOT NULL );
> -- 0 +/- SELECT COUNT(*) FROM PUBLIC.TEST;
-> ALTER TABLE "PUBLIC"."TEST" ADD CONSTRAINT "PUBLIC"."U_B" UNIQUE("B_INT");
+> ALTER TABLE "PUBLIC"."TEST" ADD CONSTRAINT "PUBLIC"."U_B" UNIQUE NULLS DISTINCT ("B_INT");
> ALTER TABLE "PUBLIC"."TEST" ADD CONSTRAINT "PUBLIC"."C1" FOREIGN KEY("A_INT") REFERENCES "PUBLIC"."TEST"("B_INT") NOCHECK;
> rows (ordered): 5
@@ -6418,9 +6418,9 @@ SCRIPT NOPASSWORDS NOSETTINGS NOVERSION;
> INSERT INTO "PUBLIC"."B_TEST" VALUES (-1, 'XX');
> ALTER TABLE "PUBLIC"."A_TEST" ADD CONSTRAINT "PUBLIC"."MIN_LENGTH" CHECK(CHAR_LENGTH("A_VARCHAR") > 1) NOCHECK;
> ALTER TABLE "PUBLIC"."B_TEST" ADD CONSTRAINT "PUBLIC"."CONSTRAINT_76" CHECK(CHAR_LENGTH("B_VARCHAR") > 1) NOCHECK;
-> ALTER TABLE "PUBLIC"."A_TEST" ADD CONSTRAINT "PUBLIC"."DATE_UNIQUE" UNIQUE("A_DATE");
-> ALTER TABLE "PUBLIC"."A_TEST" ADD CONSTRAINT "PUBLIC"."DATE_UNIQUE_2" UNIQUE("A_DATE");
-> ALTER TABLE "PUBLIC"."B_TEST" ADD CONSTRAINT "PUBLIC"."B_UNIQUE" UNIQUE("B_INT");
+> ALTER TABLE "PUBLIC"."A_TEST" ADD CONSTRAINT "PUBLIC"."DATE_UNIQUE" UNIQUE NULLS DISTINCT ("A_DATE");
+> ALTER TABLE "PUBLIC"."A_TEST" ADD CONSTRAINT "PUBLIC"."DATE_UNIQUE_2" UNIQUE NULLS DISTINCT ("A_DATE");
+> ALTER TABLE "PUBLIC"."B_TEST" ADD CONSTRAINT "PUBLIC"."B_UNIQUE" UNIQUE NULLS DISTINCT ("B_INT");
> ALTER TABLE "PUBLIC"."B_TEST" ADD CONSTRAINT "PUBLIC"."C3" FOREIGN KEY("B_INT") REFERENCES "PUBLIC"."A_TEST"("A_INT") ON DELETE SET DEFAULT ON UPDATE SET DEFAULT NOCHECK;
> rows (ordered): 14
@@ -6521,8 +6521,8 @@ SCRIPT SIMPLE NOPASSWORDS NOSETTINGS NOVERSION;
> INSERT INTO "PUBLIC"."CHILD" VALUES(101, 3, 1, 'Sabine');
> INSERT INTO "PUBLIC"."CHILD" VALUES(200, NULL, NULL, 'Jim');
> INSERT INTO "PUBLIC"."CHILD" VALUES(201, NULL, NULL, 'Johann');
-> ALTER TABLE "PUBLIC"."CHILD" ADD CONSTRAINT "PUBLIC"."CONSTRAINT_3" UNIQUE("ID", "PARENTID");
-> ALTER TABLE "PUBLIC"."PARENT" ADD CONSTRAINT "PUBLIC"."CONSTRAINT_8" UNIQUE("ID", "FAMILY_ID");
+> ALTER TABLE "PUBLIC"."CHILD" ADD CONSTRAINT "PUBLIC"."CONSTRAINT_3" UNIQUE NULLS DISTINCT ("ID", "PARENTID");
+> ALTER TABLE "PUBLIC"."PARENT" ADD CONSTRAINT "PUBLIC"."CONSTRAINT_8" UNIQUE NULLS DISTINCT ("ID", "FAMILY_ID");
> ALTER TABLE "PUBLIC"."CHILD" ADD CONSTRAINT "PUBLIC"."PARENT_CHILD" FOREIGN KEY("PARENTID", "FAMILY_ID") REFERENCES "PUBLIC"."PARENT"("ID", "FAMILY_ID") ON DELETE SET NULL ON UPDATE CASCADE NOCHECK;
> ALTER TABLE "PUBLIC"."PARENT" ADD CONSTRAINT "PUBLIC"."PARENT_FAMILY" FOREIGN KEY("FAMILY_ID") REFERENCES "PUBLIC"."FAMILY"("ID") NOCHECK;
> rows (ordered): 19
@@ -6548,8 +6548,8 @@ SCRIPT SIMPLE NOPASSWORDS NOSETTINGS NOVERSION;
> INSERT INTO "PUBLIC"."CHILD" VALUES(101, 3, 1, 'Sabine');
> INSERT INTO "PUBLIC"."CHILD" VALUES(200, NULL, NULL, 'Jim');
> INSERT INTO "PUBLIC"."CHILD" VALUES(201, NULL, NULL, 'Johann');
-> ALTER TABLE "PUBLIC"."CHILD" ADD CONSTRAINT "PUBLIC"."CONSTRAINT_3" UNIQUE("ID", "PARENTID");
-> ALTER TABLE "PUBLIC"."PARENT" ADD CONSTRAINT "PUBLIC"."CONSTRAINT_8" UNIQUE("ID", "FAMILY_ID");
+> ALTER TABLE "PUBLIC"."CHILD" ADD CONSTRAINT "PUBLIC"."CONSTRAINT_3" UNIQUE NULLS DISTINCT ("ID", "PARENTID");
+> ALTER TABLE "PUBLIC"."PARENT" ADD CONSTRAINT "PUBLIC"."CONSTRAINT_8" UNIQUE NULLS DISTINCT ("ID", "FAMILY_ID");
> ALTER TABLE "PUBLIC"."PARENT" ADD CONSTRAINT "PUBLIC"."PARENT_FAMILY" FOREIGN KEY("FAMILY_ID") REFERENCES "PUBLIC"."FAMILY"("ID") NOCHECK;
> rows (ordered): 18