Skip to content
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

Bug(LogQL): Fix mismatch results on scalar and vector binary ops #10997

Merged
merged 11 commits into from
Oct 27, 2023

Conversation

kavirajk
Copy link
Contributor

@kavirajk kavirajk commented Oct 23, 2023

What this PR does / why we need it:

According to LogQL doc, binary operators between scalar and vector should behave as follows (either it's scalar op vector or vector op scalar)

Between a vector and a scalar, these operators are applied to the value of every data sample in the vector

PromQL (where LogQL inspired from) also works that way.

Currently LogQL violates this behaviour. It returns whatever on the left (even if it's scalar). Look into the attached issue for more details.

Changes:

  1. Fixed MergeBinOps by making it aware when to return left or right (depending on which is from vector originally)
  2. Add tests in both engine_test.go and evaluator_test.go to lock this behaviour
  3. Added appropriate comments to the types and functions.

Which issue(s) this PR fixes:
Fixes #10741

Special notes for your reviewer:

Checklist

  • Reviewed the CONTRIBUTING.md guide (required)
  • Tests updated
  • CHANGELOG.md updated
    • If the change is worth mentioning in the release notes, add add-to-release-notes label
  • Changes that require user attention or interaction to upgrade are documented in docs/sources/setup/upgrade/_index.md
  • For Helm chart changes bump the Helm chart version in production/helm/loki/Chart.yaml and update production/helm/loki/CHANGELOG.md and production/helm/loki/README.md. Example PR
  • If the change is deprecating or removing a configuration option, update the deprecated-config.yaml and deleted-config.yaml files respectively in the tools/deprecated-config-checker directory.

Repect the Promql following behaviour of Binary operations with vector vs scalar
1. `scalar` op `vector` - vector
2. `vector` op `scalar` - vector

Signed-off-by: Kaviraj <[email protected]>
@kavirajk kavirajk changed the title Bug: Fix mismatch results on scalar and vector binary ops Bug(LogQL): Fix mismatch results on scalar and vector binary ops Oct 23, 2023
Signed-off-by: Kaviraj <[email protected]>
@kavirajk kavirajk marked this pull request as ready for review October 23, 2023 07:45
@kavirajk kavirajk requested a review from a team as a code owner October 23, 2023 07:45
Copy link
Contributor

@MichelHollands MichelHollands left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Member

@owen-d owen-d left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great start, thanks!

// This matters because, either it's (vector op scalar) or (scalar op vector), the return sample value should
// always be sample value of vector argument.
// https://github.com/grafana/loki/issues/10741
func MergeBinOp(op string, left, right *promql.Sample, swap, notReturnBool, isVectorComparison bool) (*promql.Sample, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's more confusing to use notReturnBool compared to filter.

// if a filter-enabled vector-wise comparison has returned non-nil,
// ensure we return the left hand side's value (2) instead of the
// comparison operator's result (1: the truthy answer)
if notReturnBool {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bool flag doesn't have anything to do with whether we should perform swap. For an example, try 1 < bool $METRIC in prometheus -- it'll return a vector of values with 0 or 1.

Copy link
Contributor Author

@kavirajk kavirajk Oct 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's been there because, swapping has no impact when return bool (vector of 0 or 1)

Means, both
1 < bool $METRIC and $METRIC > bool 1 will return exact same vector of values (0 or 1) without needed to swap. In other words, whether to return left or right sample is irrelevant in case of returning bool. Am I missing anything here?

Also confirmed by moving the swap out of filter check. Added extra test to lock the behaviour.

1. revert `notReturnBool` -> `filter`
2. swap independent of `filter` flag

Signed-off-by: Kaviraj <[email protected]>
@kavirajk kavirajk requested a review from owen-d October 27, 2023 12:44
@owen-d owen-d merged commit 9366343 into main Oct 27, 2023
2 checks passed
@owen-d owen-d deleted the kavirajk/fix-loql-binop-scalar-vector branch October 27, 2023 18:32
kavirajk added a commit that referenced this pull request Oct 27, 2023
Changlog to include this LogQL binary ops bug fix.
#10997

Signed-off-by: Kaviraj <[email protected]>
rhnasc pushed a commit to inloco/loki that referenced this pull request Apr 12, 2024
…rafana#10997)

**What this PR does / why we need it**:

[According to LogQL
doc,](https://grafana.com/docs/loki/latest/query/#comparison-operators)
binary operators between `scalar` and `vector` should behave as follows
(either it's `scalar` op `vector` or `vector` op `scalar`)

```
Between a vector and a scalar, these operators are applied to the value of every data sample in the vector
```
PromQL (where LogQL inspired from) [also works that
way](https://prometheus.io/docs/prometheus/latest/querying/operators/).

Currently LogQL violates this behaviour. It returns whatever on the
`left` (even if it's scalar). Look into the attached issue for more
details.

Changes:
1. Fixed `MergeBinOps` by making it aware when to return left or right
(depending on which is from vector originally)
2. Add tests in both `engine_test.go` and `evaluator_test.go` to lock
this behaviour
3. Added appropriate comments to the types and functions.

**Which issue(s) this PR fixes**:
Fixes grafana#10741

**Special notes for your reviewer**:


**Checklist**
- [x] Reviewed the
[`CONTRIBUTING.md`](https://github.com/grafana/loki/blob/main/CONTRIBUTING.md)
guide (**required**)
- [x] Tests updated
- [ ] `CHANGELOG.md` updated
- [ ] If the change is worth mentioning in the release notes, add
`add-to-release-notes` label
- [ ] Changes that require user attention or interaction to upgrade are
documented in `docs/sources/setup/upgrade/_index.md`
- [ ] For Helm chart changes bump the Helm chart version in
`production/helm/loki/Chart.yaml` and update
`production/helm/loki/CHANGELOG.md` and
`production/helm/loki/README.md`. [Example
PR](grafana@d10549e)
- [ ] If the change is deprecating or removing a configuration option,
update the `deprecated-config.yaml` and `deleted-config.yaml` files
respectively in the `tools/deprecated-config-checker` directory. <!--
TODO(salvacorts): Add example PR -->

---------

Signed-off-by: Kaviraj <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug/LogQL]: Results mismatch with binary comparison operators
3 participants