From 5e8af395633092b9f512d955a99ee1484f2b68cf Mon Sep 17 00:00:00 2001 From: Jared Vititoe Date: Tue, 8 Sep 2026 11:43:53 -0400 Subject: [PATCH] Fix collation inconsistency on saved_filters/ticket_attachments (#41) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit README Dev Note #12 mandates utf8mb4_general_ci for new tables, but these two tables were created with utf8mb4_unicode_ci in the baseline schema — inconsistent with every other table, and a future join or comparison against a general_ci column would need explicit COLLATE casts or hit "Illegal mix of collations" errors. - Fixed 000_baseline.sql so a fresh install matches the convention directly. - Added 002_fix_collation_consistency.sql for existing deployments. MariaDB silently drops the inline CHECK (json_valid(...)) constraint on saved_filters.filter_criteria when that column is MODIFYed (found by actually running this against a local MariaDB instance), so the migration explicitly re-adds it after the collation conversion. Verified against a local MariaDB 10.11: baseline applies cleanly, migration is idempotent (safe to run twice), and the json_valid CHECK is still enforced afterward. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01MGDKHiU5RJdo3dqQUDow3X --- migrations/000_baseline.sql | 4 +-- migrations/002_fix_collation_consistency.sql | 30 ++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 migrations/002_fix_collation_consistency.sql diff --git a/migrations/000_baseline.sql b/migrations/000_baseline.sql index dc7ddc8..3eeee7d 100644 --- a/migrations/000_baseline.sql +++ b/migrations/000_baseline.sql @@ -155,7 +155,7 @@ CREATE TABLE IF NOT EXISTS `saved_filters` ( UNIQUE KEY `unique_user_filter_name` (`user_id`,`filter_name`), KEY `idx_user_filters` (`user_id`,`is_default`), CONSTRAINT `saved_filters_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; -- ============ status_transitions ============ CREATE TABLE IF NOT EXISTS `status_transitions` ( @@ -185,7 +185,7 @@ CREATE TABLE IF NOT EXISTS `ticket_attachments` ( KEY `idx_attachments_ticket` (`ticket_id`), KEY `idx_attachments_uploaded_by` (`uploaded_by`), CONSTRAINT `ticket_attachments_ibfk_1` FOREIGN KEY (`uploaded_by`) REFERENCES `users` (`user_id`) ON DELETE SET NULL -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; -- ============ ticket_comments ============ CREATE TABLE IF NOT EXISTS `ticket_comments` ( diff --git a/migrations/002_fix_collation_consistency.sql b/migrations/002_fix_collation_consistency.sql new file mode 100644 index 0000000..5f366ec --- /dev/null +++ b/migrations/002_fix_collation_consistency.sql @@ -0,0 +1,30 @@ +-- Fix collation inconsistency on saved_filters and ticket_attachments +-- +-- README.md Developer Notes #12: "Database collation: Use +-- utf8mb4_general_ci (not unicode_ci) for new tables." These two tables +-- were created with utf8mb4_unicode_ci instead, inconsistent with every +-- other table in the schema. Mixed collations don't break anything by +-- themselves, but any future query joining/comparing these columns +-- against general_ci columns needs explicit COLLATE casts or hits +-- "Illegal mix of collations" errors. +-- +-- Safe to re-run. + +ALTER TABLE `saved_filters` + CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; + +-- saved_filters.filter_criteria is pinned to utf8mb4_bin (for the +-- json_valid() CHECK constraint) — restore that after the table-wide +-- CONVERT TO above, which resets it to general_ci. MariaDB drops the +-- inline CHECK when the column is MODIFYed, so re-add it explicitly. +ALTER TABLE `saved_filters` + MODIFY COLUMN `filter_criteria` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL; + +ALTER TABLE `saved_filters` + DROP CONSTRAINT IF EXISTS `saved_filters_filter_criteria_json`; + +ALTER TABLE `saved_filters` + ADD CONSTRAINT `saved_filters_filter_criteria_json` CHECK (json_valid(`filter_criteria`)); + +ALTER TABLE `ticket_attachments` + CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;