MySQL has issues joining on IDs with variation in capitalization
See original GitHub issueBug description
I have a set of IDs that should be treated without case sensitivity, as the default behavior for MySQL works. However, I have issues joining items which vary in capitalization.
How to reproduce
Full reproduction:
Initialization
- Check out my example repo on this branch
- Navigate to typescript/script
yarn install
- Install a
.env
file with aDB_URL
variable which points to a working MySQL database yarn run prisma db push
yarn run prisma db seed
Joining from varied case FKs to case insensitive PKs
yarn run items
- Expect that both
Item
s withID
andid
values forotherItemId
map to the sameOtherItem
with the PK ofID
. - Observe that only the exact match correctly joins.
- Observe that the raw sql
SELECT * FROM Item INNER JOIN OtherItem ON Item.otherItemId = OtherItem.id
exhibits the correct behavior of joining both rows.
Joining from case insensitive PKs to varied case FKs
yarn run otherItems
- Observe the client panic
Expected behavior
MySQL is case insensitive by default and should therefore join on IDs with varying capitalization.
Prisma information
This is also included in the repro commit described above, with the diff here.
Schema
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DB_URL")
}
model Item {
id Int @default(autoincrement()) @id
otherItemId String
otherItem OtherItem? @relation(fields: [otherItemId], references: [id])
@@index([otherItemId])
}
model OtherItem {
id String @id
item Item[]
}
Seed
await prisma.otherItem.createMany({
data: [
{id: 'ID', value: Math.random()}
]
})
await prisma.item.createMany({
data: [
/**
* Correctly has relationship with its associated Item
*/
{otherItemId: 'ID'},
/**
* Does not have an associated Item.
*/
{otherItemId: 'id'}
]
});
Item query
/**
* Only the case sensitive ID match joins with the OtherItem table. The other is null.
*/
const items = await prisma.item.findMany({
include: {
otherItem: true
}
});
/**
* Querying raw correctly joins both items.
*/
const rawResult = await prisma.$queryRaw`SELECT * FROM Item INNER JOIN OtherItem ON Item.otherItemId = OtherItem.id`;
OtherItem query
// Causes a client panic
const otherItems = await prisma.otherItem.findMany({
include: {
item: true
}
})
Environment & setup
- OS: OSX 11.6
- Database: MySQL 8.0.27
- Node.js version: v16.13.0
Prisma Version
prisma : 3.7.0 @prisma/client : 3.7.0 Current platform : darwin Query Engine (Node-API) : libquery-engine 8746e055198f517658c08a0c426c7eec87f5a85f (at node_modules/@prisma/engines/libquery_engine-darwin.dylib.node) Migration Engine : migration-engine-cli 8746e055198f517658c08a0c426c7eec87f5a85f (at node_modules/@prisma/engines/migration-engine-darwin) Introspection Engine : introspection-core 8746e055198f517658c08a0c426c7eec87f5a85f (at node_modules/@prisma/engines/introspection-engine-darwin) Format Binary : prisma-fmt 8746e055198f517658c08a0c426c7eec87f5a85f (at node_modules/@prisma/engines/prisma-fmt-darwin) Default Engines Hash : 8746e055198f517658c08a0c426c7eec87f5a85f Studio : 0.445.0
Issue Analytics
- State:
- Created 2 years ago
- Comments:5 (4 by maintainers)
Top GitHub Comments
Yes. This doc describes collation types.
utf8mb4_unicode_ci
is the collation type which Prisma created all my tables with by default.utf8mb4_unicode_ci
is a case insensitive collation type, which is denoted by theci
at the end of the name.Doesn’t matter which collation is in use, SQL Server and MySQL can join with a case-insensitive strings, and with strings with whitespace in the both ends on one of the sides, but missing from the other. Reproduction:
debug logs