[KQL] Use cache and other performance improvements (#93319)

* [KQL] Use cache and other performance improvements

* Fix test

* Fix jest tests

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Lukas Olson 2021-03-08 10:21:15 -07:00 committed by GitHub
parent b8df640c95
commit 2b3bac95c1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 846 additions and 196 deletions

File diff suppressed because it is too large Load diff

View file

@ -29,7 +29,7 @@ OrQuery
= &{ return errorOnLuceneSyntax; } LuceneQuery = &{ return errorOnLuceneSyntax; } LuceneQuery
/ head:AndQuery tail:(Or query:AndQuery { return query; })+ { / head:AndQuery tail:(Or query:AndQuery { return query; })+ {
const nodes = [head, ...tail]; const nodes = [head, ...tail];
const cursor = nodes.find(node => node.type === 'cursor'); const cursor = parseCursor && nodes.find(node => node.type === 'cursor');
if (cursor) return cursor; if (cursor) return cursor;
return buildFunctionNode('or', nodes); return buildFunctionNode('or', nodes);
} }
@ -38,7 +38,7 @@ OrQuery
AndQuery AndQuery
= head:NotQuery tail:(And query:NotQuery { return query; })+ { = head:NotQuery tail:(And query:NotQuery { return query; })+ {
const nodes = [head, ...tail]; const nodes = [head, ...tail];
const cursor = nodes.find(node => node.type === 'cursor'); const cursor = parseCursor && nodes.find(node => node.type === 'cursor');
if (cursor) return cursor; if (cursor) return cursor;
return buildFunctionNode('and', nodes); return buildFunctionNode('and', nodes);
} }
@ -143,7 +143,7 @@ ListOfValues
OrListOfValues OrListOfValues
= head:AndListOfValues tail:(Or partial:AndListOfValues { return partial; })+ { = head:AndListOfValues tail:(Or partial:AndListOfValues { return partial; })+ {
const nodes = [head, ...tail]; const nodes = [head, ...tail];
const cursor = nodes.find(node => node.type === 'cursor'); const cursor = parseCursor && nodes.find(node => node.type === 'cursor');
if (cursor) { if (cursor) {
return { return {
...cursor, ...cursor,
@ -157,7 +157,7 @@ OrListOfValues
AndListOfValues AndListOfValues
= head:NotListOfValues tail:(And partial:NotListOfValues { return partial; })+ { = head:NotListOfValues tail:(And partial:NotListOfValues { return partial; })+ {
const nodes = [head, ...tail]; const nodes = [head, ...tail];
const cursor = nodes.find(node => node.type === 'cursor'); const cursor = parseCursor && nodes.find(node => node.type === 'cursor');
if (cursor) { if (cursor) {
return { return {
...cursor, ...cursor,
@ -213,7 +213,7 @@ Literal "literal"
= QuotedString / UnquotedLiteral = QuotedString / UnquotedLiteral
QuotedString QuotedString
= '"' prefix:QuotedCharacter* cursor:Cursor suffix:QuotedCharacter* '"' { = &{ return parseCursor; } '"' prefix:QuotedCharacter* cursor:Cursor suffix:QuotedCharacter* '"' {
const { start, end } = location(); const { start, end } = location();
return { return {
type: 'cursor', type: 'cursor',
@ -234,7 +234,7 @@ QuotedCharacter
/ !Cursor char:[^"] { return char; } / !Cursor char:[^"] { return char; }
UnquotedLiteral UnquotedLiteral
= prefix:UnquotedCharacter* cursor:Cursor suffix:UnquotedCharacter* { = &{ return parseCursor; } prefix:UnquotedCharacter* cursor:Cursor suffix:UnquotedCharacter* {
const { start, end } = location(); const { start, end } = location();
return { return {
type: 'cursor', type: 'cursor',
@ -265,7 +265,7 @@ Wildcard
= '*' { return wildcardSymbol; } = '*' { return wildcardSymbol; }
OptionalSpace OptionalSpace
= prefix:Space* cursor:Cursor suffix:Space* { = &{ return parseCursor; } prefix:Space* cursor:Cursor suffix:Space* {
const { start, end } = location(); const { start, end } = location();
return { return {
type: 'cursor', type: 'cursor',

View file

@ -66,17 +66,13 @@ describe('kql syntax errors', () => {
it('should throw an error for unescaped quotes in a quoted string', () => { it('should throw an error for unescaped quotes in a quoted string', () => {
expect(() => { expect(() => {
fromKueryExpression('foo:"ba "r"'); fromKueryExpression('foo:"ba "r"');
}).toThrow( }).toThrow('Expected AND, OR, end of input but "r" found.\n' + 'foo:"ba "r"\n' + '---------^');
'Expected AND, OR, end of input, whitespace but "r" found.\n' + 'foo:"ba "r"\n' + '---------^'
);
}); });
it('should throw an error for unescaped special characters in literals', () => { it('should throw an error for unescaped special characters in literals', () => {
expect(() => { expect(() => {
fromKueryExpression('foo:ba:r'); fromKueryExpression('foo:ba:r');
}).toThrow( }).toThrow('Expected AND, OR, end of input but ":" found.\n' + 'foo:ba:r\n' + '------^');
'Expected AND, OR, end of input, whitespace but ":" found.\n' + 'foo:ba:r\n' + '------^'
);
}); });
it('should throw an error for range queries missing a value', () => { it('should throw an error for range queries missing a value', () => {

View file

@ -12,6 +12,7 @@ module.exports = {
dest: 'src/plugins/data/common/es_query/kuery/ast/_generated_/kuery.js', dest: 'src/plugins/data/common/es_query/kuery/ast/_generated_/kuery.js',
options: { options: {
allowedStartRules: ['start', 'Literal'], allowedStartRules: ['start', 'Literal'],
cache: true,
}, },
}, },
timelion_chain: { timelion_chain: {

View file

@ -286,9 +286,8 @@ export default function ({ getService }: FtrProviderContext) {
expect(resp.body).to.eql({ expect(resp.body).to.eql({
error: 'Bad Request', error: 'Bad Request',
message: message:
'KQLSyntaxError: Expected AND, OR, end of input, ' + 'KQLSyntaxError: Expected AND, OR, end of input but "<" found.\ndashboard.' +
'whitespace but "<" found.\ndashboard.attributes.title:foo' + 'attributes.title:foo<invalid\n------------------------------^: Bad Request',
'<invalid\n------------------------------^: Bad Request',
statusCode: 400, statusCode: 400,
}); });
})); }));