Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion apps/sim/lib/table/sql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,10 +322,15 @@ function buildComparisonClause(
return sql`(${sql.raw(`${tableName}.data->>'${escapedField}'`)})::numeric ${sql.raw(operator)} ${value}`
}

/** Escapes LIKE/ILIKE wildcard characters so they match literally */
function escapeLikePattern(value: string): string {
return value.replace(/[\\%_]/g, '\\$&')
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicated escapeLikePattern utility across two modules

Low Severity

The new escapeLikePattern function in sql.ts is a semantic duplicate of the existing escapeLikePattern in apps/sim/lib/knowledge/documents/service.ts. Both escape the same three characters (\, %, _) for LIKE patterns, just with slightly different implementations (single regex vs. three chained .replace calls). Having two copies risks divergent bug fixes if one is updated without the other. This could be extracted to a shared utility.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit b1790f3. Configure here.


/** Builds case-insensitive pattern match: `data->>'field' ILIKE '%value%'` */
function buildContainsClause(tableName: string, field: string, value: string): SQL {
const escapedField = field.replace(/'/g, "''")
return sql`${sql.raw(`${tableName}.data->>'${escapedField}'`)} ILIKE ${`%${value}%`}`
return sql`${sql.raw(`${tableName}.data->>'${escapedField}'`)} ILIKE ${`%${escapeLikePattern(value)}%`}`
Comment on lines +325 to +333
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Missing tests for escapeLikePattern and wildcard inputs

The escapeLikePattern function is a new security-relevant helper, but no tests were added for it. The existing $contains test in __tests__/sql.test.ts (line 95) only asserts the result is defined — it does not verify that wildcards are actually escaped in the generated SQL pattern.

The PR description lists three concrete scenarios to verify ($contains: "100%", $contains: "a_b", $contains: "a\\b"), but none were implemented as test cases. Consider adding unit tests directly on escapeLikePattern covering these inputs:

describe('escapeLikePattern', () => {
  it('escapes percent signs', () => {
    expect(escapeLikePattern('100%')).toBe('100\\%')
  })
  it('escapes underscores', () => {
    expect(escapeLikePattern('a_b')).toBe('a\\_b')
  })
  it('escapes backslashes', () => {
    expect(escapeLikePattern('a\\b')).toBe('a\\\\b')
  })
  it('leaves plain strings unchanged', () => {
    expect(escapeLikePattern('john')).toBe('john')
  })
})

}
Comment on lines 330 to 334
Copy link

Copilot AI Apr 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

escapeLikePattern prefixes %, _, and \ with backslashes, but the generated ILIKE expression does not specify an ESCAPE clause. Adding ESCAPE '\\' makes the semantics explicit and matches the established pattern used elsewhere (e.g. apps/sim/lib/knowledge/documents/service.ts:895-907).

Copilot uses AI. Check for mistakes.
Comment on lines +325 to 334
Copy link

Copilot AI Apr 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change fixes wildcard handling for $contains, but there are no assertions covering the new escaping behavior. Please add unit tests (likely in apps/sim/lib/table/__tests__/sql.test.ts) that verify the generated pattern/params for inputs containing %, _, and \\ (e.g. 100%, a_b, c\\d) so regressions are caught.

Copilot uses AI. Check for mistakes.

/**
Expand Down
Loading