From 3849d99a41e2e42c9a9e06b97c3affa2e75999d1 Mon Sep 17 00:00:00 2001 From: Vadim Kibana <82822460+vadimkibana@users.noreply.github.com> Date: Fri, 18 Oct 2024 16:15:29 +0200 Subject: [PATCH] [ES|QL] Open bracket parsing bug (#196241) ## Summary Closes https://github.com/elastic/kibana/issues/191683 Gracefully handles open square brackets in `FROM` command. ### Checklist Delete any items that are not applicable to this PR. - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios ### For maintainers - [x] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#_add_your_labels) --- .../src/parser/__tests__/from.test.ts | 16 ++++++++++++++++ .../src/parser/esql_ast_builder_listener.ts | 2 +- .../hooks/use_esql_index.test.ts | 10 +++++++++- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/packages/kbn-esql-ast/src/parser/__tests__/from.test.ts b/packages/kbn-esql-ast/src/parser/__tests__/from.test.ts index f2f0fded57ca5e..13d001dbc94ca3 100644 --- a/packages/kbn-esql-ast/src/parser/__tests__/from.test.ts +++ b/packages/kbn-esql-ast/src/parser/__tests__/from.test.ts @@ -187,5 +187,21 @@ describe('FROM', () => { expect(errors.length > 0).toBe(true); }); + + it('when open square bracket "[" is entered', () => { + const text = 'FROM kibana_sample_data_logs ['; + const { errors } = parse(text); + + expect(errors.length > 0).toBe(true); + expect(errors[0].message.toLowerCase().includes('metadata')).toBe(true); + }); + + it('when close square bracket "]" is entered', () => { + const text = 'FROM kibana_sample_data_logs []'; + const { errors } = parse(text); + + expect(errors.length > 0).toBe(true); + expect(errors[0].message.toLowerCase().includes('metadata')).toBe(true); + }); }); }); diff --git a/packages/kbn-esql-ast/src/parser/esql_ast_builder_listener.ts b/packages/kbn-esql-ast/src/parser/esql_ast_builder_listener.ts index de406e33aa7a5a..3959d42d8a35f2 100644 --- a/packages/kbn-esql-ast/src/parser/esql_ast_builder_listener.ts +++ b/packages/kbn-esql-ast/src/parser/esql_ast_builder_listener.ts @@ -120,7 +120,7 @@ export class ESQLAstBuilderListener implements ESQLParserListener { const metadataContext = ctx.metadata(); const metadataContent = metadataContext?.deprecated_metadata()?.metadataOption() || metadataContext?.metadataOption(); - if (metadataContent) { + if (metadataContent && metadataContent.METADATA()) { const option = createOption( metadataContent.METADATA().getText().toLowerCase(), metadataContent diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/hooks/use_esql_index.test.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/hooks/use_esql_index.test.ts index 2f5065eb113be1..eabd2050e7ba2a 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/hooks/use_esql_index.test.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/hooks/use_esql_index.test.ts @@ -27,8 +27,16 @@ describe('useEsqlIndex', () => { expect(result.current).toEqual([]); }); + it('returns indices which appear in source before syntax error', async () => { + const typeErrorCausingQuery = 'from auditbeat* [, auditbeat2*'; + + const { result } = renderHook(() => useEsqlIndex(typeErrorCausingQuery, 'esql')); + + expect(result.current).toEqual(['auditbeat*']); + }); + it('should return empty array if invalid query is causing a TypeError in ES|QL parser', async () => { - const typeErrorCausingQuery = 'from auditbeat* []'; + const typeErrorCausingQuery = 'from []'; const { result } = renderHook(() => useEsqlIndex(typeErrorCausingQuery, 'esql'));