Skip to content

Fix ALTER TABLE ... DROP CONSTRAINT for UNIQUE constraints#2359

Closed
nick-inkeep wants to merge 1 commit intodolthub:mainfrom
nick-inkeep:fix/drop-unique-constraint
Closed

Fix ALTER TABLE ... DROP CONSTRAINT for UNIQUE constraints#2359
nick-inkeep wants to merge 1 commit intodolthub:mainfrom
nick-inkeep:fix/drop-unique-constraint

Conversation

@nick-inkeep
Copy link
Copy Markdown

Summary

ALTER TABLE ... DROP CONSTRAINT "name" fails with Constraint "name" does not exist when the constraint is a UNIQUE constraint. This affects both inline (CREATE TABLE ... UNIQUE(...)) and ALTER-added (ALTER TABLE ADD CONSTRAINT ... UNIQUE(...)) UNIQUE constraints.

DROP CONSTRAINT works correctly for CHECK, FOREIGN KEY, and PRIMARY KEY. Only UNIQUE is broken.

Impact: Blocks any ORM/migration tool (Drizzle, Prisma, Knex) that generates standard PostgreSQL DROP CONSTRAINT for UNIQUE constraint changes.

Root cause

The existing convertDropPrimaryKeyConstraint analyzer rule intercepts plan.DropConstraint and converts PK drops to plan.AlterDropPk. No equivalent rule exists for UNIQUE constraints. GMS's default DropConstraint handler checks GetChecks() and GetDeclaredForeignKeys() but never calls GetIndexes(), so UNIQUE constraints (stored as sql.Index with IsUnique()=true) are never found.

Fix

Added convertDropUniqueConstraint analyzer rule mirroring the PK handler:

  • Intercepts plan.DropConstraint nodes
  • Looks up indexes via sql.IndexAddressableTable.GetIndexes()
  • If a matching unique (non-PK) index is found, converts to plan.NewAlterDropIndex
  • Handles IF EXISTS correctly

Files changed

  • New: server/analyzer/convert_drop_unique_constraint.go
  • Modified: server/analyzer/init.go (rule ID + registration)
  • Modified: testing/go/alter_table_test.go (5 new test cases)

Test coverage

  • Drop unique constraint added via ALTER TABLE
  • Drop unique constraint defined inline in CREATE TABLE
  • Drop unique constraint with IF EXISTS
  • Drop unique constraint on single column
  • Drop and re-add unique constraint with different columns

Reproduction

CREATE TABLE t1 (pk int PRIMARY KEY, c1 int, c2 int);
ALTER TABLE t1 ADD CONSTRAINT uniq_c1c2 UNIQUE (c1, c2);

-- Verify constraint exists:
SELECT conname, contype FROM pg_constraint WHERE conrelid = 't1'::regclass;
--  conname   | contype
-- -----------+---------
--  t1_pkey   | p
--  uniq_c1c2 | u

-- Before fix: ERROR: Constraint "uniq_c1c2" does not exist
-- After fix: ALTER TABLE (succeeds)
ALTER TABLE t1 DROP CONSTRAINT uniq_c1c2;

Add convertDropUniqueConstraint analyzer rule that intercepts
plan.DropConstraint nodes for UNIQUE constraints and converts them
to plan.NewAlterDropIndex nodes so GMS can process the index drop.

Previously, DROP CONSTRAINT only handled CHECK, FOREIGN KEY, and
PRIMARY KEY constraints. UNIQUE constraints were missed because GMS's
default DropConstraint handler checks GetChecks() and
GetDeclaredForeignKeys() but never calls GetIndexes().
@nick-inkeep nick-inkeep force-pushed the fix/drop-unique-constraint branch from 75bd0c1 to 4f0b27b Compare February 20, 2026 08:42
@fulghum
Copy link
Copy Markdown
Contributor

fulghum commented Feb 20, 2026

Thank you for this excellent write up! I've repro'ed the issue and am working through the code in the debugger. This looks to also be an issue with Dolt, where Dolt has a similar behavior that does not match MySQL's behavior. Based on that, I'm going to keep digging in deeper and I suspect there is a fix in GMS that will make this work for both Doltgres and Dolt.

Thank you for finding and reporting this one!

@fulghum
Copy link
Copy Markdown
Contributor

fulghum commented Feb 21, 2026

Thank you for reporting this one! 🙏 Your description and repro case were a big help for me to make progress on this one quickly. I noticed Dolt wasn't able to execute this statement correctly either and made a fix in GMS here: dolthub/go-mysql-server#3441

I've got that fix merged into Dolt and I'm waiting on one last CI job to complete before Doltgres is updated. After that I'll kick off a release for Doltgres version 0.55.4.

Since we made another fix in GMS for this issue, I'll go ahead and close out this PR. Let us know if you come across any other problems and we'll be happy to fix them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants