@@ -2,7 +2,7 @@ import { backfillEmbeddingSearch } from '@sim/db/script-migrations/0015_backfill
22import { backfillSearchVectors } from '@sim/db/script-migrations/0016_backfill_search_vectors'
33import { generateId } from '@sim/utils/id'
44import postgres , { type Sql } from 'postgres'
5- import { afterAll , beforeAll , describe , expect , it } from 'vitest'
5+ import { afterAll , beforeAll , describe , expect , it , vi } from 'vitest'
66
77const databaseUrl = process . env . KNOWLEDGE_ACL_TEST_DATABASE_URL
88const schemaName = `search_projection_${ generateId ( ) . replaceAll ( '-' , '' ) } `
@@ -55,8 +55,37 @@ describe.runIf(Boolean(databaseUrl))('search projection upgrade in PostgreSQL',
5555 }
5656 } )
5757
58- it ( 'upgrades multiple pages while preserving the old projection and every unsupported-model dimension' , async ( ) => {
59- expect ( await backfillSearchVectors ( sql ) ) . toBe ( 501 )
58+ it ( 'serializes behind existing writers before upgrading the projection in batches' , async ( ) => {
59+ const writer = postgres ( databaseUrl ! , {
60+ max : 1 ,
61+ connection : { search_path : `${ schemaName } ,public` } ,
62+ onnotice : ( ) => undefined ,
63+ } )
64+ const [ { pid } ] = await sql `SELECT pg_backend_pid() AS pid`
65+ await writer `BEGIN`
66+ await writer `LOCK TABLE embedding IN ROW EXCLUSIVE MODE`
67+ const upgrade = Promise . allSettled ( [ backfillSearchVectors ( sql ) ] )
68+ try {
69+ await vi . waitFor ( async ( ) => {
70+ const [ { waiting } ] = await admin `SELECT EXISTS (
71+ SELECT 1 FROM pg_locks WHERE pid = ${ pid }
72+ AND relation = ${ `${ schemaName } .embedding` } ::regclass AND NOT granted
73+ ) AS waiting`
74+ expect ( waiting ) . toBe ( true )
75+ } )
76+ await writer `UPDATE embedding SET enabled = false WHERE id = 'chunk-1'`
77+ await writer `COMMIT`
78+ const [ result ] = await upgrade
79+ if ( result . status === 'rejected' ) throw result . reason
80+ expect ( result . value ) . toBe ( 501 )
81+ } finally {
82+ await writer `ROLLBACK`
83+ await upgrade
84+ await writer . end ( )
85+ }
86+ expect ( ( await sql `SELECT enabled FROM embedding_search WHERE id = 'chunk-1'` ) [ 0 ] . enabled ) . toBe (
87+ false
88+ )
6089 const rows = await sql . unsafe ( `SELECT knowledge_base_id,
6190 vector_dims(coalesce(${ fields . join ( ', ' ) } )) AS dimensions,
6291 num_nonnulls(${ fields . join ( ', ' ) } ) AS populated,
0 commit comments