feat: Add support for querying nested/array fields#1660
Conversation
🦋 Changeset detectedLatest commit: c2e22fc The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
PR Review🔒 CRITICAL: SQL Injection Vulnerability packages/common-utils/src/queryParser.ts:788-803 - The stringifiedElement variable in renderArrayFieldExpression() is constructed and then embedded directly into SQL template strings without proper escaping. Issue: Line 791 calls SqlString.format('toString(el)', [SqlString.raw(column)]) which returns a formatted SQL string, then this string is interpolated into another SQL template at lines 797 and 801. This bypasses SqlString's escaping mechanism. Fix: Don't use SqlString.format for intermediate values. Use plain strings instead: const stringifiedElement = propertyType === JSDataType.String ? 'el' : 'toString(el)'; The column parameter is already properly escaped when passed to SqlString.format with SqlString.raw(column) at lines 798 and 802.
Recommendation: Fix the SQL injection issue before merging. |
E2E Test Results✅ All tests passed • 63 passed • 4 skipped • 835s
Tests ran across 4 shards in parallel. |
660169e to
583cab0
Compare
583cab0 to
d2c8a06
Compare
d2c8a06 to
7e3dbe4
Compare
knudtty
left a comment
There was a problem hiding this comment.
Apologies for the long review cycle
Closes HDX-3113
Summary
This PR adds support for querying nested (array-type) columns with Lucene syntax.
Syntax
Arrays of simple types
Events.Name:*-->notEmpty(Events.Name)Events.Name:"error"-->has(Events.Name, 'error')has()Events.Timestamp:"2026-02-02 15:19:37.196300098"-->arrayExists(el ->toString(el) = '2026-02-02 15:19:37.196300098, Events.Timestamp)Events.Name:domain-->arrayExists(el -> el ILIKE '%domain%', Events.Name)Arrays of Maps
Events.Attributes.exception.stacktrace:*-->arrayExists(el - > notEmpty (toString (el['exception.stacktrace'])) = 1, Events.Attributes)Events.Attributes.exception.stacktrace:"AggregateError"-->arrayExists(el - > el['exception.stacktrace'] = 'AggregateError', Events.Attributes)Events.Attributes.exception.stacktrace:"AggregateError"-->arrayExists(el - > el['exception.stacktrace'] ILIKE '%AggregateError%', Events.Attributes)Arrays of JSON
Events.Attributes.message:*-->arrayExists(el - > notEmpty (toString (el.message)) = 1, Events.Attributes)Events.Attributes.exception.stacktrace:"AggregateError"-->arrayExists(el - > toString (el.exception.stacktrace) = 'AggregateError', Events.Attributes)Events.Attributes.exception.stacktrace:AggregateError-->arrayExists(el - > toString (el.exception.stacktrace) ILIKE '%AggregateError%', Events.Attributes)