Skip to content

Commit 8203ebf

Browse files
committed
sharing expression suggestion routine
1 parent 87594e1 commit 8203ebf

File tree

5 files changed

+38
-317
lines changed

5 files changed

+38
-317
lines changed

src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/commands/eval/index.ts

Lines changed: 11 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -7,159 +7,17 @@
77
* License v3.0 only", or the "Server Side Public License, v 1".
88
*/
99

10-
import { ESQLSource } from '@kbn/esql-ast';
11-
import {
12-
findFinalWord,
13-
findPreviousWord,
14-
isSingleItem,
15-
unescapeColumnName,
16-
} from '../../../shared/helpers';
10+
import type { ESQLSingleAstItem } from '@kbn/esql-ast';
1711
import { CommandSuggestParams } from '../../../definitions/types';
1812
import type { SuggestionRawDefinition } from '../../types';
19-
import {
20-
Position,
21-
buildMatchingFieldsDefinition,
22-
getPosition,
23-
modeSuggestions,
24-
noPoliciesAvailableSuggestion,
25-
onSuggestion,
26-
withSuggestion,
27-
} from './util';
28-
import { commaCompleteItem, pipeCompleteItem } from '../../complete_items';
29-
import {
30-
TRIGGER_SUGGESTION_COMMAND,
31-
buildFieldsDefinitions,
32-
getNewVariableSuggestion,
33-
getOperatorSuggestions,
34-
} from '../../factories';
35-
36-
export async function suggest({
37-
innerText,
38-
command,
39-
getPolicies,
40-
getPolicyMetadata,
41-
getAllColumnNames,
42-
getSuggestedVariableName,
43-
}: CommandSuggestParams<'enrich'>): Promise<SuggestionRawDefinition[]> {
44-
const pos = getPosition(innerText, command);
45-
46-
const policyName = (
47-
command.args.find((arg) => isSingleItem(arg) && arg.type === 'source') as ESQLSource | undefined
48-
)?.name;
49-
50-
const getFieldSuggestionsForWithClause = async () => {
51-
if (!policyName) {
52-
return [];
53-
}
54-
55-
const policyMetadata = await getPolicyMetadata(policyName);
56-
if (!policyMetadata) {
57-
return [];
58-
}
59-
60-
const fieldSuggestions = buildFieldsDefinitions(policyMetadata.enrichFields, false);
61-
62-
const lastWord = findFinalWord(innerText);
63-
if (lastWord) {
64-
// ENRICH ... WITH a <suggest>
65-
const rangeToReplace = {
66-
start: innerText.length - lastWord.length + 1,
67-
end: innerText.length + 1,
68-
};
69-
fieldSuggestions.forEach((s) => {
70-
s.rangeToReplace = rangeToReplace;
71-
});
72-
}
73-
74-
return fieldSuggestions;
75-
};
76-
77-
switch (pos) {
78-
case Position.MODE:
79-
return modeSuggestions;
80-
81-
case Position.POLICY: {
82-
const policies = await getPolicies();
83-
const lastWord = findFinalWord(innerText);
84-
if (lastWord !== '') {
85-
policies.forEach((policySuggestion) => {
86-
policySuggestion.rangeToReplace = {
87-
start: innerText.length - lastWord.length + 1,
88-
end: innerText.length + 1,
89-
};
90-
});
91-
}
92-
return policies.length ? policies : [noPoliciesAvailableSuggestion];
93-
}
94-
95-
case Position.AFTER_POLICY:
96-
return [onSuggestion, withSuggestion, pipeCompleteItem];
97-
98-
case Position.MATCH_FIELD: {
99-
if (!policyName) {
100-
return [];
101-
}
102-
103-
const policyMetadata = await getPolicyMetadata(policyName);
104-
if (!policyMetadata) {
105-
return [];
106-
}
107-
108-
return buildMatchingFieldsDefinition(policyMetadata.matchField, getAllColumnNames());
109-
}
110-
111-
case Position.AFTER_ON_CLAUSE:
112-
return [withSuggestion, pipeCompleteItem];
113-
114-
case Position.WITH_NEW_CLAUSE: {
115-
if (!policyName) {
116-
return [];
117-
}
118-
119-
const policyMetadata = await getPolicyMetadata(policyName);
120-
if (!policyMetadata) {
121-
return [];
122-
}
123-
124-
const suggestions: SuggestionRawDefinition[] = [];
125-
suggestions.push(
126-
getNewVariableSuggestion(getSuggestedVariableName(policyMetadata.enrichFields))
127-
);
128-
suggestions.push(...(await getFieldSuggestionsForWithClause()));
129-
return suggestions;
130-
}
131-
132-
case Position.WITH_AFTER_FIRST_WORD: {
133-
if (!policyName) {
134-
return [];
135-
}
136-
const policyMetadata = await getPolicyMetadata(policyName);
137-
138-
if (!policyMetadata) {
139-
return [];
140-
}
141-
142-
const word = findPreviousWord(innerText);
143-
if (policyMetadata.enrichFields.includes(unescapeColumnName(word))) {
144-
// complete field name
145-
return [pipeCompleteItem, { ...commaCompleteItem, command: TRIGGER_SUGGESTION_COMMAND }];
146-
} else {
147-
// not recognized as a field name, assume new user-defined column name
148-
return getOperatorSuggestions({ command: 'enrich' });
149-
}
150-
}
151-
152-
case Position.WITH_AFTER_ASSIGNMENT: {
153-
const suggestions: SuggestionRawDefinition[] = [];
154-
suggestions.push(...(await getFieldSuggestionsForWithClause()));
155-
return suggestions;
156-
}
157-
158-
case Position.WITH_AFTER_COMPLETE_CLAUSE: {
159-
return [pipeCompleteItem, { ...commaCompleteItem, command: TRIGGER_SUGGESTION_COMMAND }];
160-
}
161-
162-
default:
163-
return [];
164-
}
13+
import { suggestForExpression } from '../where';
14+
15+
export async function suggest(
16+
params: CommandSuggestParams<'eval'>
17+
): Promise<SuggestionRawDefinition[]> {
18+
const expressionRoot = params.command.args[0] as ESQLSingleAstItem | undefined;
19+
return suggestForExpression({
20+
...params,
21+
expressionRoot,
22+
});
16523
}

src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/commands/eval/util.ts

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

src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/commands/where/index.ts

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,31 @@ import {
2727
UNSUPPORTED_COMMANDS_BEFORE_QSTR,
2828
} from '../../../shared/constants';
2929

30-
export async function suggest({
30+
export async function suggest(
31+
params: CommandSuggestParams<'where'>
32+
): Promise<SuggestionRawDefinition[]> {
33+
const expressionRoot = params.command.args[0] as ESQLSingleAstItem | undefined;
34+
return suggestForExpression({
35+
...params,
36+
expressionRoot,
37+
});
38+
}
39+
40+
export async function suggestForExpression({
41+
expressionRoot,
3142
innerText,
32-
command,
33-
getColumnsByType,
3443
getExpressionType,
44+
getColumnsByType,
3545
previousCommands,
36-
}: CommandSuggestParams<'where'>): Promise<SuggestionRawDefinition[]> {
46+
}: {
47+
expressionRoot: ESQLSingleAstItem | undefined;
48+
} & Pick<
49+
CommandSuggestParams<string>,
50+
'innerText' | 'getExpressionType' | 'getColumnsByType' | 'previousCommands'
51+
>): Promise<SuggestionRawDefinition[]> {
3752
const suggestions: SuggestionRawDefinition[] = [];
3853

39-
/**
40-
* The logic for WHERE suggestions is basically the logic for expression suggestions.
41-
* I assume we will eventually extract much of this to be a shared function among WHERE and EVAL
42-
* and anywhere else the user can enter a generic expression.
43-
*/
44-
const expressionRoot = command.args[0] as ESQLSingleAstItem | undefined;
45-
46-
const position = getPosition(innerText, command);
54+
const position = getPosition(innerText, expressionRoot);
4755
switch (position) {
4856
/**
4957
* After a column name

src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/commands/where/util.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* License v3.0 only", or the "Server Side Public License, v 1".
88
*/
99

10-
import { ESQLCommand, ESQLSingleAstItem } from '@kbn/esql-ast';
10+
import { ESQLSingleAstItem } from '@kbn/esql-ast';
1111
import { isColumnItem, isFunctionItem } from '../../../shared/helpers';
1212

1313
export type CaretPosition =
@@ -17,9 +17,10 @@ export type CaretPosition =
1717
| 'after_operator'
1818
| 'empty_expression';
1919

20-
export const getPosition = (innerText: string, command: ESQLCommand): CaretPosition => {
21-
const expressionRoot = command.args[0] as ESQLSingleAstItem | undefined;
22-
20+
export const getPosition = (
21+
innerText: string,
22+
expressionRoot: ESQLSingleAstItem | undefined
23+
): CaretPosition => {
2324
const endsWithNot = / not$/i.test(innerText.trimEnd());
2425
if (
2526
endsWithNot &&

0 commit comments

Comments
 (0)