mirror of
https://github.com/hyperdxio/hyperdx
synced 2026-04-21 13:37:15 +00:00
Support escaped quotes (#214)
Previously if you wanted to search something like `message:"{\"json\": \"value\""`, you couldn't as we didn't support escaping double quotes in exact property searches.
I've checked and I couldn't see anyone depending on the prior `\` behavior so while I believe this is breaking, I don't expect anyone to actually get impacted by this practically.
This commit is contained in:
parent
0824822a59
commit
a0dc1b5f25
5 changed files with 46 additions and 1 deletions
9
.changeset/angry-seahorses-sort.md
Normal file
9
.changeset/angry-seahorses-sort.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
'@hyperdx/api': minor
|
||||
'@hyperdx/app': minor
|
||||
---
|
||||
|
||||
Breaking Search Syntax Change: Backslashes will be treated as an escape
|
||||
character for a double quotes (ex. message:"\"" will search for the double quote
|
||||
character). Two backslashes will be treated as a backslash literal (ex.
|
||||
message:\\ will search for the backslash literal)
|
||||
|
|
@ -460,6 +460,36 @@ describe('searchQueryParser', () => {
|
|||
).toEqual('(1 = 0)');
|
||||
});
|
||||
|
||||
it('parses escaped quotes in quoted searches', async () => {
|
||||
const ast = parse('foo:"b\\"ar"');
|
||||
jest.spyOn(propertyTypesMappingsModel, 'get').mockReturnValue('string');
|
||||
expect(
|
||||
await genWhereSQL(
|
||||
ast,
|
||||
propertyTypesMappingsModel,
|
||||
'TEAM_ID_UNIT_TESTS',
|
||||
),
|
||||
).toEqual(eq("_string_attributes['foo']", 'b\\"ar'));
|
||||
});
|
||||
|
||||
it('parses backslash literals', async () => {
|
||||
const ast = parse('foo:"b\\\\ar"');
|
||||
jest.spyOn(propertyTypesMappingsModel, 'get').mockReturnValue('string');
|
||||
expect(
|
||||
await genWhereSQL(
|
||||
ast,
|
||||
propertyTypesMappingsModel,
|
||||
'TEAM_ID_UNIT_TESTS',
|
||||
),
|
||||
).toEqual(eq("_string_attributes['foo']", 'b\\\\ar'));
|
||||
});
|
||||
|
||||
it('does not escape quotes with backslash literals', async () => {
|
||||
expect(() => parse('foo:"b\\\\"ar"')).toThrowErrorMatchingInlineSnapshot(
|
||||
`"Expected \\"\\\\\\"\\", \\"\\\\\\\\\\", or any character but end of input found."`,
|
||||
);
|
||||
});
|
||||
|
||||
describe('negation', () => {
|
||||
it('negates property values', async () => {
|
||||
const ast = parse('-foo:bar');
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import { PropertyTypeMappingsModel } from './propertyTypeMappingsModel';
|
|||
|
||||
function encodeSpecialTokens(query: string): string {
|
||||
return query
|
||||
.replace(/\\\\/g, 'HDX_BACKSLASH_LITERAL')
|
||||
.replace('http://', 'http_COLON_//')
|
||||
.replace('https://', 'https_COLON_//')
|
||||
.replace(/localhost:(\d{1,5})/, 'localhost_COLON_$1')
|
||||
|
|
@ -15,6 +16,8 @@ function encodeSpecialTokens(query: string): string {
|
|||
}
|
||||
function decodeSpecialTokens(query: string): string {
|
||||
return query
|
||||
.replace(/\\"/g, '"')
|
||||
.replace(/HDX_BACKSLASH_LITERAL/g, '\\')
|
||||
.replace('http_COLON_//', 'http://')
|
||||
.replace('https_COLON_//', 'https://')
|
||||
.replace(/localhost_COLON_(\d{1,5})/, 'localhost:$1')
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ export default function DBQuerySidePanel() {
|
|||
const scopeWhereQuery = React.useCallback(
|
||||
(where: string) => {
|
||||
const spanNameQuery = dbQuery
|
||||
? `${DB_STATEMENT_PROPERTY}:"${dbQuery}" `
|
||||
? `${DB_STATEMENT_PROPERTY}:"${dbQuery.replace(/"/g, '\\"')}" `
|
||||
: '';
|
||||
const whereQuery = where ? `(${where})` : '';
|
||||
const serviceQuery = service ? `service:"${service}" ` : '';
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import lucene from '@hyperdx/lucene';
|
|||
|
||||
function encodeSpecialTokens(query: string): string {
|
||||
return query
|
||||
.replace(/\\\\/g, 'HDX_BACKSLASH_LITERAL')
|
||||
.replace('http://', 'http_COLON_//')
|
||||
.replace('https://', 'https_COLON_//')
|
||||
.replace(/localhost:(\d{1,5})/, 'localhost_COLON_$1')
|
||||
|
|
@ -9,6 +10,8 @@ function encodeSpecialTokens(query: string): string {
|
|||
}
|
||||
function decodeSpecialTokens(query: string): string {
|
||||
return query
|
||||
.replace(/\\"/g, '"')
|
||||
.replace(/HDX_BACKSLASH_LITERAL/g, '\\')
|
||||
.replace('http_COLON_//', 'http://')
|
||||
.replace('https_COLON_//', 'https://')
|
||||
.replace(/localhost_COLON_(\d{1,5})/, 'localhost:$1')
|
||||
|
|
|
|||
Loading…
Reference in a new issue