{"id":"3adbcb2269db79f5","repo":"typeorm/typeorm","slug":"mysql-does-not-support-exclusion-constraints-3adbcb","errorCode":null,"errorMessage":"MySql does not support exclusion constraints.","messagePattern":"MySql does not support exclusion constraints\\.","errorType":"exception","errorClass":"TypeORMError","httpStatus":null,"severity":"error","filePath":"src/driver/mysql/MysqlQueryRunner.ts","lineNumber":2225,"sourceCode":"    async dropCheckConstraints(\n        tableOrName: Table | string,\n        checkConstraints: TableCheck[],\n        ifExists?: boolean,\n    ): Promise<void> {\n        throw new TypeORMError(`MySql does not support check constraints.`)\n    }\n\n    /**\n     * Creates a new exclusion constraint.\n     *\n     * @param tableOrName\n     * @param exclusionConstraint\n     */\n    async createExclusionConstraint(\n        tableOrName: Table | string,\n        exclusionConstraint: TableExclusion,\n    ): Promise<void> {\n        throw new TypeORMError(`MySql does not support exclusion constraints.`)\n    }\n\n    /**\n     * Creates a new exclusion constraints.\n     *\n     * @param tableOrName\n     * @param exclusionConstraints\n     */\n    async createExclusionConstraints(\n        tableOrName: Table | string,\n        exclusionConstraints: TableExclusion[],\n    ): Promise<void> {\n        throw new TypeORMError(`MySql does not support exclusion constraints.`)\n    }\n\n    /**\n     * Drops exclusion constraint.\n     *","sourceCodeStart":2207,"sourceCodeEnd":2243,"githubUrl":"https://github.com/typeorm/typeorm/blob/04ff4daedcf60fa4ffd0d5d33bbafaac1a9bbc96/src/driver/mysql/MysqlQueryRunner.ts#L2207-L2243","documentation":"createExclusionConstraint() throws on MySQL because exclusion constraints are a PostgreSQL-specific feature (e.g., EXCLUDE USING GIST) with no MySQL equivalent. The method exists only to satisfy the shared QueryRunner interface.","triggerScenarios":"Calling queryRunner.createExclusionConstraint(table, exclusion) on MySQL; reusing Postgres exclusion logic (e.g., preventing overlapping time ranges) on a MySQL backend.","commonSituations":"Booking/scheduling apps that used EXCLUDE on Postgres being ported to MySQL; shared multi-DB schema code.","solutions":["Enforce the exclusion rule with a trigger that checks for overlapping rows, or in the application layer with locking.","Keep the constraint on Postgres only by branching on driver type.","Use a generated column + unique index as a partial workaround for simple ranges."],"exampleFix":"// before\nawait queryRunner.createExclusionConstraint('bookings', new TableExclusion({ name: 'no_overlap', expression: 'USING GIST (room_id WITH =, tstzrange(starts_at, ends_at) WITH &&)' }));\n\n// after (MySQL trigger-based overlap guard)\nawait queryRunner.query(`CREATE TRIGGER no_overlap_ins BEFORE INSERT ON bookings FOR EACH ROW BEGIN IF EXISTS (SELECT 1 FROM bookings b WHERE b.room_id = NEW.room_id AND NEW.starts_at < b.ends_at AND b.starts_at < NEW.ends_at) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='overlapping booking'; END IF; END`);","handlingStrategy":"validation","validationCode":"import type { QueryRunner } from 'typeorm';\n// Enforce an exclusion (e.g. no overlapping bookings) via a trigger:\nasync function createNoOverlap(runner: QueryRunner) {\n  await runner.query(`CREATE TRIGGER no_overlap_ins BEFORE INSERT ON bookings FOR EACH ROW BEGIN IF EXISTS (SELECT 1 FROM bookings b WHERE b.room_id = NEW.room_id AND NEW.starts_at < b.ends_at AND b.starts_at < NEW.ends_at) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='overlapping booking'; END IF; END`);\n}","typeGuard":"import { InstanceChecker } from 'typeorm';\nconst isTableExclusion = (v: unknown) => InstanceChecker.isTableExclusion(v);","tryCatchPattern":"null","preventionTips":["Treat exclusion constraints as Postgres-only; design MySQL equivalents as triggers or app-level locks.","Document the driver-specific enforcement in the schema docs.","Add concurrency tests for the overlap guard."],"tags":["mysql","exclusion-constraint","driver-capability","postgresql","trigger","typeorm"],"analyzedSha":"04ff4daedcf60fa4ffd0d5d33bbafaac1a9bbc96","analyzedAt":"2026-08-03T18:27:32.281Z","schemaVersion":2}