mirror of
https://github.com/elastic/kibana.git
synced 2025-06-28 03:01:21 -04:00
[ES|QL] Moves fork in tech preview (#224680)
## Summary Moves the fork command on tech preview <img width="878" alt="image" src="https://github.com/user-attachments/assets/d21d593d-f157-45e4-94aa-c97d5f3098ca" /> It also enables all the processing commands in the autocomplete except for enrich, mostly because the client side validation complains. As enrich is considered kinda deprecated I think it is ok to skip the suggestion. I will create an issue to track the client side validation problem though (Update: Added in [client side validation bugs](https://github.com/elastic/kibana/issues/192255#issuecomment-2991343277)) ### Checklist - [ ] [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
This commit is contained in:
parent
81e362ed28
commit
7c2ac235ef
12 changed files with 279 additions and 39 deletions
|
@ -52,14 +52,13 @@ import { createRowCommand } from './factories/row';
|
||||||
import { createSortCommand } from './factories/sort';
|
import { createSortCommand } from './factories/sort';
|
||||||
import { createStatsCommand } from './factories/stats';
|
import { createStatsCommand } from './factories/stats';
|
||||||
import { createWhereCommand } from './factories/where';
|
import { createWhereCommand } from './factories/where';
|
||||||
|
import { createMvExpandCommand } from './factories/mv_expand';
|
||||||
|
import { createKeepCommand } from './factories/keep';
|
||||||
|
import { createDropCommand } from './factories/drop';
|
||||||
|
import { createRenameCommand } from './factories/rename';
|
||||||
|
import { createSampleCommand } from './factories/sample';
|
||||||
import { getPosition } from './helpers';
|
import { getPosition } from './helpers';
|
||||||
import {
|
import { collectAllAggFields, visitByOption } from './walkers';
|
||||||
collectAllAggFields,
|
|
||||||
collectAllColumnIdentifiers,
|
|
||||||
getConstant,
|
|
||||||
visitByOption,
|
|
||||||
visitRenameClauses,
|
|
||||||
} from './walkers';
|
|
||||||
import { createTimeseriesCommand } from './factories/timeseries';
|
import { createTimeseriesCommand } from './factories/timeseries';
|
||||||
import { createRerankCommand } from './factories/rerank';
|
import { createRerankCommand } from './factories/rerank';
|
||||||
import { createEnrichCommand } from './factories/enrich';
|
import { createEnrichCommand } from './factories/enrich';
|
||||||
|
@ -216,9 +215,11 @@ export class ESQLAstBuilderListener implements ESQLParserListener {
|
||||||
* @param ctx the parse tree
|
* @param ctx the parse tree
|
||||||
*/
|
*/
|
||||||
exitKeepCommand(ctx: KeepCommandContext) {
|
exitKeepCommand(ctx: KeepCommandContext) {
|
||||||
const command = createCommand('keep', ctx);
|
if (this.inFork) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const command = createKeepCommand(ctx);
|
||||||
this.ast.push(command);
|
this.ast.push(command);
|
||||||
command.args.push(...collectAllColumnIdentifiers(ctx));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -226,9 +227,11 @@ export class ESQLAstBuilderListener implements ESQLParserListener {
|
||||||
* @param ctx the parse tree
|
* @param ctx the parse tree
|
||||||
*/
|
*/
|
||||||
exitDropCommand(ctx: DropCommandContext) {
|
exitDropCommand(ctx: DropCommandContext) {
|
||||||
const command = createCommand('drop', ctx);
|
if (this.inFork) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const command = createDropCommand(ctx);
|
||||||
this.ast.push(command);
|
this.ast.push(command);
|
||||||
command.args.push(...collectAllColumnIdentifiers(ctx));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -236,9 +239,11 @@ export class ESQLAstBuilderListener implements ESQLParserListener {
|
||||||
* @param ctx the parse tree
|
* @param ctx the parse tree
|
||||||
*/
|
*/
|
||||||
exitRenameCommand(ctx: RenameCommandContext) {
|
exitRenameCommand(ctx: RenameCommandContext) {
|
||||||
const command = createCommand('rename', ctx);
|
if (this.inFork) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const command = createRenameCommand(ctx);
|
||||||
this.ast.push(command);
|
this.ast.push(command);
|
||||||
command.args.push(...visitRenameClauses(ctx.renameClause_list()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -270,9 +275,11 @@ export class ESQLAstBuilderListener implements ESQLParserListener {
|
||||||
* @param ctx the parse tree
|
* @param ctx the parse tree
|
||||||
*/
|
*/
|
||||||
exitMvExpandCommand(ctx: MvExpandCommandContext) {
|
exitMvExpandCommand(ctx: MvExpandCommandContext) {
|
||||||
const command = createCommand('mv_expand', ctx);
|
if (this.inFork) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const command = createMvExpandCommand(ctx);
|
||||||
this.ast.push(command);
|
this.ast.push(command);
|
||||||
command.args.push(...collectAllColumnIdentifiers(ctx));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -289,6 +296,9 @@ export class ESQLAstBuilderListener implements ESQLParserListener {
|
||||||
* @param ctx the parse tree
|
* @param ctx the parse tree
|
||||||
*/
|
*/
|
||||||
exitEnrichCommand(ctx: EnrichCommandContext) {
|
exitEnrichCommand(ctx: EnrichCommandContext) {
|
||||||
|
if (this.inFork) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const command = createEnrichCommand(ctx);
|
const command = createEnrichCommand(ctx);
|
||||||
|
|
||||||
this.ast.push(command);
|
this.ast.push(command);
|
||||||
|
@ -306,6 +316,9 @@ export class ESQLAstBuilderListener implements ESQLParserListener {
|
||||||
* @param ctx the parse tree
|
* @param ctx the parse tree
|
||||||
*/
|
*/
|
||||||
exitJoinCommand(ctx: JoinCommandContext): void {
|
exitJoinCommand(ctx: JoinCommandContext): void {
|
||||||
|
if (this.inFork) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const command = createJoinCommand(ctx);
|
const command = createJoinCommand(ctx);
|
||||||
|
|
||||||
this.ast.push(command);
|
this.ast.push(command);
|
||||||
|
@ -378,15 +391,11 @@ export class ESQLAstBuilderListener implements ESQLParserListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
exitSampleCommand(ctx: SampleCommandContext): void {
|
exitSampleCommand(ctx: SampleCommandContext): void {
|
||||||
const command = createCommand('sample', ctx);
|
if (this.inFork) {
|
||||||
this.ast.push(command);
|
return;
|
||||||
|
|
||||||
if (ctx.constant()) {
|
|
||||||
const probability = getConstant(ctx.constant());
|
|
||||||
if (probability != null) {
|
|
||||||
command.args.push(probability);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
const command = createSampleCommand(ctx);
|
||||||
|
this.ast.push(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the "Elastic License
|
||||||
|
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
|
||||||
|
* Public License v 1"; you may not use this file except in compliance with, at
|
||||||
|
* your election, the "Elastic License 2.0", the "GNU Affero General Public
|
||||||
|
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { DropCommandContext } from '../../antlr/esql_parser';
|
||||||
|
import { ESQLCommand } from '../../types';
|
||||||
|
import { createCommand } from '../factories';
|
||||||
|
import { collectAllColumnIdentifiers } from '../walkers';
|
||||||
|
|
||||||
|
export const createDropCommand = (ctx: DropCommandContext): ESQLCommand<'drop'> => {
|
||||||
|
const command = createCommand('drop', ctx);
|
||||||
|
const identifiers = collectAllColumnIdentifiers(ctx);
|
||||||
|
|
||||||
|
command.args.push(...identifiers);
|
||||||
|
|
||||||
|
return command;
|
||||||
|
};
|
|
@ -26,6 +26,13 @@ import { createWhereCommand } from './where';
|
||||||
import { createCompletionCommand } from './completion';
|
import { createCompletionCommand } from './completion';
|
||||||
import { createChangePointCommand } from './change_point';
|
import { createChangePointCommand } from './change_point';
|
||||||
import { createGrokCommand } from './grok';
|
import { createGrokCommand } from './grok';
|
||||||
|
import { createKeepCommand } from './keep';
|
||||||
|
import { createMvExpandCommand } from './mv_expand';
|
||||||
|
import { createDropCommand } from './drop';
|
||||||
|
import { createRenameCommand } from './rename';
|
||||||
|
import { createEnrichCommand } from './enrich';
|
||||||
|
import { createSampleCommand } from './sample';
|
||||||
|
import { createJoinCommand } from './join';
|
||||||
|
|
||||||
export const createForkCommand = (ctx: ForkCommandContext): ESQLCommand<'fork'> => {
|
export const createForkCommand = (ctx: ForkCommandContext): ESQLCommand<'fork'> => {
|
||||||
const command = createCommand<'fork'>('fork', ctx);
|
const command = createCommand<'fork'>('fork', ctx);
|
||||||
|
@ -113,4 +120,39 @@ function visitForkSubQueryProcessingCommandContext(ctx: ForkSubQueryProcessingCo
|
||||||
if (completionCtx) {
|
if (completionCtx) {
|
||||||
return createCompletionCommand(completionCtx);
|
return createCompletionCommand(completionCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const mvExpandCtx = ctx.processingCommand().mvExpandCommand();
|
||||||
|
if (mvExpandCtx) {
|
||||||
|
return createMvExpandCommand(mvExpandCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
const keepCtx = ctx.processingCommand().keepCommand();
|
||||||
|
if (keepCtx) {
|
||||||
|
return createKeepCommand(keepCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
const dropCtx = ctx.processingCommand().dropCommand();
|
||||||
|
if (dropCtx) {
|
||||||
|
return createDropCommand(dropCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
const renameCtx = ctx.processingCommand().renameCommand();
|
||||||
|
if (renameCtx) {
|
||||||
|
return createRenameCommand(renameCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
const enrichCtx = ctx.processingCommand().enrichCommand();
|
||||||
|
if (enrichCtx) {
|
||||||
|
return createEnrichCommand(enrichCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
const sampleCtx = ctx.processingCommand().sampleCommand();
|
||||||
|
if (sampleCtx) {
|
||||||
|
return createSampleCommand(sampleCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
const joinCtx = ctx.processingCommand().joinCommand();
|
||||||
|
if (joinCtx) {
|
||||||
|
return createJoinCommand(joinCtx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the "Elastic License
|
||||||
|
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
|
||||||
|
* Public License v 1"; you may not use this file except in compliance with, at
|
||||||
|
* your election, the "Elastic License 2.0", the "GNU Affero General Public
|
||||||
|
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { KeepCommandContext } from '../../antlr/esql_parser';
|
||||||
|
import { ESQLCommand } from '../../types';
|
||||||
|
import { createCommand } from '../factories';
|
||||||
|
import { collectAllColumnIdentifiers } from '../walkers';
|
||||||
|
|
||||||
|
export const createKeepCommand = (ctx: KeepCommandContext): ESQLCommand<'keep'> => {
|
||||||
|
const command = createCommand('keep', ctx);
|
||||||
|
const identifiers = collectAllColumnIdentifiers(ctx);
|
||||||
|
|
||||||
|
command.args.push(...identifiers);
|
||||||
|
|
||||||
|
return command;
|
||||||
|
};
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the "Elastic License
|
||||||
|
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
|
||||||
|
* Public License v 1"; you may not use this file except in compliance with, at
|
||||||
|
* your election, the "Elastic License 2.0", the "GNU Affero General Public
|
||||||
|
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { MvExpandCommandContext } from '../../antlr/esql_parser';
|
||||||
|
import { ESQLCommand } from '../../types';
|
||||||
|
import { createCommand } from '../factories';
|
||||||
|
import { collectAllColumnIdentifiers } from '../walkers';
|
||||||
|
|
||||||
|
export const createMvExpandCommand = (ctx: MvExpandCommandContext): ESQLCommand<'mv_expand'> => {
|
||||||
|
const command = createCommand('mv_expand', ctx);
|
||||||
|
const identifiers = collectAllColumnIdentifiers(ctx);
|
||||||
|
|
||||||
|
command.args.push(...identifiers);
|
||||||
|
|
||||||
|
return command;
|
||||||
|
};
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the "Elastic License
|
||||||
|
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
|
||||||
|
* Public License v 1"; you may not use this file except in compliance with, at
|
||||||
|
* your election, the "Elastic License 2.0", the "GNU Affero General Public
|
||||||
|
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { RenameCommandContext } from '../../antlr/esql_parser';
|
||||||
|
import { ESQLCommand } from '../../types';
|
||||||
|
import { createCommand } from '../factories';
|
||||||
|
import { visitRenameClauses } from '../walkers';
|
||||||
|
|
||||||
|
export const createRenameCommand = (ctx: RenameCommandContext): ESQLCommand<'rename'> => {
|
||||||
|
const command = createCommand('rename', ctx);
|
||||||
|
const renameArgs = visitRenameClauses(ctx.renameClause_list());
|
||||||
|
|
||||||
|
command.args.push(...renameArgs);
|
||||||
|
|
||||||
|
return command;
|
||||||
|
};
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the "Elastic License
|
||||||
|
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
|
||||||
|
* Public License v 1"; you may not use this file except in compliance with, at
|
||||||
|
* your election, the "Elastic License 2.0", the "GNU Affero General Public
|
||||||
|
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { SampleCommandContext } from '../../antlr/esql_parser';
|
||||||
|
import { ESQLCommand } from '../../types';
|
||||||
|
import { createCommand } from '../factories';
|
||||||
|
import { getConstant } from '../walkers';
|
||||||
|
|
||||||
|
export const createSampleCommand = (ctx: SampleCommandContext): ESQLCommand<'sample'> => {
|
||||||
|
const command = createCommand('sample', ctx);
|
||||||
|
if (ctx.constant()) {
|
||||||
|
const probability = getConstant(ctx.constant());
|
||||||
|
if (probability != null) {
|
||||||
|
command.args.push(probability);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return command;
|
||||||
|
};
|
|
@ -8,7 +8,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Location } from '../../definitions/types';
|
import { Location } from '../../definitions/types';
|
||||||
import { ESQL_STRING_TYPES } from '../../shared/esql_types';
|
import { ESQL_STRING_TYPES, ESQL_NUMBER_TYPES } from '../../shared/esql_types';
|
||||||
import { EXPECTED_FIELD_AND_FUNCTION_SUGGESTIONS } from './autocomplete.command.sort.test';
|
import { EXPECTED_FIELD_AND_FUNCTION_SUGGESTIONS } from './autocomplete.command.sort.test';
|
||||||
import { AVG_TYPES, EXPECTED_FOR_EMPTY_EXPRESSION } from './autocomplete.command.stats.test';
|
import { AVG_TYPES, EXPECTED_FOR_EMPTY_EXPRESSION } from './autocomplete.command.stats.test';
|
||||||
import {
|
import {
|
||||||
|
@ -18,9 +18,11 @@ import {
|
||||||
import {
|
import {
|
||||||
AssertSuggestionsFn,
|
AssertSuggestionsFn,
|
||||||
SuggestFn,
|
SuggestFn,
|
||||||
|
attachTriggerCommand,
|
||||||
getFieldNamesByType,
|
getFieldNamesByType,
|
||||||
getFunctionSignaturesByReturnType,
|
getFunctionSignaturesByReturnType,
|
||||||
setup,
|
setup,
|
||||||
|
lookupIndexFields,
|
||||||
} from './helpers';
|
} from './helpers';
|
||||||
|
|
||||||
describe('autocomplete.suggest', () => {
|
describe('autocomplete.suggest', () => {
|
||||||
|
@ -56,6 +58,13 @@ describe('autocomplete.suggest', () => {
|
||||||
'STATS ',
|
'STATS ',
|
||||||
'EVAL ',
|
'EVAL ',
|
||||||
'GROK ',
|
'GROK ',
|
||||||
|
'CHANGE_POINT ',
|
||||||
|
'MV_EXPAND ',
|
||||||
|
'DROP ',
|
||||||
|
'KEEP ',
|
||||||
|
'RENAME ',
|
||||||
|
'SAMPLE ',
|
||||||
|
'LOOKUP JOIN ',
|
||||||
];
|
];
|
||||||
|
|
||||||
it('suggests FORK sub commands in an open branch', async () => {
|
it('suggests FORK sub commands in an open branch', async () => {
|
||||||
|
@ -108,6 +117,75 @@ describe('autocomplete.suggest', () => {
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('keep', async () => {
|
||||||
|
await assertSuggestions('FROM a | FORK (KEEP /)', getFieldNamesByType('any'));
|
||||||
|
await assertSuggestions('FROM a | FORK (KEEP integerField /)', [',', '| ']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('drop', async () => {
|
||||||
|
await assertSuggestions('FROM a | FORK (DROP /)', getFieldNamesByType('any'));
|
||||||
|
await assertSuggestions('FROM a | FORK (DROP integerField /)', [',', '| ']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('mv_expand', async () => {
|
||||||
|
await assertSuggestions(
|
||||||
|
'FROM a | FORK (MV_EXPAND /)',
|
||||||
|
getFieldNamesByType('any').map((name) => `${name} `)
|
||||||
|
);
|
||||||
|
await assertSuggestions('FROM a | FORK (MV_EXPAND integerField /)', ['| ']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('sample', async () => {
|
||||||
|
await assertSuggestions('FROM a | FORK (SAMPLE /)', ['.001 ', '.01 ', '.1 ']);
|
||||||
|
await assertSuggestions('FROM a | FORK (SAMPLE 0.01 /)', ['| ']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('rename', async () => {
|
||||||
|
await assertSuggestions('FROM a | FORK (RENAME /)', [
|
||||||
|
'col0 = ',
|
||||||
|
...getFieldNamesByType('any').map((field) => field + ' '),
|
||||||
|
]);
|
||||||
|
await assertSuggestions('FROM a | FORK (RENAME textField /)', ['AS ']);
|
||||||
|
await assertSuggestions('FROM a | FORK (RENAME field /)', ['= ']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('change_point', async () => {
|
||||||
|
await assertSuggestions(
|
||||||
|
`FROM a | FORK (CHANGE_POINT /`,
|
||||||
|
getFieldNamesByType(ESQL_NUMBER_TYPES).map((v) => `${v} `)
|
||||||
|
);
|
||||||
|
await assertSuggestions(
|
||||||
|
`FROM a | FORK (CHANGE_POINT value /)`,
|
||||||
|
['ON ', 'AS ', '| '].map(attachTriggerCommand)
|
||||||
|
);
|
||||||
|
await assertSuggestions(
|
||||||
|
`FROM a | FORK (CHANGE_POINT value on /)`,
|
||||||
|
getFieldNamesByType('any').map((v) => `${v} `)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('lookup join', async () => {
|
||||||
|
await assertSuggestions('FROM a | FORK (LOOKUP JOIN /)', [
|
||||||
|
'join_index ',
|
||||||
|
'join_index_with_alias ',
|
||||||
|
'lookup_index ',
|
||||||
|
'join_index_alias_1 $0',
|
||||||
|
'join_index_alias_2 $0',
|
||||||
|
]);
|
||||||
|
const suggestions = await suggest('FROM a | FORK (LOOKUP JOIN join_index ON /)');
|
||||||
|
const labels = suggestions.map((s) => s.text.trim()).sort();
|
||||||
|
const expected = getFieldNamesByType('any')
|
||||||
|
.sort()
|
||||||
|
.map((field) => field.trim());
|
||||||
|
|
||||||
|
for (const { name } of lookupIndexFields) {
|
||||||
|
expected.push(name.trim());
|
||||||
|
}
|
||||||
|
expected.sort();
|
||||||
|
|
||||||
|
expect(labels).toEqual(expected);
|
||||||
|
});
|
||||||
|
|
||||||
describe('stats', () => {
|
describe('stats', () => {
|
||||||
it('suggests for empty expression', async () => {
|
it('suggests for empty expression', async () => {
|
||||||
await assertSuggestions('FROM a | FORK (STATS /)', EXPECTED_FOR_EMPTY_EXPRESSION);
|
await assertSuggestions('FROM a | FORK (STATS /)', EXPECTED_FOR_EMPTY_EXPRESSION);
|
||||||
|
|
|
@ -8,12 +8,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { CommandSuggestParams } from '../../../definitions/types';
|
import { CommandSuggestParams } from '../../../definitions/types';
|
||||||
import {
|
import { getLastNonWhitespaceChar, isColumnItem } from '../../../shared/helpers';
|
||||||
findPreviousWord,
|
|
||||||
getLastNonWhitespaceChar,
|
|
||||||
isColumnItem,
|
|
||||||
noCaseCompare,
|
|
||||||
} from '../../../shared/helpers';
|
|
||||||
import type { SuggestionRawDefinition } from '../../types';
|
import type { SuggestionRawDefinition } from '../../types';
|
||||||
import { commaCompleteItem, pipeCompleteItem } from '../../complete_items';
|
import { commaCompleteItem, pipeCompleteItem } from '../../complete_items';
|
||||||
import { handleFragment } from '../../helper';
|
import { handleFragment } from '../../helper';
|
||||||
|
@ -28,7 +23,7 @@ export async function suggest({
|
||||||
if (
|
if (
|
||||||
/\s/.test(innerText[innerText.length - 1]) &&
|
/\s/.test(innerText[innerText.length - 1]) &&
|
||||||
getLastNonWhitespaceChar(innerText) !== ',' &&
|
getLastNonWhitespaceChar(innerText) !== ',' &&
|
||||||
!noCaseCompare(findPreviousWord(innerText), 'drop')
|
!/drop\s+\S*$/i.test(innerText)
|
||||||
) {
|
) {
|
||||||
return [pipeCompleteItem, commaCompleteItem];
|
return [pipeCompleteItem, commaCompleteItem];
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,14 @@ const FORK_AVAILABLE_COMMANDS = [
|
||||||
'eval',
|
'eval',
|
||||||
'completion',
|
'completion',
|
||||||
'grok',
|
'grok',
|
||||||
|
'change_point',
|
||||||
|
'mv_expand',
|
||||||
|
'keep',
|
||||||
|
'drop',
|
||||||
|
'rename',
|
||||||
|
'sample',
|
||||||
|
'join',
|
||||||
|
// 'enrich', // not suggesting enrich for now, there are client side validation issues
|
||||||
];
|
];
|
||||||
|
|
||||||
export async function suggest(
|
export async function suggest(
|
||||||
|
|
|
@ -8,12 +8,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { CommandSuggestParams } from '../../../definitions/types';
|
import { CommandSuggestParams } from '../../../definitions/types';
|
||||||
import {
|
import { getLastNonWhitespaceChar, isColumnItem } from '../../../shared/helpers';
|
||||||
findPreviousWord,
|
|
||||||
getLastNonWhitespaceChar,
|
|
||||||
isColumnItem,
|
|
||||||
noCaseCompare,
|
|
||||||
} from '../../../shared/helpers';
|
|
||||||
import type { SuggestionRawDefinition } from '../../types';
|
import type { SuggestionRawDefinition } from '../../types';
|
||||||
import { commaCompleteItem, pipeCompleteItem } from '../../complete_items';
|
import { commaCompleteItem, pipeCompleteItem } from '../../complete_items';
|
||||||
import { handleFragment } from '../../helper';
|
import { handleFragment } from '../../helper';
|
||||||
|
@ -28,7 +23,7 @@ export async function suggest({
|
||||||
if (
|
if (
|
||||||
/\s/.test(innerText[innerText.length - 1]) &&
|
/\s/.test(innerText[innerText.length - 1]) &&
|
||||||
getLastNonWhitespaceChar(innerText) !== ',' &&
|
getLastNonWhitespaceChar(innerText) !== ',' &&
|
||||||
!noCaseCompare(findPreviousWord(innerText), 'keep')
|
!/keep\s+\S*$/i.test(innerText)
|
||||||
) {
|
) {
|
||||||
return [pipeCompleteItem, commaCompleteItem];
|
return [pipeCompleteItem, commaCompleteItem];
|
||||||
}
|
}
|
||||||
|
|
|
@ -680,7 +680,7 @@ export const commandDefinitions: Array<CommandDefinition<any>> = [
|
||||||
fieldsSuggestionsAfter: fieldsSuggestionsAfterChangePoint,
|
fieldsSuggestionsAfter: fieldsSuggestionsAfterChangePoint,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
hidden: true,
|
hidden: false,
|
||||||
name: 'fork',
|
name: 'fork',
|
||||||
preview: true,
|
preview: true,
|
||||||
description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.forkDoc', {
|
description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.forkDoc', {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue