Skip to content

Commit

Permalink
Merge pull request #4037 from katzyn/nulls
Browse files Browse the repository at this point in the history
Fix SQL export of constraints with custom UNIQUE null treatment
  • Loading branch information
katzyn committed Apr 7, 2024
2 parents 23bf50d + 2e1c1ab commit 49104cf
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 11 deletions.
2 changes: 2 additions & 0 deletions h2/src/docsrc/html/changelog.html
Expand Up @@ -21,6 +21,8 @@ <h1>Change Log</h1>

<h2>Next Version (unreleased)</h2>
<ul>
<li>Issue #4036: NULLS NOT DISTINCT constraint changed after column dropped
</li>
<li>Issue #4033: Wrong array produced when using ARRAY_AGG() on UNNEST(ARRAY[CAST(? AS INT)]) expression
in a PreparedStatement
</li>
Expand Down
7 changes: 5 additions & 2 deletions h2/src/main/org/h2/constraint/ConstraintUnique.java
Expand Up @@ -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);
Expand Down
12 changes: 12 additions & 0 deletions h2/src/test/org/h2/test/scripts/ddl/createTable.sql
Expand Up @@ -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
Expand Up @@ -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 )
Expand Down
16 changes: 8 additions & 8 deletions h2/src/test/org/h2/test/scripts/testScript.sql
Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand All @@ -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

Expand Down

0 comments on commit 49104cf

Please sign in to comment.