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,67 @@ 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+ const columnsFromVariable : TAutocompleteEntity [ ] = [ ] ;
248+ if ( variableSources . length ) {
249+ variableSources . forEach ( ( source ) => {
250+ const newColumns =
251+ suggestVariables
252+ // Variable name from suggestions doesn't include $ sign
253+ ?. find ( ( variable ) => source . slice ( 1 ) === variable . name )
254+ ?. value ?. columns ?. map ( ( col ) => ( {
255+ Name : col ,
256+ Type : 'column' as const ,
257+ Parent : source ,
258+ } ) ) ?? [ ] ;
259+ columnsFromVariable . push ( ...newColumns ) ;
260+ } ) ;
231261 }
232262
263+ const predefinedColumns : TAutocompleteEntity [ ] = normalizedSuggestions . reduce <
264+ TAutocompleteEntity [ ]
265+ > ( ( acc , entity ) => {
266+ const columns = entity . columns ;
267+ if ( columns ) {
268+ acc . push (
269+ ...columns . map ( ( col ) => ( {
270+ Name : col ,
271+ Type : 'column' as const ,
272+ Parent : entity . name ,
273+ } ) ) ,
274+ ) ;
275+ }
276+ return acc ;
277+ } , [ ] ) ;
278+
233279 const tableNameToAliasMap = suggestColumns . tables ?. reduce (
234280 ( acc , entity ) => {
235281 const normalizedEntityName = normalizeEntityPrefix (
@@ -246,7 +292,7 @@ export async function generateColumnsSuggestion(
246292 { } as Record < string , string [ ] > ,
247293 ) ;
248294
249- autocompleteResponse . Result . Entities ? .forEach ( ( col ) => {
295+ [ ... autocompleteEntities , ... columnsFromVariable , ... predefinedColumns ] . forEach ( ( col ) => {
250296 if ( ! isAutocompleteColumn ( col ) ) {
251297 return ;
252298 }
@@ -293,7 +339,7 @@ export async function generateColumnsSuggestion(
293339 normalizedColumns ?. push ( columnNameSuggestion ) ;
294340 }
295341 } ) ;
296- if ( normalizedColumns && normalizedColumns . length > 0 ) {
342+ if ( normalizedColumns && normalizedColumns . length > 1 ) {
297343 const allColumns = normalizedColumns . join ( ', ' ) ;
298344 suggestions . push ( {
299345 label : allColumns ,
@@ -341,13 +387,13 @@ export function generateKeywordsSuggestion(
341387
342388export function generateVariableSuggestion (
343389 rangeToInsertSuggestion : monaco . IRange ,
344- suggestVariables ?: string [ ] ,
390+ suggestVariables ?: VariableSuggestion [ ] ,
345391) {
346392 if ( ! suggestVariables ) {
347393 return [ ] ;
348394 }
349- return suggestVariables . map ( ( rawVariable ) => {
350- const variable = '$' + rawVariable ;
395+ return suggestVariables . map ( ( { name } ) => {
396+ const variable = '$' + name ;
351397 return {
352398 label : variable ,
353399 insertText : variable ,
0 commit comments