Skip to content

Commit 3a4a533

Browse files
[9.1] [ES|QL] Improve binary expression grouping (#225416) (#226370)
# Backport This will backport the following commits from `main` to `9.1`: - [[ES|QL] Improve binary expression grouping (#225416)](#225416) <!--- Backport version: 9.6.6 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport) <!--BACKPORT [{"author":{"name":"Vadim Kibana","email":"[email protected]"},"sourceCommit":{"committedDate":"2025-07-03T10:03:00Z","message":"[ES|QL] Improve binary expression grouping (#225416)\n\n## Summary\n\nCloses https://github.com/elastic/kibana/issues/224990\n\nAlso:\n\n- Improves binary expression grouping with `()` parenthesis in\npretty-printer.\n- Updates binary expression precedence list.\n\n\n### Checklist\n\n- [x] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios","sha":"6d0dc4bcf7d8ed90a8634832a2aaa6b1683fc7fb","branchLabelMapping":{"^v9.2.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["review","release_note:skip","Feature:ES|QL","Team:ESQL","backport:version","v9.1.0","v8.19.0","v9.2.0"],"title":"[ES|QL] Improve binary expression grouping","number":225416,"url":"https://github.com/elastic/kibana/pull/225416","mergeCommit":{"message":"[ES|QL] Improve binary expression grouping (#225416)\n\n## Summary\n\nCloses https://github.com/elastic/kibana/issues/224990\n\nAlso:\n\n- Improves binary expression grouping with `()` parenthesis in\npretty-printer.\n- Updates binary expression precedence list.\n\n\n### Checklist\n\n- [x] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios","sha":"6d0dc4bcf7d8ed90a8634832a2aaa6b1683fc7fb"}},"sourceBranch":"main","suggestedTargetBranches":["9.1","8.19"],"targetPullRequestStates":[{"branch":"9.1","label":"v9.1.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.19","label":"v8.19.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v9.2.0","branchLabelMappingKey":"^v9.2.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/225416","number":225416,"mergeCommit":{"message":"[ES|QL] Improve binary expression grouping (#225416)\n\n## Summary\n\nCloses https://github.com/elastic/kibana/issues/224990\n\nAlso:\n\n- Improves binary expression grouping with `()` parenthesis in\npretty-printer.\n- Updates binary expression precedence list.\n\n\n### Checklist\n\n- [x] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios","sha":"6d0dc4bcf7d8ed90a8634832a2aaa6b1683fc7fb"}}]}] BACKPORT--> Co-authored-by: Vadim Kibana <[email protected]>
1 parent 91b9343 commit 3a4a533

File tree

24 files changed

+471
-230
lines changed

24 files changed

+471
-230
lines changed

src/platform/packages/shared/kbn-esql-ast/index.ts

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,7 @@ export type {
3232
ESQLAstChangePointCommand,
3333
} from './src/types';
3434

35-
export {
36-
isColumn,
37-
isDoubleLiteral,
38-
isFunctionExpression,
39-
isBinaryExpression,
40-
isWhereExpression,
41-
isFieldExpression,
42-
isSource,
43-
isIdentifier,
44-
isIntegerLiteral,
45-
isLiteral,
46-
isParamLiteral,
47-
isProperNode,
48-
} from './src/ast/helpers';
35+
export * from './src/ast/is';
4936

5037
export { Builder, type AstNodeParserFields, type AstNodeTemplate } from './src/builder';
5138

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
interface JsonWalkerOptions {
11+
visitObject?: (node: Record<string, unknown>) => void;
12+
visitArray?: (node: unknown[]) => void;
13+
visitString?: (node: string) => void;
14+
visitNumber?: (node: number) => void;
15+
visitBigint?: (node: bigint) => void;
16+
visitBoolean?: (node: boolean) => void;
17+
visitNull?: () => void;
18+
visitUndefined?: () => void;
19+
}
20+
21+
const walkJson = (json: unknown, options: JsonWalkerOptions = {}) => {
22+
switch (typeof json) {
23+
case 'string': {
24+
options.visitString?.(json);
25+
break;
26+
}
27+
case 'number': {
28+
options.visitNumber?.(json);
29+
break;
30+
}
31+
case 'bigint': {
32+
options.visitBigint?.(json as bigint);
33+
break;
34+
}
35+
case 'boolean': {
36+
options.visitBoolean?.(json);
37+
break;
38+
}
39+
case 'undefined': {
40+
options.visitUndefined?.();
41+
break;
42+
}
43+
case 'object': {
44+
if (!json) {
45+
options.visitNull?.();
46+
} else if (Array.isArray(json)) {
47+
options.visitArray?.(json);
48+
const length = json.length;
49+
50+
for (let i = 0; i < length; i++) {
51+
walkJson(json[i], options);
52+
}
53+
} else {
54+
options.visitObject?.(json as Record<string, unknown>);
55+
const values = Object.values(json as Record<string, unknown>);
56+
const length = values.length;
57+
58+
for (let i = 0; i < length; i++) {
59+
const value = values[i];
60+
walkJson(value, options);
61+
}
62+
}
63+
}
64+
}
65+
};

src/platform/packages/shared/kbn-esql-ast/src/ast/constants.ts

Lines changed: 0 additions & 20 deletions
This file was deleted.
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
import { isBinaryExpression } from './is';
11+
import type { ESQLAstNode } from '../types';
12+
13+
/**
14+
* The group name of a binary expression. Groups are ordered by precedence.
15+
*/
16+
export enum BinaryExpressionGroup {
17+
/**
18+
* No group, not a binary expression.
19+
*/
20+
none = 0,
21+
22+
/**
23+
* Binary expression, but its group is unknown.
24+
*/
25+
unknown = 1,
26+
27+
/**
28+
* Logical: `and`, `or`
29+
*/
30+
or = 10,
31+
and = 11,
32+
33+
/**
34+
* Regular expression: `like`, `not like`, `rlike`, `not rlike`
35+
*/
36+
regex = 20,
37+
38+
/**
39+
* Assignment: `=`, `:=`
40+
*/
41+
assignment = 30,
42+
43+
/**
44+
* Comparison: `==`, `=~`, `!=`, `<`, `<=`, `>`, `>=`
45+
*/
46+
comparison = 40,
47+
48+
/**
49+
* Additive: `+`, `-`
50+
*/
51+
additive = 50,
52+
53+
/**
54+
* Multiplicative: `*`, `/`, `%`
55+
*/
56+
multiplicative = 60,
57+
}
58+
59+
/**
60+
* Returns the group of a binary expression.
61+
*
62+
* @param node Any ES|QL AST node.
63+
* @returns Binary expression group or undefined if the node is
64+
* not a binary expression.
65+
*/
66+
export const binaryExpressionGroup = (node: ESQLAstNode): BinaryExpressionGroup => {
67+
if (isBinaryExpression(node)) {
68+
switch (node.name) {
69+
case '+':
70+
case '-':
71+
return BinaryExpressionGroup.additive;
72+
case '*':
73+
case '/':
74+
case '%':
75+
return BinaryExpressionGroup.multiplicative;
76+
case '=':
77+
return BinaryExpressionGroup.assignment;
78+
case '==':
79+
case '=~':
80+
case '!=':
81+
case '<':
82+
case '<=':
83+
case '>':
84+
case '>=':
85+
return BinaryExpressionGroup.comparison;
86+
case 'like':
87+
case 'not like':
88+
case 'rlike':
89+
case 'not rlike':
90+
return BinaryExpressionGroup.regex;
91+
case 'or':
92+
return BinaryExpressionGroup.or;
93+
case 'and':
94+
return BinaryExpressionGroup.and;
95+
}
96+
return BinaryExpressionGroup.unknown;
97+
}
98+
return BinaryExpressionGroup.none;
99+
};

src/platform/packages/shared/kbn-esql-ast/src/ast/helpers.ts

Lines changed: 0 additions & 137 deletions
This file was deleted.

0 commit comments

Comments
 (0)