Skip to content

feat(lapis): support escaping single quotes in advanced query string values#1599

Merged
fengelniederhammer merged 6 commits intomainfrom
1597-escaping-in-advanced-queries
Mar 17, 2026
Merged

feat(lapis): support escaping single quotes in advanced query string values#1599
fengelniederhammer merged 6 commits intomainfrom
1597-escaping-in-advanced-queries

Conversation

@fengelniederhammer
Copy link
Contributor

resolves #1597

Inside a quoted value, \' now produces a literal ', and \\ produces a literal \.

BREAKING CHANGE: Backslash is now an escape character inside quoted strings. In regex queries that use \ as a regex escape, you'll need to pass \\ now, e.g. before: division.regex=Basel\{1,2\} -> after: division.regex=Basel\\{1,2\\}

PR Checklist

  • All necessary documentation has been adapted.
    - [ ] All necessary changes are explained in the llms.txt.
  • The implemented feature is covered by an appropriate test.

@vercel
Copy link

vercel bot commented Mar 16, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
lapis Ready Ready Preview, Comment Mar 16, 2026 9:31am

Request Review

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the LAPIS advanced query language to support escaping within single-quoted metadata values, enabling queries like country='Côte d\'Ivoire' and treating backslash as an escape character inside quoted strings.

Changes:

  • Extend the ANTLR grammar for quoted strings to support backslash escapes within single-quoted values.
  • Unescape backslash-escaped characters when mapping parsed metadata values into the query model.
  • Update tests and docs to cover escaped single quotes/backslashes and the new regex-escape requirements.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
lapis/src/test/kotlin/org/genspectrum/lapis/model/AdvancedQueryFacadeTest.kt Updates/extends test cases for escaped quotes/backslashes and regex behavior.
lapis/src/main/kotlin/org/genspectrum/lapis/model/AdvancedQueryCustomListener.kt Unescapes parsed quoted values before creating filter expressions.
lapis/src/main/antlr/org/genspectrum/lapis/model/advancedqueryparser/AdvancedQuery.g4 Adjusts QUOTED_STRING lexer rule to allow backslash escapes.
lapis-docs/src/content/docs/concepts/advanced-query.mdx Documents escaping single quotes and backslashes in quoted metadata values.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

DOT: '.';
ASTERISK: '*';
QUOTED_STRING: '\'' (~['\r\n])* '\''; // matches all strings with quotes, except if they contain a newline
QUOTED_STRING: '\'' ( '\\' . | ~['\\\r\n] )* '\''; // matches all strings with quotes, supports \' to escape a single quote
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I simply decided to treat newlines as literal characters there. I don't see the need for the additional complexity of somehow getting rid of them and then having weird, inconsistent behavior.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds support for escaping single quotes (and backslashes) inside quoted values in LAPIS advanced queries, enabling queries like country='Côte d\'Ivoire' and requiring doubled backslashes for literal backslashes in regex patterns.

Changes:

  • Update ANTLR grammar to allow backslash-escaped characters inside QUOTED_STRING.
  • Unescape quoted metadata values in the advanced query listener.
  • Extend tests and documentation with examples for escaped quotes/backslashes and newline handling.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
lapis/src/test/kotlin/org/genspectrum/lapis/model/AdvancedQueryFacadeTest.kt Adds/updates test cases for escaped quotes/backslashes (including regex) and newline behavior.
lapis/src/main/kotlin/org/genspectrum/lapis/model/AdvancedQueryCustomListener.kt Introduces unescaping for quoted values in enterMetadataQuery.
lapis/src/main/antlr/org/genspectrum/lapis/model/advancedqueryparser/AdvancedQuery.g4 Extends QUOTED_STRING token to support backslash escaping.
lapis-docs/src/content/docs/concepts/advanced-query.mdx Documents escaping single quotes and backslashes in quoted values.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines 171 to 174
override fun enterMetadataQuery(ctx: AdvancedQueryParser.MetadataQueryContext) {
val metadataName = ctx.name().text
val metadataValue = ctx.value().text.trim('\'')
val metadataValue = ctx.value().text.trim('\'').replace(ESCAPE_SEQUENCE_REGEX, "$1")

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think this is true? There is a test that checks it.

Copy link
Contributor

Choose a reason for hiding this comment

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

I was also confused

Copy link
Contributor

@anna-parker anna-parker left a comment

Choose a reason for hiding this comment

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

this looks good, could you add some examples of some more weird characters that are escaped e.g. umlaut?

@fengelniederhammer
Copy link
Contributor Author

could you add some examples of some more weird characters that are escaped e.g. umlaut?

Yes, but I'll make a separate issue for that. It's beyond the scope of this PR.
-> #1603

@fengelniederhammer fengelniederhammer merged commit 88d59e9 into main Mar 17, 2026
8 checks passed
@fengelniederhammer fengelniederhammer deleted the 1597-escaping-in-advanced-queries branch March 17, 2026 10:30
fengelniederhammer pushed a commit that referenced this pull request Mar 19, 2026
🤖 I have created a release *beep* *boop*
---


## [0.8.0](v0.7.2...v0.8.0)
(2026-03-19)


### ⚠ BREAKING CHANGES

* **lapis:** Backslash is now an escape character inside quoted strings.
In regex queries that use `\` as a regex escape, you'll need to pass
`\\` now, e.g. before: `division.regex=Basel\{1,2\}` -> after:
`division.regex=Basel\\{1,2\\}`

### Features

* **lapis:** support escaping single quotes in advanced query string
values ([#1599](#1599))
([88d59e9](88d59e9))


### Bug Fixes

* **lapis:** health check: consider LAPIS "UP" even when SILO is down
([#1594](#1594))
([b9abdf9](b9abdf9))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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.

Escaping ' in advanced queries

3 participants