11import type {
22 ColumnAliasSuggestion ,
33 KeywordSuggestion ,
4+ VariableSuggestion ,
45} from '@gravity-ui/websql-autocomplete/shared' ;
56import type { YQLEntity , YqlAutocompleteResult } from '@gravity-ui/websql-autocomplete/yql' ;
67import * as monaco from 'monaco-editor/esm/vs/editor/editor.api' ;
@@ -107,6 +108,10 @@ function removeBackticks(value: string) {
107108 return value . slice ( sliceStart , sliceEnd ) ;
108109}
109110
111+ function isVariable ( value : string ) {
112+ return value . startsWith ( '$' ) ;
113+ }
114+
110115function removeStartSlash ( value : string ) {
111116 if ( value . startsWith ( '/' ) ) {
112117 return value . slice ( 1 ) ;
@@ -199,7 +204,8 @@ function getColumnDetails(col: AutocompleteColumn) {
199204
200205export async function generateColumnsSuggestion (
201206 rangeToInsertSuggestion : monaco . IRange ,
202- suggestColumns : YqlAutocompleteResult [ 'suggestColumns' ] | undefined ,
207+ suggestColumns : YqlAutocompleteResult [ 'suggestColumns' ] ,
208+ suggestVariables : YqlAutocompleteResult [ 'suggestVariables' ] ,
203209 database : string ,
204210) : Promise < monaco . languages . CompletionItem [ ] > {
205211 if ( ! suggestColumns ?. tables ) {
@@ -209,27 +215,63 @@ export async function generateColumnsSuggestion(
209215 const normalizedColumns = suggestColumns . all ? ( [ ] as string [ ] ) : undefined ;
210216 const multi = suggestColumns . tables . length > 1 ;
211217
212- const normalizedTableNames =
218+ const normalizedSuggestions =
213219 suggestColumns . tables ?. map ( ( entity ) => {
214220 let normalizedEntityName = removeBackticks ( entity . name ) ;
215- if ( ! normalizedEntityName . endsWith ( '/' ) ) {
221+ if ( ! normalizedEntityName . endsWith ( '/' ) && ! isVariable ( normalizedEntityName ) ) {
216222 normalizedEntityName = `${ normalizedEntityName } /` ;
217223 }
218- return normalizeEntityPrefix ( normalizedEntityName , database ) ;
224+ return { ... entity , name : normalizeEntityPrefix ( normalizedEntityName , database ) } ;
219225 } ) ?? [ ] ;
220226
227+ const normalizedTableNames = normalizedSuggestions . map ( ( entity ) => entity . name ) ;
228+
221229 // remove duplicates if any
222230 const filteredTableNames = Array . from ( new Set ( normalizedTableNames ) ) ;
223231
224- const autocompleteResponse = await window . api . viewer . autocomplete ( {
225- database,
226- table : filteredTableNames ,
227- limit : 1000 ,
228- } ) ;
229- if ( ! autocompleteResponse . Success ) {
230- return [ ] ;
232+ const tableSources = filteredTableNames . filter ( ( name ) => ! isVariable ( name ) ) ;
233+
234+ let autocompleteEntities : TAutocompleteEntity [ ] = [ ] ;
235+ if ( tableSources . length ) {
236+ const autocompleteResponse = await window . api . viewer . autocomplete ( {
237+ database,
238+ table : tableSources ,
239+ limit : 1000 ,
240+ } ) ;
241+ if ( autocompleteResponse . Success ) {
242+ autocompleteEntities = autocompleteResponse . Result . Entities ?? [ ] ;
243+ }
244+ }
245+
246+ const variableSources = filteredTableNames . filter ( isVariable ) ;
247+ let columnsFromVariable : TAutocompleteEntity [ ] = [ ] ;
248+ if ( variableSources . length ) {
249+ variableSources . forEach ( ( source ) => {
250+ columnsFromVariable =
251+ suggestVariables
252+ // Variable name from suggestions doesn't include $ sign
253+ ?. find ( ( variable ) => source . slice ( 1 ) === variable . name )
254+ ?. value ?. columns ?. map ( ( col ) => ( { Name : col , Type : 'column' , Parent : source } ) ) ??
255+ [ ] ;
256+ } ) ;
231257 }
232258
259+ const predefinedColumns : TAutocompleteEntity [ ] = normalizedSuggestions . reduce <
260+ TAutocompleteEntity [ ]
261+ > ( ( acc , entity ) => {
262+ const columns = entity . columns ;
263+ if ( columns ) {
264+ acc . push (
265+ ...columns . map ( ( col ) => ( {
266+ Name : col ,
267+ Type : 'column' as const ,
268+ Parent : entity . name ,
269+ } ) ) ,
270+ ) ;
271+ }
272+ return acc ;
273+ } , [ ] ) ;
274+
233275 const tableNameToAliasMap = suggestColumns . tables ?. reduce (
234276 ( acc , entity ) => {
235277 const normalizedEntityName = normalizeEntityPrefix (
@@ -246,7 +288,7 @@ export async function generateColumnsSuggestion(
246288 { } as Record < string , string [ ] > ,
247289 ) ;
248290
249- autocompleteResponse . Result . Entities ? .forEach ( ( col ) => {
291+ [ ... autocompleteEntities , ... columnsFromVariable , ... predefinedColumns ] . forEach ( ( col ) => {
250292 if ( ! isAutocompleteColumn ( col ) ) {
251293 return ;
252294 }
@@ -293,7 +335,7 @@ export async function generateColumnsSuggestion(
293335 normalizedColumns ?. push ( columnNameSuggestion ) ;
294336 }
295337 } ) ;
296- if ( normalizedColumns && normalizedColumns . length > 0 ) {
338+ if ( normalizedColumns && normalizedColumns . length > 1 ) {
297339 const allColumns = normalizedColumns . join ( ', ' ) ;
298340 suggestions . push ( {
299341 label : allColumns ,
@@ -341,13 +383,13 @@ export function generateKeywordsSuggestion(
341383
342384export function generateVariableSuggestion (
343385 rangeToInsertSuggestion : monaco . IRange ,
344- suggestVariables ?: string [ ] ,
386+ suggestVariables ?: VariableSuggestion [ ] ,
345387) {
346388 if ( ! suggestVariables ) {
347389 return [ ] ;
348390 }
349- return suggestVariables . map ( ( rawVariable ) => {
350- const variable = '$' + rawVariable ;
391+ return suggestVariables . map ( ( { name } ) => {
392+ const variable = '$' + name ;
351393 return {
352394 label : variable ,
353395 insertText : variable ,
0 commit comments