Skip to content

Conversation

@sgress454
Copy link
Contributor

This PR updates the escape character sequences in SQLite to only be ''. From the SQLite docs (see section 3 "Literal Values (Constants)"; emphasis mine):

A string constant is formed by enclosing the string in single quotes ('). A single quote within the string can be encoded by putting two single quotes in a row - as in Pascal. C-style escapes using the backslash character are not supported because they are not standard SQL.

This fix allows the following common query pattern to work:

SELECT * FROM "table_name" WHERE "column_name" LIKE '\_%' ESCAPE '\'

This sets the escape character to a backslash so that single-character wildcared _ char can be escaped, and you can look for values starting with an underscore.

Comment on lines -269 to +270
const sql = `SELECT * FROM table_name WHERE column_name LIKE '%pattern%' ESCAPE '\'`
expect(getParsedSql(sql)).to.be.equal(`SELECT * FROM "table_name" WHERE "column_name" LIKE '%pattern%' ESCAPE '\'`)
const sql = `SELECT * FROM table_name WHERE column_name LIKE '%pattern%' ESCAPE 'x'`
expect(getParsedSql(sql)).to.be.equal(`SELECT * FROM "table_name" WHERE "column_name" LIKE '%pattern%' ESCAPE 'x'`)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

My previous PR added this test which I thought proved that the desired query would work, but this really just evaluated to ESCAPE ''. Working with escapes can really do your head in! Updating to just show that ESCAPE works with LIKE, and added a separate test for the \' case.

sgress454 added a commit to fleetdm/fleet that referenced this pull request Jul 25, 2025
for #30109

# Details

This PR fixes an issue in our current SQL parsing library that was
causing queries like this to be marked invalid:

```
SELECT * FROM table_name WHERE column_name LIKE '\_%' ESCAPE '\'
```

This is valid in SQLite because the `\` is not considered an escape
character by default. From [the SQLite
docs](https://www.sqlite.org/lang_expr.html) (see section 3 "Literal
Values (Constants)"; emphasis mine):

> A string constant is formed by enclosing the string in single quotes
('). A single quote within the string can be encoded by putting two
single quotes in a row - as in Pascal. C-style escapes using the
backslash character are not supported because they are not standard SQL.

# Use of forked code

Part of the fix for this was [submitted as a PR to the node-sql-parser
library](taozhi8833998/node-sql-parser#2496) we
now use, and merged. I then found that another fix was needed, which I
submitted as [a separate
PR](taozhi8833998/node-sql-parser#2512). As
these fixes have yet to be made part of an official release of the
library, I made a fork off of the release we were using (5.3.10) and
bundled the necessary build artifacts with Fleet. We have an [ADR
proposing the use of submodules for this
purpose](#31079); I'm happy to
implement that instead if we approve that, although for a front-end
module with a build step it's a bit more complicated. Hopefully this
code will be released in `node-sql-parser` soon and we can revert back
to using the dependency.

Here is the [full set of
changes](taozhi8833998/node-sql-parser@master...sgress454:node-sql-parser:5.3.10-plus).

# Checklist for submitter

- [X] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.
- [X] Manual QA for all new/changed functionality
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant