* Fire-and-forget reclamation of a deleted column's row storage. The column is * already gone from the schema, so reads never surface the orphaned id — * dropping the JSONB key just frees space. Runs in its own transaction with a * row-count-scaled timeout; failures are logged, not propagated.
( tableId: string, columnIds: string[], rowCount: number, requestId: string )
| 244 | * row-count-scaled timeout; failures are logged, not propagated. |
| 245 | */ |
| 246 | function stripColumnDataInBackground( |
| 247 | tableId: string, |
| 248 | columnIds: string[], |
| 249 | rowCount: number, |
| 250 | requestId: string |
| 251 | ): void { |
| 252 | if (columnIds.length === 0) return |
| 253 | void (async () => { |
| 254 | try { |
| 255 | await db.transaction(async (trx) => { |
| 256 | const statementMs = scaledStatementTimeoutMs(rowCount, { |
| 257 | baseMs: 60_000, |
| 258 | perRowMs: 2 * columnIds.length, |
| 259 | }) |
| 260 | await setTableTxTimeouts(trx, { statementMs }) |
| 261 | for (const id of columnIds) { |
| 262 | await trx.execute( |
| 263 | sql`UPDATE user_table_rows SET data = data - ${id}::text WHERE table_id = ${tableId} AND data ? ${id}::text` |
| 264 | ) |
| 265 | } |
| 266 | }) |
| 267 | logger.info( |
| 268 | `[${requestId}] Background-stripped deleted column data [${columnIds.join(', ')}] from table ${tableId}` |
| 269 | ) |
| 270 | } catch (err) { |
| 271 | logger.error( |
| 272 | `[${requestId}] Background column-data strip failed for table ${tableId} [${columnIds.join(', ')}]:`, |
| 273 | err |
| 274 | ) |
| 275 | } |
| 276 | })() |
| 277 | } |
| 278 | |
| 279 | /** |
| 280 | * Deletes a column from a table's schema. When id-keyed, returns once the schema |
no test coverage detected