Skip to content

Commit bf376dd

Browse files
fix(cleanup): compare live-paused statuses with IN, not ANY over a row constructor (#6004)
1 parent e5ae445 commit bf376dd

3 files changed

Lines changed: 49 additions & 9 deletions

File tree

apps/sim/background/cleanup-logs.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ async function cleanupLegacyLargeExecutionValues(
256256
SELECT 1
257257
FROM ${pausedExecutions} AS ref_pe
258258
WHERE ref_pe.execution_id = ref.execution_id
259-
AND ref_pe.status = ANY(${LIVE_PAUSED_REFERENCE_STATUSES}::text[])
259+
AND ref_pe.status IN ${LIVE_PAUSED_REFERENCE_STATUSES}
260260
)
261261
)
262262
)
@@ -279,7 +279,7 @@ async function cleanupLegacyLargeExecutionValues(
279279
SELECT 1
280280
FROM ${pausedExecutions} AS parent_owner_pe
281281
WHERE parent_owner_pe.execution_id = parent_value.owner_execution_id
282-
AND parent_owner_pe.status = ANY(${LIVE_PAUSED_REFERENCE_STATUSES}::text[])
282+
AND parent_owner_pe.status IN ${LIVE_PAUSED_REFERENCE_STATUSES}
283283
)
284284
OR EXISTS (
285285
SELECT 1
@@ -300,7 +300,7 @@ async function cleanupLegacyLargeExecutionValues(
300300
SELECT 1
301301
FROM ${pausedExecutions} AS parent_ref_pe
302302
WHERE parent_ref_pe.execution_id = parent_ref.execution_id
303-
AND parent_ref_pe.status = ANY(${LIVE_PAUSED_REFERENCE_STATUSES}::text[])
303+
AND parent_ref_pe.status IN ${LIVE_PAUSED_REFERENCE_STATUSES}
304304
)
305305
)
306306
)
@@ -316,7 +316,7 @@ async function cleanupLegacyLargeExecutionValues(
316316
SELECT 1
317317
FROM ${pausedExecutions} AS pe
318318
WHERE pe.execution_id = split_part(${workspaceFiles.key}, '/', 4)
319-
AND pe.status = ANY(${LIVE_PAUSED_REFERENCE_STATUSES}::text[])
319+
AND pe.status IN ${LIVE_PAUSED_REFERENCE_STATUSES}
320320
)`
321321
)
322322
)

apps/sim/lib/execution/payloads/large-value-metadata.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ async function pruneStaleReferences(
412412
SELECT 1
413413
FROM ${pausedExecutions} AS pe
414414
WHERE pe.execution_id = ref.execution_id
415-
AND pe.status = ANY(${LIVE_PAUSED_REFERENCE_STATUSES}::text[])
415+
AND pe.status IN ${LIVE_PAUSED_REFERENCE_STATUSES}
416416
)
417417
)
418418
OR ref.source NOT IN ('execution_log', 'paused_snapshot')
@@ -568,7 +568,7 @@ export function unreferencedLargeValuePredicate() {
568568
SELECT 1
569569
FROM ${pausedExecutions} AS pe
570570
WHERE pe.execution_id = elvr.execution_id
571-
AND pe.status = ANY(${LIVE_PAUSED_REFERENCE_STATUSES}::text[])
571+
AND pe.status IN ${LIVE_PAUSED_REFERENCE_STATUSES}
572572
)
573573
)
574574
)
@@ -582,7 +582,7 @@ export function unreferencedLargeValuePredicate() {
582582
SELECT 1
583583
FROM ${pausedExecutions} AS owner_pe
584584
WHERE owner_pe.execution_id = ${executionLargeValues.ownerExecutionId}
585-
AND owner_pe.status = ANY(${LIVE_PAUSED_REFERENCE_STATUSES}::text[])
585+
AND owner_pe.status IN ${LIVE_PAUSED_REFERENCE_STATUSES}
586586
)
587587
AND NOT EXISTS (
588588
SELECT 1
@@ -602,7 +602,7 @@ export function unreferencedLargeValuePredicate() {
602602
SELECT 1
603603
FROM ${pausedExecutions} AS parent_owner_pe
604604
WHERE parent_owner_pe.execution_id = parent_value.owner_execution_id
605-
AND parent_owner_pe.status = ANY(${LIVE_PAUSED_REFERENCE_STATUSES}::text[])
605+
AND parent_owner_pe.status IN ${LIVE_PAUSED_REFERENCE_STATUSES}
606606
)
607607
OR EXISTS (
608608
SELECT 1
@@ -623,7 +623,7 @@ export function unreferencedLargeValuePredicate() {
623623
SELECT 1
624624
FROM ${pausedExecutions} AS parent_ref_pe
625625
WHERE parent_ref_pe.execution_id = parent_ref.execution_id
626-
AND parent_ref_pe.status = ANY(${LIVE_PAUSED_REFERENCE_STATUSES}::text[])
626+
AND parent_ref_pe.status IN ${LIVE_PAUSED_REFERENCE_STATUSES}
627627
)
628628
)
629629
)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* @vitest-environment node
3+
*/
4+
5+
// Renders the real predicate against the real drizzle dialect and schema: the
6+
// bug this guards against is a SQL *rendering* bug, so the global drizzle-orm
7+
// and schema mocks would hide it entirely.
8+
import { describe, expect, it, vi } from 'vitest'
9+
10+
vi.unmock('drizzle-orm')
11+
vi.unmock('@sim/db')
12+
vi.unmock('@sim/db/schema')
13+
14+
process.env.DATABASE_URL ??= 'postgresql://user:pass@localhost:5432/test'
15+
16+
const { PgDialect } = await import('drizzle-orm/pg-core')
17+
const { LIVE_PAUSED_REFERENCE_STATUSES, unreferencedLargeValuePredicate } = await import(
18+
'@/lib/execution/payloads/large-value-metadata'
19+
)
20+
21+
describe('unreferencedLargeValuePredicate SQL', () => {
22+
const { sql: text, params } = new PgDialect().sqlToQuery(unreferencedLargeValuePredicate())
23+
24+
it('compares paused status against an IN list', () => {
25+
expect(text).toMatch(/\.status IN \(\$\d+, \$\d+, \$\d+\)/)
26+
expect(params).toEqual(expect.arrayContaining([...LIVE_PAUSED_REFERENCE_STATUSES]))
27+
})
28+
29+
it('never emits ANY() over drizzle-expanded statuses', () => {
30+
// Drizzle renders a JS array as `($1, $2, $3)` — correct for IN, but
31+
// `ANY((...)::text[])` makes Postgres reject the whole statement with
32+
// "cannot cast type record to text[]", which killed cleanup-logs for two months.
33+
expect(text).not.toMatch(/ANY\(\(\$\d+/)
34+
})
35+
36+
it('never emits a dangling comparison operator before IN', () => {
37+
// `status = IN (...)` is a syntax error Postgres only reports at execution time.
38+
expect(text).not.toMatch(/=\s*IN\s*\(/)
39+
})
40+
})

0 commit comments

Comments
 (0)