-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Compound cursor with DateTime field returns 0 rows via driver adapter (@prisma/adapter-mariadb) #29309
Description
Bug description
When using @prisma/adapter-mariadb, a findMany with a compound cursor (@@id) containing a DateTime field returns 0 rows. The equivalent WHERE-based query returns correct results. The cursor subquery reaches the database but the DateTime comparison silently fails.
Severity
Reproduction
Minimal repro repo: https://github.com/aviraccoon/prisma-datetime-cursor-bug
git clone https://github.com/aviraccoon/prisma-datetime-cursor-bug
cd prisma-datetime-cursor-bug
bun install
bunx prisma generate
bunx prisma db push --url "mysql://root@127.0.0.1:3306/cursor_repro"
bun repro.tsUpdate the connection details in repro.ts and the --url flag for your MySQL instance.
Minimal repro:
Schema:
generator client {
provider = "prisma-client-js"
previewFeatures = ["driverAdapters"]
}
datasource db {
provider = "mysql"
}
model Event {
appId Int
createdAt DateTime @db.Date
value Int
@@id([appId, createdAt])
}Repro script:
import { PrismaMariaDb } from "@prisma/adapter-mariadb";
import { PrismaClient } from "@prisma/client";
const adapter = new PrismaMariaDb({
host: "127.0.0.1",
port: 3306,
user: "root",
password: "",
database: "cursor_repro",
connectionLimit: 2,
});
const prisma = new PrismaClient({ adapter });
async function main() {
await prisma.event.deleteMany();
const rows = [];
for (let day = 1; day <= 10; day++) {
rows.push({
appId: 1,
createdAt: new Date(`2025-01-${String(day).padStart(2, "0")}`),
value: day * 100,
});
}
await prisma.event.createMany({ data: rows });
const firstThree = await prisma.event.findMany({
where: { appId: 1 },
orderBy: { createdAt: "asc" },
take: 3,
});
const cursorRow = firstThree[2]; // 2025-01-03
// BUG: returns 0 rows
const withCursor = await prisma.event.findMany({
where: { appId: 1 },
cursor: {
appId_createdAt: {
appId: cursorRow.appId,
createdAt: cursorRow.createdAt,
},
},
orderBy: { createdAt: "asc" },
take: 3,
skip: 1,
});
console.log(`Cursor: ${withCursor.length} rows (expected: 3)`);
// WORKS: equivalent WHERE-based query
const withWhere = await prisma.event.findMany({
where: { appId: 1, createdAt: { gt: cursorRow.createdAt } },
orderBy: { createdAt: "asc" },
take: 3,
});
console.log(`WHERE: ${withWhere.length} rows (expected: 3)`);
await prisma.$disconnect();
}
main().catch(console.error);Expected vs. Actual Behavior
Expected: Both queries return 3 rows (Jan 4, 5, 6).
Actual: The cursor query returns 0 rows. The WHERE query returns 3 rows correctly.
Frequency
Consistently reproducible.
Does this occur in development or production?
Both development and production.
Is this a regression?
Likely — we did not encounter this in Prisma 6.
Workaround
Convert the compound cursor to an equivalent WHERE condition:
// Instead of:
cursor: { appId_createdAt: { appId, createdAt } }, skip: 1
// Use:
where: { appId, createdAt: { gt: createdAt } }, skip: 0The comparison operator (gt/lt) depends on the orderBy direction and pagination direction.
Prisma Schema & Queries
See reproduction above.
Prisma Config
import path from "node:path";
import { defineConfig } from "prisma/config";
export default defineConfig({
earlyAccess: true,
schema: path.join(__dirname, "schema.prisma"),
datasource: {
async url() {
return process.env.DATABASE_URL ?? "mysql://root@127.0.0.1:3306/cursor_repro";
},
},
});Environment & Setup
- OS: macOS (Darwin arm64)
- Database: MySQL 8.0.42
- Node.js version: v22.18.0
Prisma Version
prisma : 7.4.2
@prisma/client : 7.4.2
Operating System : darwin
Architecture : arm64
Node.js : v22.18.0
Query Compiler : enabled
Schema Engine : schema-engine-cli 94a226be1cf2967af2541cca5529f0f7ba866919