-
Notifications
You must be signed in to change notification settings - Fork 1.9k
feat: implement case-insensitive query name handling in formula evaluation #9302
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: implement case-insensitive query name handling in formula evaluation #9302
Conversation
…ation Signed-off-by: “niladrix719” <[email protected]>
Signed-off-by: “niladrix719” <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR is being reviewed by Cursor Bugbot
Details
Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.
To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.
Bug: Case-Insensitive Key Mismatch in Default-To-Zero Lookup
The canDefaultZero lookup uses the original variable case from the expression (e.g., "a"), but canDefaultZero is keyed by query names from the spec (e.g., "A"). When formulas use lowercase variables like "a / b" but queries are named "A" and "B", the lookup fe.canDefaultZero[variable] fails, breaking default-to-zero behavior. The canDefaultZero map keys need normalization to uppercase to match the case-insensitive query name handling.
pkg/types/querybuildertypes/querybuildertypesv5/formula.go#L502-L503
signoz/pkg/types/querybuildertypes/querybuildertypesv5/formula.go
Lines 502 to 503 in ad48039
| for _, variable := range fe.variables { | |
| if _, exists := values[variable]; !exists && fe.canDefaultZero[variable] { |
|
@niladrix719 check the above ^ |
Signed-off-by: “niladrix719” <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR is being reviewed by Cursor Bugbot
Details
Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.
To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.
| normalizedCanDefaultZero[k] = v | ||
| normalizedCanDefaultZero[strings.ToUpper(k)] = v | ||
| normalizedCanDefaultZero[strings.ToLower(k)] = v | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Non-deterministic behavior with conflicting case-sensitive keys
The normalization logic creates non-deterministic behavior when canDefaultZero contains the same key in different cases with conflicting values (e.g., {"A": true, "a": false}). Since Go map iteration order is random, the final normalized values become unpredictable as later iterations overwrite earlier ones. This causes inconsistent formula evaluation results across runs when conflicting case-sensitive keys exist in the input.
| normalizedSeriesMap := make(map[string]*TimeSeriesData, len(timeSeriesData)) | ||
| for name, ts := range timeSeriesData { | ||
| normalizedSeriesMap[strings.ToUpper(name)] = ts | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Non-deterministic data loss with case-conflicting time series keys
The normalization logic causes data loss when timeSeriesData contains multiple keys differing only in case (e.g., {"a": data1, "A": data2}). Since Go map iteration order is random, which time series data survives the uppercase normalization is non-deterministic. This leads to unpredictable formula evaluation results when case-conflicting query names exist in the input data, potentially using the wrong time series for calculations.
📄 Summary
Modified the formula evaluation logic in formula.go to normalize query names to uppercase during parsing and use case-insensitive matching when looking up time series data, allowing formulas like A/B, a/b, A/b, and a/B to produce same results
✅ Changes
🏷️ Required: Add Relevant Labels
ex:
backend👥 Reviewers
🧪 How to Test
🔍 Related Issues
Closes #9216
📸 Screenshots / Screen Recording (if applicable / mandatory for UI related changes)
Screen.Recording.2025-10-10.at.8.49.24.AM.mov
📋 Checklist
👀 Notes for Reviewers
Note
Normalize query names for formulas to be case-insensitive (variables, lookups, and defaults), plus tests validating mixed-case usage.
pkg/types/querybuildertypes/querybuildertypesv5/formula.go:parseAggregationReferenceand when building lookup maps forEvaluateFormulato enable case-insensitive matching between expressions andtimeSeriesDatakeys.canDefaultZerokeys to include original, upper, and lower cases for consistent access.pkg/types/querybuildertypes/querybuildertypesv5/formula_test.go:TestCaseInsensitiveQueryNamescovering mixed/mismatched case across expressions and data keys.Written by Cursor Bugbot for commit 2b06446. This will update automatically on new commits. Configure here.