MCPcopy
hub / github.com/simstudioai/sim / updateColumnType

Function updateColumnType

apps/sim/lib/table/columns/service.ts:459–539  ·  view source on GitHub ↗
(
  data: UpdateColumnTypeData,
  requestId: string
)

Source from the content-addressed store, hash-verified

457 * @throws Error if table not found, column not found, or existing data is incompatible
458 */
459export async function updateColumnType(
460 data: UpdateColumnTypeData,
461 requestId: string
462): Promise<TableDefinition> {
463 return withLockedTable(data.tableId, async (table, trx) => {
464 // Scale both statement and idle timeouts to row count: the compatibility
465 // check below iterates every row in Node between the row SELECT and the
466 // schema UPDATE, leaving the transaction idle for that gap. The default 5s
467 // `idle_in_transaction_session_timeout` would abort a valid type change on
468 // a large table.
469 const timeoutMs = scaledStatementTimeoutMs(table.rowCount ?? 0, {
470 baseMs: 60_000,
471 perRowMs: 2,
472 })
473 await setTableTxTimeouts(trx, { statementMs: timeoutMs, idleMs: timeoutMs })
474
475 if (!(COLUMN_TYPES as readonly string[]).includes(data.newType)) {
476 throw new Error(
477 `Invalid column type "${data.newType}". Valid types: ${COLUMN_TYPES.join(', ')}`
478 )
479 }
480
481 const schema = table.schema
482 const columnIndex = schema.columns.findIndex((c) => columnMatchesRef(c, data.columnName))
483 if (columnIndex === -1) {
484 throw new Error(`Column "${data.columnName}" not found`)
485 }
486
487 const column = schema.columns[columnIndex]
488 if (column.type === data.newType) {
489 return table
490 }
491 const columnKey = getColumnId(column)
492
493 // Validate existing data is compatible with the new type
494 const rows = await trx
495 .select({ id: userTableRows.id, data: userTableRows.data })
496 .from(userTableRows)
497 .where(
498 and(
499 eq(userTableRows.tableId, data.tableId),
500 sql`${userTableRows.data} ? ${columnKey}`,
501 sql`${userTableRows.data}->>${columnKey}::text IS NOT NULL`
502 )
503 )
504
505 let incompatibleCount = 0
506 for (const row of rows) {
507 const rowData = row.data as RowData
508 const value = rowData[columnKey]
509 if (value === null || value === undefined) continue
510
511 if (!isValueCompatibleWithType(value, data.newType)) {
512 incompatibleCount++
513 }
514 }
515
516 if (incompatibleCount > 0) {

Callers 3

executeFunction · 0.90
route.tsFile · 0.90
route.tsFile · 0.90

Calls 10

withLockedTableFunction · 0.90
scaledStatementTimeoutMsFunction · 0.90
setTableTxTimeoutsFunction · 0.90
columnMatchesRefFunction · 0.90
getColumnIdFunction · 0.90
joinMethod · 0.80
infoMethod · 0.80
setMethod · 0.65
eqFunction · 0.50

Tested by

no test coverage detected