Skip to content

Commit

Permalink
[ES|QL] Separate ROW and SHOW autocomplete routines (elastic#210934)
Browse files Browse the repository at this point in the history
## Summary

Part of elastic#195418

Gives `ROW` and `SHOW` autocomplete logic its own home 🏡

### Checklist

- [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

### Identify risks

- [ ] As with any refactor, there's a possibility this will introduce a
regression in the behavior of FROM. However, all automated tests are
passing and I have tested the behavior manually and can detect no
regression.

---------

Co-authored-by: kibanamachine <[email protected]>
Co-authored-by: Stratoula Kalafateli <[email protected]>
  • Loading branch information
3 people authored Feb 13, 2025
1 parent 526ff05 commit 79f1144
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* 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 { getNewVariableSuggestion } from '../factories';
import { attachTriggerCommand, getFunctionSignaturesByReturnType, setup } from './helpers';

describe('autocomplete.suggest', () => {
describe('ROW column1 = value1[, ..., columnN = valueN]', () => {
const functions = getFunctionSignaturesByReturnType('row', 'any', { scalar: true });
it('suggests functions and an assignment for new expressions', async () => {
const { assertSuggestions } = await setup();
const expectedSuggestions = [getNewVariableSuggestion('var0'), ...functions];

await assertSuggestions('ROW /', expectedSuggestions);
await assertSuggestions('ROW foo = "bar", /', expectedSuggestions);
});

it('suggests only functions after an assignment', async () => {
const { assertSuggestions } = await setup();
await assertSuggestions('ROW var0 = /', functions);
});

it('suggests a comma and a pipe after a complete expression', async () => {
const { assertSuggestions } = await setup();
const expected = [', ', '| '].map(attachTriggerCommand);

await assertSuggestions('ROW var0 = 23 /', expected);
await assertSuggestions('ROW ABS(23) /', expected);
await assertSuggestions('ROW ABS(23), var0=234 /', expected);
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* 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 { attachTriggerCommand, setup } from './helpers';

describe('autocomplete.suggest', () => {
describe('SHOW INFO', () => {
it('suggests INFO', async () => {
const { assertSuggestions } = await setup();

await assertSuggestions('SHOW /', ['INFO']);
});

it('suggests pipe after INFO', async () => {
const { assertSuggestions } = await setup();

await assertSuggestions('SHOW INFO /', [attachTriggerCommand('| ')]);
await assertSuggestions('SHOW INFO\t/', [attachTriggerCommand('| ')]);
await assertSuggestions('SHOW info /', [attachTriggerCommand('| ')]);
});

it('suggests nothing after a random word', async () => {
const { assertSuggestions } = await setup();

await assertSuggestions('SHOW lolz /', []);
await assertSuggestions('SHOW inof /', []);
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* 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 { isRestartingExpression } from '../../../shared/helpers';
import { CommandSuggestParams } from '../../../definitions/types';

import type { SuggestionRawDefinition } from '../../types';
import {
TRIGGER_SUGGESTION_COMMAND,
getFunctionSuggestions,
getNewVariableSuggestion,
} from '../../factories';
import { commaCompleteItem, pipeCompleteItem } from '../../complete_items';

export async function suggest({
getSuggestedVariableName,
command,
innerText,
}: CommandSuggestParams<'row'>): Promise<SuggestionRawDefinition[]> {
// ROW var0 = /
if (/=\s*$/.test(innerText)) {
return getFunctionSuggestions({ command: 'row' });
}

// ROW var0 = 23 /
else if (command.args.length > 0 && !isRestartingExpression(innerText)) {
return [
{ ...pipeCompleteItem, command: TRIGGER_SUGGESTION_COMMAND },
{ ...commaCompleteItem, text: ', ', command: TRIGGER_SUGGESTION_COMMAND },
];
}

// ROW /
// ROW foo = "bar", /
return [
getNewVariableSuggestion(getSuggestedVariableName()),
...getFunctionSuggestions({ command: 'row' }),
];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* 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 { i18n } from '@kbn/i18n';
import { CommandSuggestParams } from '../../../definitions/types';
import type { SuggestionRawDefinition } from '../../types';
import { pipeCompleteItem } from '../../complete_items';
import { TRIGGER_SUGGESTION_COMMAND } from '../../factories';

export async function suggest({
innerText,
}: CommandSuggestParams<'show'>): Promise<SuggestionRawDefinition[]> {
// SHOW INFO /
if (/INFO\s+$/i.test(innerText)) {
return [{ ...pipeCompleteItem, command: TRIGGER_SUGGESTION_COMMAND }];
}
// SHOW INSOF /
else if (/SHOW\s+\S+\s+$/i.test(innerText)) {
return [];
}
// SHOW /
return [
{
text: 'INFO',
detail: i18n.translate('kbn-esql-validation-autocomplete.esql.show.info.detail', {
defaultMessage: 'Get information about the Elasticsearch cluster.',
}),
kind: 'Method',
label: 'INFO',
},
];
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ import { suggest as suggestForStats } from '../autocomplete/commands/stats';
import { suggest as suggestForWhere } from '../autocomplete/commands/where';
import { suggest as suggestForJoin } from '../autocomplete/commands/join';
import { suggest as suggestForFrom } from '../autocomplete/commands/from';
import { suggest as suggestForRow } from '../autocomplete/commands/row';
import { suggest as suggestForShow } from '../autocomplete/commands/show';

const statsValidator = (command: ESQLCommand) => {
const messages: ESQLMessage[] = [];
Expand Down Expand Up @@ -191,12 +193,13 @@ export const commandDefinitions: Array<CommandDefinition<any>> = [
defaultMessage:
'Produces a row with one or more columns with values that you specify. This can be useful for testing.',
}),
examples: ['row a=1', 'row a=1, b=2'],
examples: ['ROW a=1', 'ROW a=1, b=2'],
signature: {
multipleParams: true,
// syntax check already validates part of this
params: [{ name: 'assignment', type: 'any' }],
},
suggest: suggestForRow,
options: [],
modes: [],
},
Expand All @@ -220,13 +223,14 @@ export const commandDefinitions: Array<CommandDefinition<any>> = [
description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.showDoc', {
defaultMessage: 'Returns information about the deployment and its capabilities',
}),
examples: ['show info'],
examples: ['SHOW INFO'],
options: [],
modes: [],
signature: {
multipleParams: false,
params: [{ name: 'functions', type: 'function' }],
},
suggest: suggestForShow,
},
{
name: 'metrics',
Expand Down

0 comments on commit 79f1144

Please sign in to comment.