diff --git a/.changeset/clean-waves-smoke.md b/.changeset/clean-waves-smoke.md new file mode 100644 index 000000000..6b6e99e57 --- /dev/null +++ b/.changeset/clean-waves-smoke.md @@ -0,0 +1,5 @@ +--- +"@hyperdx/app": patch +--- + +fix delimited column identifier for dynamic fields diff --git a/packages/app/src/hooks/__tests__/useRowWhere.test.tsx b/packages/app/src/hooks/__tests__/useRowWhere.test.tsx index 3d63f4cc2..53950474b 100644 --- a/packages/app/src/hooks/__tests__/useRowWhere.test.tsx +++ b/packages/app/src/hooks/__tests__/useRowWhere.test.tsx @@ -173,10 +173,10 @@ describe('processRowToWhereClause', () => { const row = { dynamic_field: '"quoted_value"' }; const result = processRowToWhereClause(row, columnMap); - expect(result).toBe("toString(dynamic_field)='quoted_value'"); + expect(result).toBe("toString(`dynamic_field`)='quoted_value'"); }); - it('should handle Dynamic columns with escaped values', () => { + it('should handle Dynamic columns with escaped values and single quote', () => { const columnMap = new Map([ [ 'dynamic_field', @@ -189,10 +189,30 @@ describe('processRowToWhereClause', () => { ], ]); - const row = { dynamic_field: '{\\"took\\":7, not a valid json' }; + const row = { dynamic_field: '{\\"took\\":7, this ins\'t a valid json' }; const result = processRowToWhereClause(row, columnMap); expect(result).toBe( - 'toString(dynamic_field)=\'{\\"took\\":7, not a valid json\'', + "toString(`dynamic_field`)='{\\\"took\\\":7, this ins\\'t a valid json'", + ); + }); + + it('should handle Dynamic columns with delimited identifier', () => { + const columnMap = new Map([ + [ + 'dynamic_field.nested.needs\\toBeEscaped', + { + name: 'dynamic_field.nested\\ToBeEscaped', + type: 'Dynamic', + valueExpr: 'dynamic_field.nested.needs\\ToBeEscaped', + jsType: JSDataType.Dynamic, + }, + ], + ]); + + const row = { 'dynamic_field.nested.needs\\toBeEscaped': 'some string' }; + const result = processRowToWhereClause(row, columnMap); + expect(result).toBe( + `toString(\`dynamic_field\`.\`nested\`.\`needs\\ToBeEscaped\`)='some string'`, ); }); diff --git a/packages/app/src/hooks/useRowWhere.tsx b/packages/app/src/hooks/useRowWhere.tsx index 62d438c80..d7b483946 100644 --- a/packages/app/src/hooks/useRowWhere.tsx +++ b/packages/app/src/hooks/useRowWhere.tsx @@ -68,21 +68,19 @@ export function processRowToWhereClause( if (value === 'null') { return SqlString.format(`isNull(??)`, [valueExpr]); } - if (value.length > 1000 || column.length > 1000) { - console.warn('Search value/object key too large.'); - } // TODO: update when JSON type have new version // will not work for array/object dyanmic data // escaped strings needs raw, becuase sqlString will add another layer of escaping // data other than array/object will alwayas return with dobule quote(because of CH) - // remove dobule qoute to search correctly - return SqlString.format(`toString(?)='?'`, [ - SqlString.raw(valueExpr), + // remove double quotes if present and escape single quotes + return SqlString.format(`toString(??)='?'`, [ + valueExpr, SqlString.raw( - value[0] === '"' && value[value.length - 1] === '"' + (value[0] === '"' && value[value.length - 1] === '"' ? value.slice(1, -1) - : value, + : value + ).replace(/'/g, "\\'"), ), ]); default: