Skip to content

Commit 50bad43

Browse files
feat(tables): resolve position-based inserts by key ordinal under the flag
Position-based callers (mothership tool, v1 API, undo fallback, transient old clients) resolve their insert neighbor by order_key ordinal (OFFSET) when the flag is on — positions are gappy then, so WHERE position=N would miss. Flag off keeps the indexed position lookup. The mothership tool itself is unchanged.
1 parent d221611 commit 50bad43

1 file changed

Lines changed: 26 additions & 12 deletions

File tree

apps/sim/lib/table/service.ts

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,26 +1170,40 @@ export function buildOrderedRowValues(opts: {
11701170
}
11711171

11721172
/**
1173-
* Computes the fractional `order_key` for a row being inserted at
1174-
* `requestedPosition` (or appended when omitted). Neighbors are resolved by the
1175-
* current `position` order — valid because keys are kept consistent with
1176-
* position order while the flag is off. Caller holds the row-order lock.
1173+
* Computes the fractional `order_key` for a row inserted at the integer
1174+
* `requestedPosition` (or appended when omitted). Used by position-based callers
1175+
* (mothership tool, v1 API, undo position-fallback, transient old clients).
11771176
*
1178-
* NOTE: flag-on insert-*at a position* will resolve neighbors by `order_key`
1179-
* (via beforeRowId/afterRowId) once the wire contract carries them; until then
1180-
* append (the common path) is exact and at-position is position-derived.
1177+
* The neighbor at slot `s` is resolved differently per flag state:
1178+
* - **off**: `WHERE position = s` (positions are contiguous, so the row at
1179+
* position `s` is the `s`-th row — an indexed O(1) lookup).
1180+
* - **on**: the `s`-th row in `order_key, id` order (`OFFSET s`) — positions are
1181+
* gappy and non-authoritative, so `position = s` would miss; the visual
1182+
* ordinal is the key's ordinal. O(s), acceptable for these low-volume callers.
1183+
*
1184+
* Caller holds the row-order lock.
11811185
*/
11821186
async function resolveInsertOrderKey(
11831187
trx: DbTransaction,
11841188
tableId: string,
11851189
requestedPosition?: number
11861190
): Promise<string> {
1187-
const orderKeyAtPosition = async (pos: number): Promise<string | null> => {
1188-
if (pos < 0) return null
1191+
const orderKeyAtSlot = async (slot: number): Promise<string | null> => {
1192+
if (slot < 0) return null
1193+
if (isTablesFractionalOrderingEnabled) {
1194+
const [r] = await trx
1195+
.select({ orderKey: userTableRows.orderKey })
1196+
.from(userTableRows)
1197+
.where(eq(userTableRows.tableId, tableId))
1198+
.orderBy(asc(userTableRows.orderKey), asc(userTableRows.id))
1199+
.limit(1)
1200+
.offset(slot)
1201+
return r?.orderKey ?? null
1202+
}
11891203
const [r] = await trx
11901204
.select({ orderKey: userTableRows.orderKey })
11911205
.from(userTableRows)
1192-
.where(and(eq(userTableRows.tableId, tableId), eq(userTableRows.position, pos)))
1206+
.where(and(eq(userTableRows.tableId, tableId), eq(userTableRows.position, slot)))
11931207
.limit(1)
11941208
return r?.orderKey ?? null
11951209
}
@@ -1200,8 +1214,8 @@ async function resolveInsertOrderKey(
12001214
.where(eq(userTableRows.tableId, tableId))
12011215
return keyBetween(maxKey ?? null, null)
12021216
}
1203-
const lo = await orderKeyAtPosition(requestedPosition - 1)
1204-
const hi = await orderKeyAtPosition(requestedPosition)
1217+
const lo = await orderKeyAtSlot(requestedPosition - 1)
1218+
const hi = await orderKeyAtSlot(requestedPosition)
12051219
return keyBetween(lo, hi)
12061220
}
12071221

0 commit comments

Comments
 (0)