mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Loki Query Builder: Throw warning in query builder when order of operations is ambiguous (#75198)
* flag vector aggregations containing metric expressions (i.e.`(...)`) containing binary operation expressions with ambiguous error in the UI when switching between code and visual query builders.
This commit is contained in:
parent
ef441f02d0
commit
a996f3b4a7
@ -235,6 +235,22 @@ describe('buildVisualQueryFromString', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('returns error when parsing ambiguous query', () => {
|
||||||
|
//becomes topk(5, count_over_time({app="aggregator"} [1m])) / count_over_time({cluster="dev-eu-west-2"} [1m])
|
||||||
|
const context = buildVisualQueryFromString(
|
||||||
|
'topk(5,count_over_time({app="aggregator"}[1m])/count_over_time({cluster="dev-eu-west-2"}[1m]))'
|
||||||
|
);
|
||||||
|
expect(context).toMatchObject({
|
||||||
|
errors: [
|
||||||
|
{
|
||||||
|
from: 7,
|
||||||
|
text: 'Query parsing is ambiguous.',
|
||||||
|
to: 93,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('parses query with matcher label filter', () => {
|
it('parses query with matcher label filter', () => {
|
||||||
expect(buildVisualQueryFromString('{app="frontend"} | bar="baz"')).toEqual(
|
expect(buildVisualQueryFromString('{app="frontend"} | bar="baz"')).toEqual(
|
||||||
noErrors({
|
noErrors({
|
||||||
@ -535,7 +551,8 @@ describe('buildVisualQueryFromString', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('parses metrics query with function and aggregation with grouping at the end', () => {
|
it('parses metrics query with function and aggregation with grouping at the end', () => {
|
||||||
expect(buildVisualQueryFromString('sum(rate({app="frontend"} | json [5m])) without(job,name)')).toEqual(
|
const expression = 'sum(rate({app="frontend"} | json [5m])) without(job,name)';
|
||||||
|
expect(buildVisualQueryFromString(expression)).toEqual(
|
||||||
noErrors({
|
noErrors({
|
||||||
labels: [
|
labels: [
|
||||||
{
|
{
|
||||||
@ -667,7 +684,9 @@ describe('buildVisualQueryFromString', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('parses query with multiple label format', () => {
|
it('parses query with multiple label format', () => {
|
||||||
expect(buildVisualQueryFromString('{app="frontend"} | label_format renameTo=original, bar=baz')).toEqual(
|
// Converted to {app="frontend"} | label_format renameTo=original | label_format bar=baz by visual query builder
|
||||||
|
const expression = '{app="frontend"} | label_format renameTo=original, bar=baz';
|
||||||
|
expect(buildVisualQueryFromString(expression)).toEqual(
|
||||||
noErrors({
|
noErrors({
|
||||||
labels: [
|
labels: [
|
||||||
{
|
{
|
||||||
@ -715,9 +734,10 @@ describe('buildVisualQueryFromString', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('parses chained binary query', () => {
|
it('parses chained binary query', () => {
|
||||||
expect(
|
const expression = 'rate({project="bar"}[5m]) * 2 / rate({project="foo"}[5m]) + rate({app="test"}[1m])';
|
||||||
buildVisualQueryFromString('rate({project="bar"}[5m]) * 2 / rate({project="foo"}[5m]) + rate({app="test"}[1m])')
|
// is converted to (rate({project="bar"} [5m]) * 2) / (rate({project="foo"} [5m]) + rate({app="test"} [1m])) by visual query builder
|
||||||
).toEqual(
|
// Note the extra parenthesis around the first binary operation expression: (rate({project="bar"} [5m]) * 2)
|
||||||
|
expect(buildVisualQueryFromString(expression)).toEqual(
|
||||||
noErrors({
|
noErrors({
|
||||||
labels: [{ op: '=', value: 'bar', label: 'project' }],
|
labels: [{ op: '=', value: 'bar', label: 'project' }],
|
||||||
operations: [
|
operations: [
|
||||||
@ -777,7 +797,9 @@ describe('buildVisualQueryFromString', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('parses a regexp with no param', () => {
|
it('parses a regexp with no param', () => {
|
||||||
expect(buildVisualQueryFromString('{app="frontend"} | regexp ')).toEqual(
|
const expression = '{app="frontend"} | regexp ';
|
||||||
|
// Converted to {app="frontend"} | regexp `` by visual query builder
|
||||||
|
expect(buildVisualQueryFromString(expression)).toEqual(
|
||||||
noErrors({
|
noErrors({
|
||||||
labels: [
|
labels: [
|
||||||
{
|
{
|
||||||
|
@ -541,6 +541,15 @@ function handleVectorAggregation(expr: string, node: SyntaxNode, context: Contex
|
|||||||
const op: QueryBuilderOperation = { id: funcName, params };
|
const op: QueryBuilderOperation = { id: funcName, params };
|
||||||
|
|
||||||
if (metricExpr) {
|
if (metricExpr) {
|
||||||
|
// A vector aggregation expression with a child of metric expression with a child of binary expression is ambiguous after being parsed into a visual query
|
||||||
|
if (metricExpr.firstChild?.type.id === BinOpExpr) {
|
||||||
|
context.errors.push({
|
||||||
|
text: 'Query parsing is ambiguous.',
|
||||||
|
from: metricExpr.firstChild.from,
|
||||||
|
to: metricExpr.firstChild?.to,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
handleExpression(expr, metricExpr, context);
|
handleExpression(expr, metricExpr, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user