Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix SQL export of constraints with custom UNIQUE null treatment #4037

Merged
merged 1 commit into from Apr 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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