-- PlannedTab: match customers case-insensitively ALTER TABLE "PlannedTab" ADD COLUMN "customerNameKey" TEXT; UPDATE "PlannedTab" SET "customerNameKey" = lower(trim(regexp_replace("customerName", '\s+', ' ', 'g'))); -- Names that only differ in case or spacing keep the oldest row as the match; later ones get a unique key UPDATE "PlannedTab" p SET "customerNameKey" = p."customerNameKey" || '#' || p."id" WHERE EXISTS ( SELECT 1 FROM "PlannedTab" o WHERE o."venueId" = p."venueId" AND o."customerNameKey" = p."customerNameKey" AND (o."createdAt", o."id") < (p."createdAt", p."id") ); ALTER TABLE "PlannedTab" ALTER COLUMN "customerNameKey" SET NOT NULL; DROP INDEX "PlannedTab_venueId_customerName_key"; CREATE UNIQUE INDEX "PlannedTab_venueId_customerNameKey_key" ON "PlannedTab"("venueId", "customerNameKey"); -- RemoteCommand: keep who the tab belonged to, the tab itself disappears once closed ALTER TABLE "RemoteCommand" ADD COLUMN "customerName" TEXT, ADD COLUMN "amountInCents" INTEGER; UPDATE "RemoteCommand" c SET "customerName" = s."customerName", "amountInCents" = s."totalInCents" FROM "OpenTabSnapshot" s WHERE s."deviceId" = c."deviceId" AND s."tabId" = c."targetTabId";