Skip to content

Commit 5021523

Browse files
d-csclaude
andcommitted
fix(run-ops split): use composite keyset cursor in cross-version pagination test
The keyset walk paged with createdAt > cursor while ordering DESC, so it re-fetched newer rows instead of advancing to older ones and terminated after one page — never exercising the page boundary. Both clients failed identically, so the equality assertion passed on broken data. Use a composite (createdAt, id) cursor with the correct direction so paging walks the full corpus and applies the id tie-break across tie groups. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent d331802 commit 5021523

1 file changed

Lines changed: 9 additions & 8 deletions

File tree

internal-packages/run-engine/src/engine/tests/crossVersionCompat.test.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -328,28 +328,29 @@ async function assertKeysetOrderIdentical(prismaA: AnyPrisma, prismaB: AnyPrisma
328328
await seed(prismaA);
329329
await seed(prismaB);
330330

331-
// EXACT cursor shape from getExecutionSnapshotsSince: createdAt > since, desc,
332-
// take 50. Mirror the prisma findMany as raw SQL so ORDER-BY is explicit and
333-
// version-comparable, with an explicit id tie-break.
334-
const page = (p: AnyPrisma, sinceCreatedAt: string | null) =>
331+
// Keyset walk mirroring getExecutionSnapshotsSince: desc, take 50, with a
332+
// composite (createdAt, id) cursor so paging advances to older rows and the
333+
// id tie-break is applied across straddled tie groups.
334+
const page = (p: AnyPrisma, cursor: { createdAt: string; id: string } | null) =>
335335
p.$queryRawUnsafe<{ id: string; createdAt: Date }[]>(
336336
`SELECT "id","createdAt" FROM "TaskRunExecutionSnapshot"
337337
WHERE "runId" = $1 AND "isValid" = true
338-
${sinceCreatedAt ? `AND "createdAt" > $2::timestamptz` : ""}
338+
${cursor ? `AND ("createdAt" < $2::timestamptz OR ("createdAt" = $2::timestamptz AND "id" < $3))` : ""}
339339
ORDER BY "createdAt" DESC, "id" DESC
340340
LIMIT 50`,
341-
...(sinceCreatedAt ? [runId, sinceCreatedAt] : [runId])
341+
...(cursor ? [runId, cursor.createdAt, cursor.id] : [runId])
342342
);
343343

344344
const walk = async (p: AnyPrisma) => {
345345
const all: { id: string; createdAt: Date }[] = [];
346-
let cursor: string | null = null;
346+
let cursor: { createdAt: string; id: string } | null = null;
347347
for (;;) {
348348
const rows = await page(p, cursor);
349349
if (rows.length === 0) break;
350350
all.push(...rows);
351351
if (rows.length < 50) break;
352-
cursor = rows[rows.length - 1].createdAt.toISOString();
352+
const last = rows[rows.length - 1];
353+
cursor = { createdAt: last.createdAt.toISOString(), id: last.id };
353354
}
354355
return all.map((r) => r.id);
355356
};

0 commit comments

Comments
 (0)