1" Vim OMNI completion script for SQL 2" Language: SQL 3" Maintainer: David Fishburn <dfishburn dot vim at gmail dot com> 4" Version: 9.0 5" Last Change: 2010 Apr 20 6" Usage: For detailed help 7" ":help sql.txt" 8" or ":help ft-sql-omni" 9" or read $VIMRUNTIME/doc/sql.txt 10 11" History 12" Version 9.0 13" This change removes some of the support for tables with spaces in their 14" names in order to simplify the regexes used to pull out query table 15" aliases for more robust table name and column name code completion. 16" Full support for "table names with spaces" can be added in again 17" after 7.3. 18" Version 8.0 19" Incorrectly re-executed the g:ftplugin_sql_omni_key_right and g:ftplugin_sql_omni_key_left 20" when drilling in and out of a column list for a table. 21" Version 7.0 22" Better handling of object names 23" Version 6.0 24" Supports object names with spaces "my table name" 25" 26" Set completion with CTRL-X CTRL-O to autoloaded function. 27" This check is in place in case this script is 28" sourced directly instead of using the autoload feature. 29if exists('&omnifunc') 30 " Do not set the option if already set since this 31 " results in an E117 warning. 32 if &omnifunc == "" 33 setlocal omnifunc=sqlcomplete#Complete 34 endif 35endif 36 37if exists('g:loaded_sql_completion') 38 finish 39endif 40let g:loaded_sql_completion = 70 41 42" Maintains filename of dictionary 43let s:sql_file_table = "" 44let s:sql_file_procedure = "" 45let s:sql_file_view = "" 46 47" Define various arrays to be used for caching 48let s:tbl_name = [] 49let s:tbl_alias = [] 50let s:tbl_cols = [] 51let s:syn_list = [] 52let s:syn_value = [] 53 54" Used in conjunction with the syntaxcomplete plugin 55let s:save_inc = "" 56let s:save_exc = "" 57if exists('g:omni_syntax_group_include_sql') 58 let s:save_inc = g:omni_syntax_group_include_sql 59endif 60if exists('g:omni_syntax_group_exclude_sql') 61 let s:save_exc = g:omni_syntax_group_exclude_sql 62endif 63 64" Used with the column list 65let s:save_prev_table = "" 66 67" Default the option to verify table alias 68if !exists('g:omni_sql_use_tbl_alias') 69 let g:omni_sql_use_tbl_alias = 'a' 70endif 71" Default syntax items to precache 72if !exists('g:omni_sql_precache_syntax_groups') 73 let g:omni_sql_precache_syntax_groups = [ 74 \ 'syntax', 75 \ 'sqlKeyword', 76 \ 'sqlFunction', 77 \ 'sqlOption', 78 \ 'sqlType', 79 \ 'sqlStatement' 80 \ ] 81endif 82" Set ignorecase to the ftplugin standard 83if !exists('g:omni_sql_ignorecase') 84 let g:omni_sql_ignorecase = &ignorecase 85endif 86" During table completion, should the table list also 87" include the owner name 88if !exists('g:omni_sql_include_owner') 89 let g:omni_sql_include_owner = 0 90 if exists('g:loaded_dbext') 91 if g:loaded_dbext >= 300 92 " New to dbext 3.00, by default the table lists include the owner 93 " name of the table. This is used when determining how much of 94 " whatever has been typed should be replaced as part of the 95 " code replacement. 96 let g:omni_sql_include_owner = 1 97 endif 98 endif 99endif 100 101" This function is used for the 'omnifunc' option. 102function! sqlcomplete#Complete(findstart, base) 103 104 " Default to table name completion 105 let compl_type = 'table' 106 " Allow maps to specify what type of object completion they want 107 if exists('b:sql_compl_type') 108 let compl_type = b:sql_compl_type 109 endif 110 111 " First pass through this function determines how much of the line should 112 " be replaced by whatever is chosen from the completion list 113 if a:findstart 114 " Locate the start of the item, including "." 115 let line = getline('.') 116 let start = col('.') - 1 117 let lastword = -1 118 let begindot = 0 119 " Check if the first character is a ".", for column completion 120 if line[start - 1] == '.' 121 let begindot = 1 122 endif 123 while start > 0 124 " Additional code was required to handle objects which 125 " can contain spaces like "my table name". 126 if line[start - 1] !~ '\(\w\|\.\)' 127 " If the previous character is not a period or word character 128 break 129 " elseif line[start - 1] =~ '\(\w\|\s\+\)' 130 " let start -= 1 131 elseif line[start - 1] =~ '\w' 132 " If the previous character is word character continue back 133 let start -= 1 134 elseif line[start - 1] =~ '\.' && 135 \ compl_type =~ 'column\|table\|view\|procedure' 136 " If the previous character is a period and we are completing 137 " an object which can be specified with a period like this: 138 " table_name.column_name 139 " owner_name.table_name 140 141 " If lastword has already been set for column completion 142 " break from the loop, since we do not also want to pickup 143 " a table name if it was also supplied. 144 if lastword != -1 && compl_type == 'column' 145 break 146 endif 147 " If column completion was specified stop at the "." if 148 " a . was specified, otherwise, replace all the way up 149 " to the owner name (if included). 150 if lastword == -1 && compl_type == 'column' && begindot == 1 151 let lastword = start 152 endif 153 " If omni_sql_include_owner = 0, do not include the table 154 " name as part of the substitution, so break here 155 if lastword == -1 && 156 \ compl_type =~ 'table\|view\|procedure\column_csv' && 157 \ g:omni_sql_include_owner == 0 158 let lastword = start 159 break 160 endif 161 let start -= 1 162 else 163 break 164 endif 165 endwhile 166 167 " Return the column of the last word, which is going to be changed. 168 " Remember the text that comes before it in s:prepended. 169 if lastword == -1 170 let s:prepended = '' 171 return start 172 endif 173 let s:prepended = strpart(line, start, lastword - start) 174 return lastword 175 endif 176 177 " Second pass through this function will determine what data to put inside 178 " of the completion list 179 " s:prepended is set by the first pass 180 let base = s:prepended . a:base 181 182 " Default the completion list to an empty list 183 let compl_list = [] 184 185 " Default to table name completion 186 let compl_type = 'table' 187 " Allow maps to specify what type of object completion they want 188 if exists('b:sql_compl_type') 189 let compl_type = b:sql_compl_type 190 unlet b:sql_compl_type 191 endif 192 193 if compl_type == 'tableReset' 194 let compl_type = 'table' 195 let base = '' 196 endif 197 198 if compl_type == 'table' || 199 \ compl_type == 'procedure' || 200 \ compl_type == 'view' 201 202 " This type of completion relies upon the dbext.vim plugin 203 if s:SQLCCheck4dbext() == -1 204 return [] 205 endif 206 207 " Allow the user to override the dbext plugin to specify whether 208 " the owner/creator should be included in the list 209 if g:loaded_dbext >= 300 210 let saveSetting = DB_listOption('dict_show_owner') 211 exec 'DBSetOption dict_show_owner='.(g:omni_sql_include_owner==1?'1':'0') 212 endif 213 214 let compl_type_uc = substitute(compl_type, '\w\+', '\u&', '') 215 " Same call below, no need to do it twice 216 " if s:sql_file_{compl_type} == "" 217 " let s:sql_file_{compl_type} = DB_getDictionaryName(compl_type_uc) 218 " endif 219 let s:sql_file_{compl_type} = DB_getDictionaryName(compl_type_uc) 220 if s:sql_file_{compl_type} != "" 221 if filereadable(s:sql_file_{compl_type}) 222 let compl_list = readfile(s:sql_file_{compl_type}) 223 endif 224 endif 225 226 if g:loaded_dbext > 300 227 exec 'DBSetOption dict_show_owner='.saveSetting 228 endif 229 elseif compl_type =~? 'column' 230 231 " This type of completion relies upon the dbext.vim plugin 232 if s:SQLCCheck4dbext() == -1 233 return [] 234 endif 235 236 if base == "" 237 " The last time we displayed a column list we stored 238 " the table name. If the user selects a column list 239 " without a table name of alias present, assume they want 240 " the previous column list displayed. 241 let base = s:save_prev_table 242 endif 243 244 let owner = '' 245 let column = '' 246 247 if base =~ '\.' 248 " Check if the owner/creator has been specified 249 let owner = matchstr( base, '^\zs.*\ze\..*\..*' ) 250 let table = matchstr( base, '^\(.*\.\)\?\zs.*\ze\..*' ) 251 let column = matchstr( base, '.*\.\zs.*' ) 252 253 " It is pretty well impossible to determine if the user 254 " has entered: 255 " owner.table 256 " table.column_prefix 257 " So there are a couple of things we can do to mitigate 258 " this issue. 259 " 1. Check if the dbext plugin has the option turned 260 " on to even allow owners 261 " 2. Based on 1, if the user is showing a table list 262 " and the DrillIntoTable (using <Right>) then 263 " this will be owner.table. In this case, we can 264 " check to see the table.column exists in the 265 " cached table list. If it does, then we have 266 " determined the user has actually chosen 267 " owner.table, not table.column_prefix. 268 let found = -1 269 if g:omni_sql_include_owner == 1 && owner == '' 270 if filereadable(s:sql_file_table) 271 let tbl_list = readfile(s:sql_file_table) 272 let found = index( tbl_list, ((table != '')?(table.'.'):'').column) 273 endif 274 endif 275 " If the table.column was found in the table list, we can safely assume 276 " the owner was not provided and shift the items appropriately. 277 " OR 278 " If the user has indicated not to use table owners at all and 279 " the base ends in a '.' we know they are not providing a column 280 " name, so we can shift the items appropriately. 281 if found != -1 || (g:omni_sql_include_owner == 0 && base !~ '\.$') 282 let owner = table 283 let table = column 284 let column = '' 285 endif 286 else 287 let table = base 288 endif 289 290 " Get anything after the . and consider this the table name 291 " If an owner has been specified, then we must consider the 292 " base to be a partial column name 293 " let base = matchstr( base, '^\(.*\.\)\?\zs.*' ) 294 295 if table != "" 296 let s:save_prev_table = base 297 let list_type = '' 298 299 if compl_type == 'column_csv' 300 " Return one array element, with a comma separated 301 " list of values instead of multiple array entries 302 " for each column in the table. 303 let list_type = 'csv' 304 endif 305 306 let compl_list = s:SQLCGetColumns(table, list_type) 307 if column != '' 308 " If no column prefix has been provided and the table 309 " name was provided, append it to each of the items 310 " returned. 311 let compl_list = map(compl_list, "table.'.'.v:val") 312 if owner != '' 313 " If an owner has been provided append it to each of the 314 " items returned. 315 let compl_list = map(compl_list, "owner.'.'.v:val") 316 endif 317 else 318 let base = '' 319 endif 320 321 if compl_type == 'column_csv' 322 " Join the column array into 1 single element array 323 " but make the columns column separated 324 let compl_list = [join(compl_list, ', ')] 325 endif 326 endif 327 elseif compl_type == 'resetCache' 328 " Reset all cached items 329 let s:tbl_name = [] 330 let s:tbl_alias = [] 331 let s:tbl_cols = [] 332 let s:syn_list = [] 333 let s:syn_value = [] 334 335 let msg = "All SQL cached items have been removed." 336 call s:SQLCWarningMsg(msg) 337 " Leave time for the user to read the error message 338 :sleep 2 339 else 340 let compl_list = s:SQLCGetSyntaxList(compl_type) 341 endif 342 343 if base != '' 344 " Filter the list based on the first few characters the user entered. 345 " Check if the text matches at the beginning 346 " or 347 " Match to a owner.table or alias.column type match 348 " or 349 " Handle names with spaces "my table name" 350 let expr = 'v:val '.(g:omni_sql_ignorecase==1?'=~?':'=~#').' "\\(^'.base.'\\|^\\(\\w\\+\\.\\)\\?'.base.'\\)"' 351 " let expr = 'v:val '.(g:omni_sql_ignorecase==1?'=~?':'=~#').' "\\(^'.base.'\\)"' 352 " let expr = 'v:val '.(g:omni_sql_ignorecase==1?'=~?':'=~#').' "\\(^'.base.'\\|\\(\\.\\)\\?'.base.'\\)"' 353 " let expr = 'v:val '.(g:omni_sql_ignorecase==1?'=~?':'=~#').' "\\(^'.base.'\\|\\([^.]*\\)\\?'.base.'\\)"' 354 let compl_list = filter(deepcopy(compl_list), expr) 355 endif 356 357 if exists('b:sql_compl_savefunc') && b:sql_compl_savefunc != "" 358 let &omnifunc = b:sql_compl_savefunc 359 endif 360 361 return compl_list 362endfunc 363 364function! sqlcomplete#PreCacheSyntax(...) 365 let syn_group_arr = [] 366 if a:0 > 0 367 let syn_group_arr = a:1 368 else 369 let syn_group_arr = g:omni_sql_precache_syntax_groups 370 endif 371 " For each group specified in the list, precache all 372 " the sytnax items. 373 if !empty(syn_group_arr) 374 for group_name in syn_group_arr 375 call s:SQLCGetSyntaxList(group_name) 376 endfor 377 endif 378endfunction 379 380function! sqlcomplete#Map(type) 381 " Tell the SQL plugin what you want to complete 382 let b:sql_compl_type=a:type 383 " Record previous omnifunc, if the SQL completion 384 " is being used in conjunction with other filetype 385 " completion plugins 386 if &omnifunc != "" && &omnifunc != 'sqlcomplete#Complete' 387 " Record the previous omnifunc, the plugin 388 " will automatically set this back so that it 389 " does not interfere with other ftplugins settings 390 let b:sql_compl_savefunc=&omnifunc 391 endif 392 " Set the OMNI func for the SQL completion plugin 393 let &omnifunc='sqlcomplete#Complete' 394endfunction 395 396function! sqlcomplete#DrillIntoTable() 397 " If the omni popup window is visible 398 if pumvisible() 399 call sqlcomplete#Map('column') 400 " C-Y, makes the currently highlighted entry active 401 " and trigger the omni popup to be redisplayed 402 call feedkeys("\<C-Y>\<C-X>\<C-O>", 'n') 403 else 404 " If the popup is not visible, simple perform the normal 405 " key behaviour. 406 " Must use exec since they key must be preceeded by "\" 407 " or feedkeys will simply push each character of the string 408 " rather than the "key press". 409 exec 'call feedkeys("\'.g:ftplugin_sql_omni_key_right.'", "n")' 410 endif 411 return "" 412endfunction 413 414function! sqlcomplete#DrillOutOfColumns() 415 " If the omni popup window is visible 416 if pumvisible() 417 call sqlcomplete#Map('tableReset') 418 " Trigger the omni popup to be redisplayed 419 call feedkeys("\<C-X>\<C-O>") 420 else 421 " If the popup is not visible, simple perform the normal 422 " key behaviour. 423 " Must use exec since they key must be preceeded by "\" 424 " or feedkeys will simply push each character of the string 425 " rather than the "key press". 426 exec 'call feedkeys("\'.g:ftplugin_sql_omni_key_left.'", "n")' 427 endif 428 return "" 429endfunction 430 431function! s:SQLCWarningMsg(msg) 432 echohl WarningMsg 433 echomsg a:msg 434 echohl None 435endfunction 436 437function! s:SQLCErrorMsg(msg) 438 echohl ErrorMsg 439 echomsg a:msg 440 echohl None 441endfunction 442 443function! s:SQLCGetSyntaxList(syn_group) 444 let syn_group = a:syn_group 445 let compl_list = [] 446 447 " Check if we have already cached the syntax list 448 let list_idx = index(s:syn_list, syn_group, 0, &ignorecase) 449 if list_idx > -1 450 " Return previously cached value 451 let compl_list = s:syn_value[list_idx] 452 else 453 " Request the syntax list items from the 454 " syntax completion plugin 455 if syn_group == 'syntax' 456 " Handle this special case. This allows the user 457 " to indicate they want all the syntax items available, 458 " so do not specify a specific include list. 459 let g:omni_syntax_group_include_sql = '' 460 else 461 " The user has specified a specific syntax group 462 let g:omni_syntax_group_include_sql = syn_group 463 endif 464 let g:omni_syntax_group_exclude_sql = '' 465 let syn_value = OmniSyntaxList() 466 let g:omni_syntax_group_include_sql = s:save_inc 467 let g:omni_syntax_group_exclude_sql = s:save_exc 468 " Cache these values for later use 469 let s:syn_list = add( s:syn_list, syn_group ) 470 let s:syn_value = add( s:syn_value, syn_value ) 471 let compl_list = syn_value 472 endif 473 474 return compl_list 475endfunction 476 477function! s:SQLCCheck4dbext() 478 if !exists('g:loaded_dbext') 479 let msg = "The dbext plugin must be loaded for dynamic SQL completion" 480 call s:SQLCErrorMsg(msg) 481 " Leave time for the user to read the error message 482 :sleep 2 483 return -1 484 elseif g:loaded_dbext < 600 485 let msg = "The dbext plugin must be at least version 5.30 " . 486 \ " for dynamic SQL completion" 487 call s:SQLCErrorMsg(msg) 488 " Leave time for the user to read the error message 489 :sleep 2 490 return -1 491 endif 492 return 1 493endfunction 494 495function! s:SQLCAddAlias(table_name, table_alias, cols) 496 " Strip off the owner if included 497 let table_name = matchstr(a:table_name, '\%(.\{-}\.\)\?\zs\(.*\)' ) 498 let table_alias = a:table_alias 499 let cols = a:cols 500 501 if g:omni_sql_use_tbl_alias != 'n' 502 if table_alias == '' 503 if 'da' =~? g:omni_sql_use_tbl_alias 504 if table_name =~ '_' 505 " Treat _ as separators since people often use these 506 " for word separators 507 let save_keyword = &iskeyword 508 setlocal iskeyword-=_ 509 510 " Get the first letter of each word 511 " [[:alpha:]] is used instead of \w 512 " to catch extended accented characters 513 " 514 let table_alias = substitute( 515 \ table_name, 516 \ '\<[[:alpha:]]\+\>_\?', 517 \ '\=strpart(submatch(0), 0, 1)', 518 \ 'g' 519 \ ) 520 " Restore original value 521 let &iskeyword = save_keyword 522 elseif table_name =~ '\u\U' 523 let table_alias = substitute( 524 \ table_name, '\(\u\)\U*', '\1', 'g') 525 else 526 let table_alias = strpart(table_name, 0, 1) 527 endif 528 endif 529 endif 530 if table_alias != '' 531 " Following a word character, make sure there is a . and no spaces 532 let table_alias = substitute(table_alias, '\w\zs\.\?\s*$', '.', '') 533 if 'a' =~? g:omni_sql_use_tbl_alias && a:table_alias == '' 534 let table_alias = inputdialog("Enter table alias:", table_alias) 535 endif 536 endif 537 if table_alias != '' 538 let cols = substitute(cols, '\<\w', table_alias.'&', 'g') 539 endif 540 endif 541 542 return cols 543endfunction 544 545function! s:SQLCGetObjectOwner(object) 546 " The owner regex matches a word at the start of the string which is 547 " followed by a dot, but doesn't include the dot in the result. 548 " ^ - from beginning of line 549 " \("\|\[\)\? - ignore any quotes 550 " \zs - start the match now 551 " .\{-} - get owner name 552 " \ze - end the match 553 " \("\|\[\)\? - ignore any quotes 554 " \. - must by followed by a . 555 " let owner = matchstr( a:object, '^\s*\zs.*\ze\.' ) 556 let owner = matchstr( a:object, '^\("\|\[\)\?\zs\.\{-}\ze\("\|\]\)\?\.' ) 557 return owner 558endfunction 559 560function! s:SQLCGetColumns(table_name, list_type) 561 " Check if the table name was provided as part of the column name 562 let table_name = matchstr(a:table_name, '^["\[\]a-zA-Z0-9_ ]\+\ze\.\?') 563 let table_cols = [] 564 let table_alias = '' 565 let move_to_top = 1 566 567 let table_name = substitute(table_name, '\s*\(.\{-}\)\s*$', '\1', 'g') 568 569 " If the table name was given as: 570 " where c. 571 let table_name = substitute(table_name, '^\c\(WHERE\|AND\|OR\)\s\+', '', '') 572 if g:loaded_dbext >= 300 573 let saveSettingAlias = DB_listOption('use_tbl_alias') 574 exec 'DBSetOption use_tbl_alias=n' 575 endif 576 577 let table_name_stripped = substitute(table_name, '["\[\]]*', '', 'g') 578 579 " Check if we have already cached the column list for this table 580 " by its name 581 let list_idx = index(s:tbl_name, table_name_stripped, 0, &ignorecase) 582 if list_idx > -1 583 let table_cols = split(s:tbl_cols[list_idx], '\n') 584 else 585 " Check if we have already cached the column list for this table 586 " by its alias, assuming the table_name provided was actually 587 " the alias for the table instead 588 " select * 589 " from area a 590 " where a. 591 let list_idx = index(s:tbl_alias, table_name_stripped, 0, &ignorecase) 592 if list_idx > -1 593 let table_alias = table_name_stripped 594 let table_name = s:tbl_name[list_idx] 595 let table_cols = split(s:tbl_cols[list_idx], '\n') 596 endif 597 endif 598 599 " If we have not found a cached copy of the table 600 " And the table ends in a "." or we are looking for a column list 601 " if list_idx == -1 && (a:table_name =~ '\.' || b:sql_compl_type =~ 'column') 602 " if list_idx == -1 && (a:table_name =~ '\.' || a:list_type =~ 'csv') 603 if list_idx == -1 604 let saveY = @y 605 let saveSearch = @/ 606 let saveWScan = &wrapscan 607 let curline = line(".") 608 let curcol = col(".") 609 610 " Do not let searchs wrap 611 setlocal nowrapscan 612 " If . was entered, look at the word just before the . 613 " We are looking for something like this: 614 " select * 615 " from customer c 616 " where c. 617 " So when . is pressed, we need to find 'c' 618 " 619 620 " Search backwards to the beginning of the statement 621 " and do NOT wrap 622 " exec 'silent! normal! v?\<\(select\|update\|delete\|;\)\>'."\n".'"yy' 623 exec 'silent! normal! ?\<\c\(select\|update\|delete\|;\)\>'."\n" 624 625 " Start characterwise visual mode 626 " Advance right one character 627 " Search foward until one of the following: 628 " 1. Another select/update/delete statement 629 " 2. A ; at the end of a line (the delimiter) 630 " 3. The end of the file (incase no delimiter) 631 " Yank the visually selected text into the "y register. 632 exec 'silent! normal! vl/\c\(\<select\>\|\<update\>\|\<delete\>\|;\s*$\|\%$\)'."\n".'"yy' 633 634 let query = @y 635 let query = substitute(query, "\n", ' ', 'g') 636 let found = 0 637 638 " if query =~? '^\c\(select\)' 639 if query =~? '^\(select\|update\|delete\)' 640 let found = 1 641 " \(\(\<\w\+\>\)\.\)\? - 642 " '\c\(from\|join\|,\).\{-}' - Starting at the from clause (case insensitive) 643 " '\zs\(\(\<\w\+\>\)\.\)\?' - Get the owner name (optional) 644 " '\<\w\+\>\ze' - Get the table name 645 " '\s\+\<'.table_name.'\>' - Followed by the alias 646 " '\s*\.\@!.*' - Cannot be followed by a . 647 " '\(\<where\>\|$\)' - Must be followed by a WHERE clause 648 " '.*' - Exclude the rest of the line in the match 649 " let table_name_new = matchstr(@y, 650 " \ '\c\(from\|join\|,\).\{-}'. 651 " \ '\zs\(\("\|\[\)\?.\{-}\("\|\]\)\.\)\?'. 652 " \ '\("\|\[\)\?.\{-}\("\|\]\)\?\ze'. 653 " \ '\s\+\%(as\s\+\)\?\<'. 654 " \ matchstr(table_name, '.\{-}\ze\.\?$'). 655 " \ '\>'. 656 " \ '\s*\.\@!.*'. 657 " \ '\(\<where\>\|$\)'. 658 " \ '.*' 659 " \ ) 660 let table_name_new = matchstr(@y, 661 \ '\c\(\<from\>\|\<join\>\|,\)\s*'. 662 \ '\zs\(\("\|\[\)\?\w\+\("\|\]\)\?\.\)\?'. 663 \ '\("\|\[\)\?\w\+\("\|\]\)\?\ze'. 664 \ '\s\+\%(as\s\+\)\?\<'. 665 \ matchstr(table_name, '.\{-}\ze\.\?$'). 666 \ '\>'. 667 \ '\s*\.\@!.*'. 668 \ '\(\<where\>\|$\)'. 669 \ '.*' 670 \ ) 671 672 if table_name_new != '' 673 let table_alias = table_name 674 let table_name = matchstr( table_name_new, '^\(.*\.\)\?\zs.*\ze' ) 675 676 let list_idx = index(s:tbl_name, table_name, 0, &ignorecase) 677 if list_idx > -1 678 let table_cols = split(s:tbl_cols[list_idx]) 679 let s:tbl_name[list_idx] = table_name 680 let s:tbl_alias[list_idx] = table_alias 681 else 682 let list_idx = index(s:tbl_alias, table_name, 0, &ignorecase) 683 if list_idx > -1 684 let table_cols = split(s:tbl_cols[list_idx]) 685 let s:tbl_name[list_idx] = table_name 686 let s:tbl_alias[list_idx] = table_alias 687 endif 688 endif 689 690 endif 691 else 692 " Simply assume it is a table name provided with a . on the end 693 let found = 1 694 endif 695 696 let @y = saveY 697 let @/ = saveSearch 698 let &wrapscan = saveWScan 699 700 " Return to previous location 701 call cursor(curline, curcol) 702 703 if found == 0 704 if g:loaded_dbext > 300 705 exec 'DBSetOption use_tbl_alias='.saveSettingAlias 706 endif 707 708 " Not a SQL statement, do not display a list 709 return [] 710 endif 711 endif 712 713 if empty(table_cols) 714 " Specify silent mode, no messages to the user (tbl, 1) 715 " Specify do not comma separate (tbl, 1, 1) 716 let table_cols_str = DB_getListColumn(table_name, 1, 1) 717 718 if table_cols_str != "" 719 let s:tbl_name = add( s:tbl_name, table_name ) 720 let s:tbl_alias = add( s:tbl_alias, table_alias ) 721 let s:tbl_cols = add( s:tbl_cols, table_cols_str ) 722 let table_cols = split(table_cols_str, '\n') 723 endif 724 725 endif 726 727 if g:loaded_dbext > 300 728 exec 'DBSetOption use_tbl_alias='.saveSettingAlias 729 endif 730 731 " If the user has asked for a comma separate list of column 732 " values, ask the user if they want to prepend each column 733 " with a tablename alias. 734 if a:list_type == 'csv' && !empty(table_cols) 735 let cols = join(table_cols, ', ') 736 let cols = s:SQLCAddAlias(table_name, table_alias, cols) 737 let table_cols = [cols] 738 endif 739 740 return table_cols 741endfunction 742