MCPcopy Index your code
hub / github.com/simstudioai/sim / findRowMatches

Function findRowMatches

apps/sim/lib/table/rows/service.ts:791–868  ·  view source on GitHub ↗
(
  table: TableDefinition,
  options: { q: string; filter?: Filter; sort?: Sort },
  requestId: string
)

Source from the content-addressed store, hash-verified

789 * index on a text projection is the future accelerator if needed.
790 */
791export async function findRowMatches(
792 table: TableDefinition,
793 options: { q: string; filter?: Filter; sort?: Sort },
794 requestId: string
795): Promise<{ matches: FindRowMatch[]; truncated: boolean }> {
796 const tableName = USER_TABLE_ROWS_SQL_NAME
797 const columns = table.schema.columns
798 // Row data is keyed by stable column id, so scan/return JSONB keys as ids.
799 const columnIds = columns.map(getColumnId)
800 if (columnIds.length === 0) return { matches: [], truncated: false }
801
802 // Same visibility rule as queryRows: don't surface rows a running delete job will remove.
803 const deleteMask = await pendingDeleteMask(table)
804
805 const baseConditions = and(
806 eq(userTableRows.tableId, table.id),
807 eq(userTableRows.workspaceId, table.workspaceId),
808 deleteMask
809 )
810 let whereClause: SQL | undefined = baseConditions
811 if (options.filter && Object.keys(options.filter).length > 0) {
812 const filterClause = buildFilterClause(options.filter, tableName, columns)
813 if (filterClause) whereClause = and(baseConditions, filterClause)
814 }
815
816 const fractionalOrdering = await isFeatureEnabled('tables-fractional-ordering')
817 const orderBySql = buildRowOrderBySql(options.sort, tableName, columns, fractionalOrdering)
818 const pattern = `%${escapeLikePattern(options.q)}%`
819
820 const result = await db.transaction(async (trx) => {
821 // Planner flags, not correctness: `enable_* = off` only penalizes a plan shape, so a
822 // genuinely required sort still runs. Seqscan off keeps the scan inside the tenant's rows
823 // (the lateral ILIKE is unestimatable, so the planner otherwise walks the whole shared
824 // relation). On the default order, the remaining flags steer to the already-sorted
825 // `(table_id, order_key, id)` index walk so the window function streams without a 100MB+
826 // disk sort; a custom sort has no index to stream from, so those flags would only distort
827 // that plan.
828 await trx.execute(sql`SET LOCAL enable_seqscan = off`)
829 if (!options.sort) {
830 await trx.execute(sql`SET LOCAL enable_bitmapscan = off`)
831 await trx.execute(sql`SET LOCAL enable_sort = off`)
832 await trx.execute(sql`SET LOCAL max_parallel_workers_per_gather = 0`)
833 }
834 return trx.execute<{
835 ordinal: string | number
836 id: string
837 column_name: string
838 }>(sql`
839 WITH ordered AS (
840 SELECT id, data, row_number() OVER (ORDER BY ${orderBySql}) - 1 AS ordinal
841 FROM ${userTableRows}
842 WHERE ${whereClause}
843 )
844 SELECT o.ordinal, o.id, kv.key AS column_name
845 FROM ordered o
846 CROSS JOIN LATERAL jsonb_each_text(o.data) kv
847 WHERE kv.value ILIKE ${pattern}
848 AND ${inArray(sql`kv.key`, columnIds)}

Callers 2

route.tsFile · 0.90

Calls 8

buildFilterClauseFunction · 0.90
isFeatureEnabledFunction · 0.90
escapeLikePatternFunction · 0.90
pendingDeleteMaskFunction · 0.85
buildRowOrderBySqlFunction · 0.85
infoMethod · 0.80
executeMethod · 0.65
eqFunction · 0.50

Tested by

no test coverage detected