HYPERFLEET-1276 - refactor: simplify TSL v6 search helpers#249
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Central YAML (base), Organization UI (inherited) Review profile: CHILL Plan: Enterprise Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (7)
🔗 Linked repositories identifiedCodeRabbit considers these linked repositories for cross-repo context during reviews:
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (4)
📝 WalkthroughSummary by CodeRabbit
WalkthroughThis PR migrates tree-search-language usage to v6 in Sequence Diagram(s)sequenceDiagram
participant GenericService
participant tsl
participant db
participant SqlWalker
GenericService->>tsl: ParseTSL(listCtx.args.Search)
GenericService->>db: ExtractConditionQueries(tslTree)
GenericService->>db: FieldNameWalk(tslTree, disallowedFields)
GenericService->>SqlWalker: Walk(&tsl.TSLNode{Node: tslTree})
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes 🚥 Pre-merge checks | ✅ 10 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (10 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
Comment |
Risk Score: 2 —
|
| Signal | Detail | Points |
|---|---|---|
| PR size | 1530 lines (>500) | +2 |
| Sensitive paths | none | +0 |
| Test coverage | Tests cover changed packages | +0 |
Computed by hyperfleet-risk-scorer
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
pkg/db/sql_helpers.go (1)
365-392: 🎯 Functional Correctness | 🟠 MajorReject mixed
ORexpressions containing condition predicates.ExtractConditionQueriesreplaces condition nodes with1 = 1, and the extracted SQL is appended later withAND. That changesname='x' OR status.conditions.Available='True'into(name='x' OR 1=1) AND ..., which collapses theORbranch and mis-evaluates the query (CWE-682). Either keep condition SQL in the AST or reject mixedORqueries.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pkg/db/sql_helpers.go` around lines 365 - 392, ExtractConditionQueries in sql_helpers.go must not rewrite condition predicates inside mixed OR expressions to a always-true placeholder, because that changes the boolean logic. Update the handling around hasCondition/conditionsNodeConverter so mixed OR queries containing condition fields are either rejected with a BadRequest or preserved in the AST without collapsing the OR branch. Use the existing unary NOT and condition extraction logic in ExtractConditionQueries, conditionsNodeConverter, and subtreeHasCondition as the place to enforce this rule.pkg/services/generic.go (1)
333-355: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winSkip mapped JSONB expressions before related-table dot splitting.
After
FieldNameWalk, fields likelabels->>'app.kubernetes.io/name'orproperties ->> 'owner.name'can contain dots but are no longer relation paths. Splitting them here misclassifies the prefix as a related resource and returns a bad request. No CWE applies; this is deterministic query translation breakage.Proposed fix
walkFn := func(field string) (string, error) { + if strings.Contains(field, "->") { + return field, nil + } fieldParts := strings.Split(field, ".") if len(fieldParts) > 1 && fieldParts[0] != resourceTable {🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pkg/services/generic.go` around lines 333 - 355, Skip JSONB-mapped expressions before relation-path handling in walkFn: after FieldNameWalk, strings like labels->>'app.kubernetes.io/name' or properties ->> 'owner.name' may contain dots but are not related-table references. Update the IdentWalk logic in generic.go so it first detects mapped JSONB expressions and returns them unchanged, and only then splits on "." and resolves joins via listCtx.joins/GetTableRelation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@pkg/db/sql_helpers.go`:
- Around line 52-60: The properties.* branch in the field-building logic is
bypassing the shared disallowed-field validation, so a resource that forbids
properties can still be queried through a nested property key. Update the field
resolution flow in the helper that handles trimmed names so the disallowedFields
check applies before returning from the properties prefix path, or explicitly
validate the base “properties” field before constructing the SQL expression. Use
the existing symbols validateFieldKey, disallowedFields, and the properties.*
handling in sql_helpers.go to keep the check consistent with other field cases.
- Around line 271-279: Preserve sub-second precision when rebinding timestamp
literals in the SQL helper: in the `tsl.KindTimestampLiteral` handling inside
`sql_helpers.go`, change the formatting used for `n.Right.Value.(time.Time)`
from the current RFC3339-based conversion to a nanosecond-preserving one so
fractional seconds are not lost. Keep the existing type check and error path in
place, and update the `rightStr` assignment in this branch to use
`time.RFC3339Nano` so condition filters compare against the exact timestamp
value.
---
Outside diff comments:
In `@pkg/db/sql_helpers.go`:
- Around line 365-392: ExtractConditionQueries in sql_helpers.go must not
rewrite condition predicates inside mixed OR expressions to a always-true
placeholder, because that changes the boolean logic. Update the handling around
hasCondition/conditionsNodeConverter so mixed OR queries containing condition
fields are either rejected with a BadRequest or preserved in the AST without
collapsing the OR branch. Use the existing unary NOT and condition extraction
logic in ExtractConditionQueries, conditionsNodeConverter, and
subtreeHasCondition as the place to enforce this rule.
In `@pkg/services/generic.go`:
- Around line 333-355: Skip JSONB-mapped expressions before relation-path
handling in walkFn: after FieldNameWalk, strings like
labels->>'app.kubernetes.io/name' or properties ->> 'owner.name' may contain
dots but are not related-table references. Update the IdentWalk logic in
generic.go so it first detects mapped JSONB expressions and returns them
unchanged, and only then splits on "." and resolves joins via
listCtx.joins/GetTableRelation.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Central YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Enterprise
Run ID: b558e419-641e-4759-91b1-c59da15e1075
⛔ Files ignored due to path filters (1)
go.sumis excluded by!**/*.sum,!**/go.sum
📒 Files selected for processing (5)
go.modpkg/db/sql_helpers.gopkg/db/sql_helpers_test.gopkg/services/generic.gopkg/services/generic_test.go
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
openshift-hyperfleet/architecture(manual)openshift-hyperfleet/hyperfleet-api(manual)openshift-hyperfleet/hyperfleet-sentinel(manual)openshift-hyperfleet/hyperfleet-adapter(manual)openshift-hyperfleet/hyperfleet-broker(manual)
Replace 100-line FieldNameWalk with IdentWalk + getField callback, extract wrapSpecNumericCasts, move properties into getField, delete NormalizeInSyntax (no consumers use old IN () syntax), add missing properties key validation, remove dead code. Net: -670 lines.
Replace 100-line FieldNameWalk with IdentWalk + getField callback, extract wrapSpecNumericCasts, move properties into getField, delete NormalizeInSyntax (no consumers use old IN () syntax), add missing properties key validation, remove dead code.
Net: -670 lines.
Summary
Test Plan
make test-allpassesmake lintpassesmake test-helm(if applicable)